mcp嵌入式ui(Python)
这是什么?
如果你用Python构建一个MCP服务器,你的用户会通过原始JSON与工具交互——没有视觉反馈,没有模式浏览器,也没有快速的测试方法。此库为您的服务器添加了一个完整的浏览器UI 一个导入,一个挂载.
┌───────────────────────────────────┐
│ Browser │
│ Tool list → Schema → Try it │
└──────────────┬────────────────────┘
│ HTTP / JSON
┌──────────────▼────────────────────┐
│ Your Python MCP Server │
│ + mcp-embedded-ui │
│ (FastAPI / Starlette / ASGI) │
└───────────────────────────────────┘UI提供了什么?
- 工具列表 --浏览所有带有描述和注释徽章的注册工具
- 模式检查器 --展开任何工具以查看其完整的JSON模式(
inputSchema) - 试试控制台 --键入JSON参数,执行工具,立即查看结果
- cURL导出 --复制现成的cURL命令以执行任何操作
- 身份验证支持 --在UI中输入与所有请求一起发送的Bearer令牌
无构建步骤。没有CDN。没有外部依赖关系。整个UI是嵌入在包中的单个自包含的HTML页面。
安装
pip install mcp-embedded-ui需要Python 3.10+和 斯塔雷特 >= 0.14.
快速开始
FastAPI/Starlette
from fastapi import FastAPI
from mcp_embedded_ui import create_mount
app = FastAPI()
# Mount at /explorer (default), enable tool execution
app.routes.append(create_mount(tools=my_tools, handle_call=my_handler, allow_execute=True))
# Or specify a custom prefix
app.routes.append(create_mount("/mcp-ui", tools=my_tools, handle_call=my_handler, allow_execute=True))
# Visit http://localhost:8000/explorer/任何ASGI框架
from mcp_embedded_ui import create_app
# Returns a standard ASGI app — mount in any ASGI-compatible framework
ui_app = create_app(tools=my_tools, handle_call=my_handler, allow_execute=True)完整工作示例
from fastapi import FastAPI
from mcp_embedded_ui import create_mount
# 1. Define your tools (any object with .name, .description, .inputSchema)
class MyTool:
def __init__(self, name, description, input_schema):
self.name = name
self.description = description
self.inputSchema = input_schema
tools = [
MyTool("greet", "Say hello", {
"type": "object",
"properties": {"name": {"type": "string"}},
}),
]
# 2. Define a handler: (name, args) -> (content, is_error, trace_id)
async def handle_call(name, args):
if name == "greet":
return [{"type": "text", "text": f"Hello, {args.get('name', 'world')}!"}], False, None
return [{"type": "text", "text": f"Unknown tool: {name}"}], True, None
# 3. Mount the UI
app = FastAPI()
app.routes.append(create_mount(tools=tools, handle_call=handle_call, allow_execute=True))带身份验证挂钩
from contextlib import contextmanager
from fastapi import Request
@contextmanager
def my_auth(request: Request):
token = request.headers.get("authorization", "")
if not token.startswith("Bearer "):
raise ValueError("Unauthorized")
# Verify the token with your own logic (JWT, API key, session, etc.)
yield
# Pass auth_hook to enable, omit to disable
app.routes.append(create_mount(
tools=tools,
handle_call=handle_call,
allow_execute=True,
auth_hook=my_auth,
))仅授权警卫 POST /tools/{name}/call发现端点始终是公开的。UI有一个内置的令牌输入字段——在那里输入你的Bearer令牌,它会随着每个执行请求一起发送。
附带的演示(examples/fastapi_demo.py)使用硬编码 Bearer demo-secret-token --令牌在启动时打印,因此您知道要粘贴到UI中的内容。
动态工具
# Sync callable — re-evaluated on every request
def get_tools():
return registry.list_tools()
# Async callable
async def get_tools():
return await registry.async_list_tools()
app = create_app(tools=get_tools, handle_call=my_handler, allow_execute=True)API
三倍API
| 函数 | 返回 | 用例 |
|---|---|---|
create_mount(prefix, *, tools, handle_call, **config) | Mount | FastAPI/Starlette——在URL前缀下挂载 |
create_app(tools, handle_call, **config) | ASGIApp | 任何ASGI框架——独立应用 |
build_ui_routes(tools, handle_call, **config) | list[Route] | 高级用户——细粒度路由控制 |
参数
| 参数 | 类型 | 默认值 | 说明 | ||
|---|---|---|---|---|---|
tools | `list \ | Callable \ | AsyncCallable` | _必需的_ | MCP工具对象(.name, .description, .inputSchema) |
handle_call | ToolCallHandler | _必需的_ | async (name, args) -> (content, is_error, trace_id) | ||
allow_execute | bool | False | 启用/禁用工具执行(强制服务器端) | ||
auth_hook | `AuthHook \ | None` | None | 用于身份验证的同步/异步上下文管理器工厂 | |
title | str | "MCP Tool Explorer" | 页面标题(HTML自动转义) | ||
project_name | `str \ | None` | None | 页脚中显示的项目名称 | |
project_url | `str \ | None` | None | 页脚中链接的项目URL(需要 project_name) |
身份验证挂钩
这 auth_hook 收到Starlette Request 并返回一个上下文管理器(同步或异步)。提高内部拒绝401。错误响应总是 {"error": "Unauthorized"} --内部细节从未泄露。
from contextlib import contextmanager
@contextmanager
def my_auth(request):
token = request.headers.get("Authorization")
if not valid(token):
raise ValueError("Bad token")
my_identity_var.set(decode(token))
yield仅授权警卫 POST /tools/{name}/call.发现端点(GET /tools, GET /tools/{name})总是公开的。
端点
| 方法 | 路径 | 描述 |
|---|---|---|
| 得到 | / | 独立的HTML资源管理器页面 |
| 得到 | /tools | 所有工具的摘要列表 |
| 得到 | /tools/{name} | 完整的工具细节 inputSchema |
| 职位 | /tools/{name}/call | 执行工具,返回MCP CallToolResult |
发展
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run the demo (auth enabled with a demo token)
python examples/fastapi_demo.py
# Visit http://localhost:8000/explorer/
# Paste "Bearer demo-secret-token" in the UI's token field to execute tools
# Run tests
pytest跨语言规范
此包实现了 mcp嵌入式ui 规范。规范仓库包含:
- 协议.md --端点规范、数据形状、安全检查表
- explorer.html --共享HTML模板(所有语言实现都相同)
- 功能规格 --详细要求和测试标准
许可证
阿帕奇-2.0
