mcp嵌入式用户界面(TypeScript)
这是什么?
如果你用Types/JavaScript构建一个MCP服务器,你的用户会通过原始JSON与工具交互——没有视觉反馈,没有模式浏览器,也没有快速的测试方法。此库为您的服务器添加了一个完整的浏览器UI 零依赖和一次函数调用.
┌───────────────────────────────────┐
│ Browser │
│ Tool list → Schema → Try it │
└──────────────┬────────────────────┘
│ HTTP / JSON
┌──────────────▼────────────────────┐
│ Your TypeScript MCP Server │
│ + mcp-embedded-ui │
│ (Node / Bun / Deno / Hono) │
└───────────────────────────────────┘UI提供了什么?
- 工具列表 --浏览所有带有描述和注释徽章的注册工具
- 模式检查器 --展开任何工具以查看其完整的JSON模式(
inputSchema) - 试试控制台 --键入JSON参数,执行工具,立即查看结果
- cURL导出 --复制现成的cURL命令以执行任何操作
- 身份验证支持 --在UI中输入与所有请求一起发送的Bearer令牌
无构建步骤。没有CDN。没有外部依赖关系。整个UI是嵌入在包中的单个自包含的HTML页面。
安装
npm install mcp-embedded-ui需要Node.js 18+(或支持Web API的Bun/Deno)。 零运行时依赖关系。
快速开始
Web Fetch API(Bun、Deno、Hono、Cloudflare Workers)
import { createHandler } from "mcp-embedded-ui";
const handler = createHandler(tools, handleCall, { title: "My Explorer", allowExecute: true });
// Use with any framework that supports Request/Response:
// Bun.serve({ fetch: (req) => handler(req, "/explorer") });
// Deno.serve((req) => handler(req, "/explorer"));Node.js http
import http from "node:http";
import { createNodeHandler } from "mcp-embedded-ui";
const handle = createNodeHandler(tools, handleCall, {
prefix: "/explorer",
title: "My Explorer",
allowExecute: true,
});
http.createServer(handle).listen(8000);
// Visit http://localhost:8000/explorer完整工作示例
import http from "node:http";
import { createNodeHandler } from "mcp-embedded-ui";
import type { Tool, ToolCallHandler } from "mcp-embedded-ui";
// 1. Define your tools
const tools: Tool[] = [
{
name: "greet",
description: "Say hello",
inputSchema: {
type: "object",
properties: { name: { type: "string" } },
},
},
];
// 2. Define a handler: (name, args) -> [content, isError, traceId?]
const handleCall: ToolCallHandler = async (name, args) => {
if (name === "greet") {
return [
[{ type: "text", text: `Hello, ${args.name ?? "world"}!` }],
false,
undefined,
];
}
return [[{ type: "text", text: `Unknown tool: ${name}` }], true, undefined];
};
// 3. Create and start the server
const handle = createNodeHandler(tools, handleCall, { prefix: "/explorer", allowExecute: true });
http.createServer(handle).listen(8000);带身份验证挂钩
import type { AuthHook } from "mcp-embedded-ui";
const authHook: AuthHook = async (req, next) => {
const token = req.headers["authorization"] ?? "";
if (typeof token !== "string" || !token.startsWith("Bearer ")) {
throw new Error("Unauthorized");
}
// Verify the token with your own logic (JWT, API key, session, etc.)
return next();
};
// Pass authHook to enable, omit to disable
const handle = createNodeHandler(tools, handleCall, {
prefix: "/explorer",
allowExecute: true,
authHook,
});仅授权警卫 POST /tools/{name}/call发现端点始终是公开的。UI有一个内置的令牌输入字段——在那里输入你的Bearer令牌,它会随着每个执行请求一起发送。
附带的演示(examples/node-demo.ts)使用硬编码 Bearer demo-secret-token --令牌在启动时打印,因此您知道要粘贴到UI中的内容。
动态工具
// Sync function — re-evaluated on every request
function getTools(): Tool[] {
return registry.listTools();
}
// Async function
async function getTools(): Promise {
return await registry.asyncListTools();
}
const handler = createHandler(getTools, handleCall, { allowExecute: true });API
三倍API
| 函数 | 返回 | 用例 |
|---|---|---|
createHandler(tools, handleCall, config?) | (req: Request, prefix?) => Promise | Bun、Deno、Hono、Cloudflare员工 |
createNodeHandler(tools, handleCall, config?) | (req, res) => void | Node.js http.createServer |
buildUIRoutes(tools, handleCall, config?) | Route[] | 高级用户——细粒度路由控制 |
参数
| 参数 | 类型 | 默认值 | 说明 | ||
|---|---|---|---|---|---|
tools | `Tool[] \ | () => Tool[] \ | () => Promise` | _必需的_ | MCP工具对象 |
handleCall | ToolCallHandler | _必需的_ | async (name, args) => [content, isError, traceId?] | ||
allowExecute | boolean | false | 启用/禁用工具执行(强制服务器端) | ||
authHook | AuthHook | -- | 中间件: (req, next) => Promise | ||
title | string | "MCP Tool Explorer" | 页面标题(HTML自动转义) | ||
projectName | string | -- | 页脚中显示的项目名称 | ||
projectUrl | string | -- | 页脚中链接的项目URL(需要 projectName) |
身份验证挂钩
这 authHook 是一个中间件函数,用于接收请求和 next 功能。用401拒绝。错误响应总是 {"error": "Unauthorized"} --内部细节从未泄露。
const authHook: AuthHook = async (req, next) => {
const token = req.headers["authorization"];
if (!token || !isValid(token)) {
throw new Error("Bad token");
}
return next();
};仅授权警卫 POST /tools/{name}/call.发现端点(GET /tools, GET /tools/{name})总是公开的。
端点
| 方法 | 路径 | 描述 |
|---|---|---|
| 得到 | / | 独立的HTML资源管理器页面 |
| 得到 | /tools | 所有工具的摘要列表 |
| 得到 | /tools/{name} | 完整的工具细节 inputSchema |
| 职位 | /tools/{name}/call | 执行工具,返回MCP CallToolResult |
发展
# Install dependencies
npm install
# Type check
npx tsc --noEmit
# Run tests
npx vitest run
# Run the demo (auth enabled with a demo token)
npx tsx examples/node-demo.ts
# Visit http://localhost:8000/explorer
# Paste "Bearer demo-secret-token" in the UI's token field to execute tools跨语言规范
此包实现了 mcp嵌入式ui 规范。规范仓库包含:
- 协议.md --端点规范、数据形状、安全检查表
- explorer.html --共享HTML模板(所有语言实现都相同)
- 功能规格 --详细要求和测试标准
许可证
阿帕奇-2.0
