@ appport/ mcp
AppPort的MCP适配器:将AppPort应用程序的能力暴露于
官方之上的 MCP 客户端( 代理、 IDEs 、 其他主机)
@modelcontextprotocol/sdk。 。 。 .
建筑
AppPort (authority: capabilities, authorization, idempotency, timeouts)
│
┌─────────┴──────────┐
native clients @appport/mcp ──► MCP clients
AppPort是权威;MCP是投影. 此软件包定义无
能力、权限、租户、经营、持久性或商业逻辑,
并在呼叫之间保持状态。 每一个多边方案 tools/call 翻译为
AppRequest 并经由 AppPortApplication.handleRequest 一样
管道所有其他运输用途——因此,验证、授权、一能,
超时,遥测和处理器执行不变. JSON-RPC, 协议
谈判、框架和运输是MCP SDK的;这里没有重新执行.
MCP tools/call → @appport/mcp → AppRequest → application.handleRequest
→ validate → authorize → capability handler
服务器设置
createMcpHandler 返回标准 (Request) => Promise<Response> 函数
服务 MCP 流式 HTTP. 这是无国籍的,每个HTTP请求都有自己的
短寿命的 SDK 服务器和运输, 被作为 JSON 的响应——所以它
在没有服务器的平台上运行, 并且没有粘滞的获取兼容运行时间
课程或长期过程. GET 财务报告和审定财务报表 DELETE (服务器发起的溪流,
删除会议) 405,是MCP允许的.
import { createMcpHandler } from "@appport/mcp";
import { errors } from "@appport/protocol";
const handler = createMcpHandler(application, {
// Runs per MCP request. Verify credentials, then say who the caller is.
async context({ headers, authInfo }) {
const token = headers["authorization"]?.toString().replace(/^Bearer /, "");
if (!token) return undefined; // anonymous: AppPort allows only public capabilities
const session = await myApp.verify(token); // your AppPort `Session`
if (!session) throw errors.unauthorized("Invalid credentials");
return { session };
}
});
// e.g. a Next.js / Vercel route handler
export const POST = (request: Request) => handler(request);
export const GET = POST;
export const DELETE = POST;
对于Stdio或内在使用, createMcpServer(application, options) 返回时
SDK 软件 Server 连接到任何SDK运输.
选项( E)McpServerOptions: context, (中文(简体) ), serverInfo (对
应用程序的名称和版本), include, (中文(简体) ), prefix, (中文(简体) ), includeBuiltins。 。 。 .
主机拥有部署、路由、TLS、源码/ DNS 重新绑定的检查、速率
限制和认证。 主机也可以验证证书
{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}然后就把它当作 handler(request, { authInfo }); 内容
然后到达 context 作为 authInfo。 。 。 .
认证
适配器从不认证呼叫器,也从不隐含地信任它们. 这个
主机用品认证 session 和(或) principal - 同样的价值a
appPort的本地交通通行证 DispatchOptions 通过 context。 。 。 .
- 没有
context选项,或context返回无 ~ 调用已发出 匿名地说 AppPort授权人拒绝任何需要的能力 权限( e)UNAUTHORIZED;只有公共能力运行. context丢出一个AppPortError(单位:千美元)UNAUTHORIZED编号 :FORBIDDEN∗∗ 报告为a 工具错误。 任何其他例外都报告为 JSON-RPC 内部错误 没有细节.- 无法由 MCP 调用器在工具参数中提供身份或
_meta。 。 。 .
AppPort为会话设定了范围,从而提供稳定的,
每名打电话者 session.id。 。 。 .
能力接触
工具取自每个请求上显示的应用程序;没有 第二名单.
| 应用端口 | MCP 工具 |
|---|---|
请求能力 call.create | 工具 call_create (单位:千美元). → _选项 prefix(中文(简体) ) |
能力 inputSchema | 工具 inputSchema (必须是对象计划) |
能力 outputSchema | 工具 outputSchema (当物体计划) |
| 能力名称/版本/许可 | 工具 _meta["dev.appport/capability"] |
工具名是一个标签,不是身份:通过清单调用解析.
两个能力投射到一个工具名是一个错误,而不是覆盖.
流能力、非对象输入和保留 appport.* 命名空间
(除非 includeBuiltins)没有暴露。 工具发现列出
应用程序发布;它不通过调用者过滤——执行授权
当一个工具被调用时.
元数据
AppPort 请求的元数据包含在 MCP 中 tools/call _meta 对象和
原封不动地放在 AppRequest (单位:千美元)MCP_META 导出密钥 :
_meta 键 | Apport 字段 | 页:1 |
|---|---|---|
dev.appport/idempotencyKey | idempotencyKey | 重放是 AppPort (§13.1); 此软件包不保存缓存 |
dev.appport/timeoutMs | timeoutMs | 成为该能力的最后期限; AppPort 把它夹住( 第13.3节); 没有添加 MCP 默认值 |
dev.appport/traceId | traceId | 达到 context.traceId; AppPort 如果缺席则生成一个; 对结果的响应 _meta |
错误的值( 空字符串、 非正态超时) 被拒绝为
INVALID_REQUESTMCP 请求取消和 HTTP 客户端断开
该能力 context.signal。 。 。 .
错误
协议级别问题使用 SDK 的 JSON- RPC 错误: 格式错误的 JSON 或
电文 (-32700编号 :-32600),未知的方法(-32601),未知工具 (-32602, (中文(简体) ),
和适配器故障(-32603,没有细节). 每个 AppPort 结果都是工具
结果:成功 content (JSON文本)和 structuredContent; 失败
isError: true文字 CODE: message,以及 _meta["dev.appport/error"]
(单位:千美元)MCP_ERROR_META与 { code, category, retryable, details? }。 。 。 . details 实值
appPort已经消毒(§16).
| Appport 代码 | category |
|---|---|
INVALID_REQUEST, (中文(简体) ), INVALID_INPUT, (中文(简体) ), INVALID_PROTOCOL, (中文(简体) ), UNSUPPORTED_VERSION, (中文(简体) ), UNSUPPORTED_CAPABILITY_VERSION, (中文(简体) ), PAYLOAD_TOO_LARGE, (中文(简体) ), NO_COMPATIBLE_MATERIALIZATION | invalid_request |
UNAUTHORIZED | unauthenticated |
FORBIDDEN | forbidden |
NOT_FOUND, (中文(简体) ), UNKNOWN_CAPABILITY | not_found |
CONFLICT | conflict |
TIMEOUT | timeout |
RATE_LIMITED | rate_limited |
CANCELLED | cancelled |
STREAM_ERROR,名称空格扩展代码(acme.UPSTREAM_DOWN(中文(简体) ) | capability_failure |
INTERNAL_ERROR其它东西 | internal |
警卫
通过 MCP 显示能力 没有 绕过 AppPort 授权: 每
呼叫通过 AppPort 验证和应用程序的授权人及处理器
接收主机提供的会话/主机。 租户和资源隔离现象依然存在
申请人的责任,由能力处理者通过
上下文(例如: context.session.attributes; 呼叫者无法联系
另一个租户的数据通过MCP 比任何其他运输.
状态
无。 没有东西被缓存、存储或共享到呼叫之间; 新鲜的 SDK 服务器是 按 HTTP 请求构建。 持久和短暂状态(权威记录, session, operation)属于AppPort应用程序.
兼容性
createMcpBridge, (中文(简体) ), toMcpTools, (中文(简体) ), toToolName, (中文(简体) ), fromToolName 财务报告和审定财务报表 describeError
留下来. createMcpBridge(...).callTool(name, args, metadata?) 现在转发
AppPort 同位素键、超时和微量ID(以前已放弃)及其
成果现载 structuredContent 财务报告和审定财务报表 _meta. 偏爱 createMcpHandler 编号 :
createMcpServer,会讲MCP; fromToolName 能力名称丢失
包含 _ 而不在内部使用.
@appport/mcp/bridge (1.3.0) (中文(简体) )
@appport/mcp/bridge 只导出预测 : createMcpBridge, (中文(简体) ), toMcpTools, (中文(简体) ), toToolName, (中文(简体) ), fromToolName, (中文(简体) ), MCP_META, (中文(简体) ),
MCP_ERROR_META, (中文(简体) ), mcpErrorCategory 和他们的类型。 它从不进口 @modelcontextprotocol/sdk或在其申报中.
词根 @appport/mcp 导出相同名称外加 MCP 服务器(createMcpServer, (中文(简体) ), createMcpHandler),这确实如此。 MCP SDK的自带
仅引用 DOM 声明 HeadersInit,所以只使用节点的 TypeScript 项目(无) DOM 丽比, skipLibCheck: false)可以导入
@appport/mcp/bridge 但必须添加 DOM lib 或启用 skipLibCheck 输入 @appport/mcp 树根.
@appport/sdk 从这个子路径取出它的MCP桥出口.