@ byokit/ mcp
在可流的HTTP上托管了工具和资源. 官方MCP TypeScript SDK 拥有 协议,包括初始化、事件流和会话终止。 这个包 添加设备签名, 在每个请求上认证, 以及绑定在一个人身上的会话 . 它运行于节点22.18上或后期;是一个服务器包,没有浏览器或电话条目.
安装片段
npm install @byokit/mcp zod@4
设备批准后设置 MCP_URL 到您的 HTTPS 端点和 MCP_TOKEN 改为
在您的外壳的私人环境中返回的访问符 。 这些是一行加法:
# Claude Code
claude mcp add --transport http demo "$MCP_URL" --header "Authorization: Bearer $MCP_TOKEN"
# Codex
codex mcp add demo --url "$MCP_URL" --bearer-token-env-var MCP_TOKEN
# Cursor (opens the install dialog; macOS uses open, Linux uses xdg-open)
node --input-type=module -e 'import {spawnSync} from "node:child_process"; const config=Buffer.from(JSON.stringify({url:process.env.MCP_URL,headers:{Authorization:`Bearer ${process.env.MCP_TOKEN}`}})).toString("base64"); spawnSync(process.platform === "darwin" ? "open" : "xdg-open", [`cursor://anysphere.cursor-deeplink/mcp/install?name=demo&config=${encodeURIComponent(config)}`], {stdio:"ignore"});'
头和安装-链接格式保存客户端配置中的符. 保留 那个配置的私人。 目前还没有客户端自动启动设备流. 命令格式 : HTTP 添加, (中文(简体) ), 远程添加, (中文(简体) ), 安装链接。 。 。 .
最小服务器
import { createServer } from 'node:http';
import { z } from 'zod';
import { overrideStore } from '@byokit/secrets';
import { deviceFlow, hostedMcp } from '@byokit/mcp';
// In-memory demo only. Supply your app's secrets backend for persistent grants.
const auth = deviceFlow({
store: overrideStore({}),
verificationUri: 'http://127.0.0.1:3000/approve',
});
const kit = hostedMcp({
name: 'demo', version: '0.1.0', url: 'http://127.0.0.1:3000/mcp', auth, device: auth,
mount(m) {
m.tool('hello', { inputSchema: { name: z.string() } }, async ({ name }, context) => {
await context.progress(1, 1);
return { content: [{ type: 'text', text: `${context.principal.name} says hello to ${name}.` }] };
});
m.resource('profile', 'demo://profile', { mimeType: 'text/plain' }, (uri, context) => ({
contents: [{ uri: uri.href, text: context.principal.name, mimeType: 'text/plain' }],
}));
},
});
const http = createServer((req, res) => { void kit.handle(req, res); });
http.listen(3000, '127.0.0.1');
// In your authenticated account page, after Umer explicitly approves the typed code:
function approveForDemoUser(typedCode: string) {
auth.approve(typedCode, { id: 'umer', name: 'Umer' });
}
// On shutdown: await kit.close(); http.close();
主机拥有它的收听器,帐号页和部署. 在生产和生产中使用HTTPS
通过公共终点为 url该工具包根据该URL验证主机和原产地;
您的反向代理必须保存公共主机。 在这条路径及其上挂载处理器
设备子路径。 它不为批准页服务,也不执行账户登录.
自动流量
- 贾森后
{}改为/mcp/device/code。答复中包含device_code, (中文(简体) ),user_code, (中文(简体) ),verification_uri, (中文(简体) ),expires_in财务报告和审定财务报表interval(秒数). - 显示校验地址和用户代码 。 那个人签到主机帐户
并明确批准。 认证的CSRF保护的页面呼叫
auth.approve(userCode, principal);设备不能选择自己的本能. - 贾森后
{ "device_code": "…" }改为/mcp/device/token,不会比interval。 。 。 .pending表示仍需批准;busy意思是等到投票前再说. 核准数量access_token, (中文(简体) ),token_type: "Bearer"财务报告和审定财务报表expires_in一次就是这样. - 发送
Authorization: Bearer …在每一个 POST 上,获取和删除/mcp. SDK 软件 谈判初始化并供应会话头. 取消赠款await auth.revoke(token); 过期或被撤销的令牌停止对现有会话的工作.
同一流量可直接与 begin(), (中文(简体) ), approve() 财务报告和审定财务报表 poll()。设备代码
5分钟后失效;30天后失效;待投票时违约为5个
秒数。 一切皆能现相. 工具箱只保留待发地图中的设备编码散列
并将SHA-256号接通式散列车作为提供的名称储存 @byokit/secrets
Keystore。没有保存纯文本访问符。 一个密封的 fileStore({ path, passphrase })
或者OS密钥环后端可以坚持这些授予;主机通过每一个路径和秘密.
该工具包不读取环境变量、日志证书,也不检查其他应用程序.
McpError.code 区分 unauthorized, (中文(简体) ), expired, (中文(简体) ), invalid, (中文(简体) ), pending, (中文(简体) ), busy, (中文(简体) ),
session 财务报告和审定财务报表 failed;它的信息是一个固定的平话. 未知的处理器和
存储例外成为 failed,而不披露其原始消息或堆栈.
工具返回出错结果;资源返回协议出错. 成功处理器
结果为应用数据:主机必须保留它们和它自己的HTTP日志中的证书.
Authenticator.authenticate(token) 是未来授权计划的接合点.
OAuth 发现、重定向和刷新没有执行。 这个设备流是套件
设置 API,不是 OAuth 授权服务器 .
会议和部署
每个初始化都会在 SDK 服务器上挂载新的定义. 回电收到
当前请求的本金,取消信号和一个进度发送器。 同时
请求有不同的上下文。 默认会话持续30分钟( E)sessionMs和
无法被他人重复使用。 设备批准和会话处于内存中: 使用一个
过程,或粘接的路由。 恢复损失等待批准和会议;已保存
象征性赠款留在主店。 连续续会和分期会议
本版本未提供。 当请求打开时授权流; 主机
账户访问变更时,应当取消长期运行的工作.
maxPending 财务报告和审定财务报表 maxSessions 默认为 1000。 把设备端点放在后面
主机的每源速率限制 。 托肯没有隐含的工具范围;主机执行它
使用所提供本金的回调权限. close() 结束工具箱的会话
并拒绝更多的请求,而主机拥有关闭其收听器.
检查
从寄存器根 :
export TMPDIR=$(mktemp -d /tmp/bk-XXXX)
trap 'rm -rf "$TMPDIR"' EXIT
npm run build
npm run check
sh scripts/test.sh 'packages/mcp/test/*.test.ts'
npm run smoke:pack
测试使用真实的SDK客户端和回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回 存储。 不需要账户、外部网络或模型.