@cat-factory/mcp-server
A 类 示范背景协议 服务器在 cat- defactory 上 公开
API 密码 (单位:千美元)/api/v1) (中文(简体) ). 它让一个MCP主机——克洛德桌面(Claude Desktop),一个IDE(IDE),一个代理框架(Agender frame)——规划关于a
工作空间的板子,开始和观看运行, 回答停放的决定,并读取运行的遥测.
网站上记录了使用该工具的情况数字 : MCP 服务器 拥有两个访问路径,即 配置表,工具表面和工作流程,为从未克隆过这种repo的阅读器. 这艘研究母舰在公布的柏油球中, 所以它保持自成一体, 而不是成为一个 指针;当工具表面或过滤器发生变化时,使两者保持步入.
这是一个 外观不是客户 每个工具都是一通电话
@cat-factory/sdk,工具表则由相同的
docs/openapi.json 4个SDK客户端来自此.
你需要这个包裹吗?
在MCP上达到猫因子部署有两种方式,它们服务于同一个服务器.
- 托管, (中文(简体) ),
POST /api/v1/mcp在部署本身。 没有要安装的: 给主机一个 URL 和钥匙。 如果主机会说 HTTP MCP 的话, 这是需要联系的 。 见backend/docs/public-api.md。 。 。 . - 这个包超乎寻常 它不需要你的后端部署 这是唯一的路径 一个不能说 HTTP MCP 主机, 它是唯一一个每个主机工具过滤器.
部署也会从此套件上挂载主机端点(handleMcpHttpRequest页:1
工具表、指令和结果渲染是两个路径上相同的字节.
运行它
与克洛德代码,在一行:
claude mcp add cat-factory \
--env CAT_FACTORY_BASE_URL=https://cat-factory.example.com \
--env CAT_FACTORY_API_KEY_FILE=$HOME/.config/cat-factory/api-key \
-- npx -y @cat-factory/mcp-server
或以任何主机的配置格式 :
// An MCP host's server config
{
"mcpServers": {
"cat-factory": {
"command": "npx",
"args": ["-y", "@cat-factory/mcp-server"],
"env": {
"CAT_FACTORY_BASE_URL": "https://cat-factory.example.com",
"CAT_FACTORY_API_KEY_FILE": "/home/you/.config/cat-factory/api-key",
},
},
},
}
从部署中切换密钥( Mint the key from the approach) (backend/docs/public-api.md §Setup)并给予它 最窄处
工作范围数字 : read ⊂ write ⊂ decide ⊂ admin。每个工具都瞄准键的
工作空间,关键是决定一个模型能做什么.
| 变量 | 含义 |
|---|---|
CAT_FACTORY_BASE_URL | 部署的起源. 要求. |
CAT_FACTORY_API_KEY | 公用API密钥. 需要, 除非给出下面的文件 . |
CAT_FACTORY_API_KEY_FILE | 取而代之的是持有密钥的文件 。 两者都不行. |
CAT_FACTORY_MCP_GROUPS | 逗号分离资源组曝光. 全部解开. |
CAT_FACTORY_MCP_TOOLS | 要曝光的逗号分隔工具名 。 取消所有其它过滤器离开. |
CAT_FACTORY_MCP_EXCLUDE_TOOLS | 逗号分隔工具名以保留,在所有其他过滤器之后应用 . |
CAT_FACTORY_MCP_READ_ONLY | true {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}只揭露那些改变不了什么的工具 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}我. |
CAT_FACTORY_MCP_MAX_RESULT_CHARS | 在一个工具结果上设置上限。 默认十万. |
CAT_FACTORY_MCP_TIMEOUT_MS | 请求的最后期限已经到SDK了. 0 关闭它. |
CAT_FACTORY_MCP_MAX_RETRIES | 报复可挽回的失败, 传递给SDK. |
缺少证书、未知的团体或工具名称、过滤器组合不会暴露任何东西, 和所有非数字上限 启动时失败。一个服务器,它出现后每一次呼叫都会失败 被主机报告为连接型,模型花掉时会发现其他的.
保留主机配置中的密钥
CAT_FACTORY_API_KEY_FILE 命名要读取密钥的文件。 一个stdio服务器的环境是
主机的配置文件, 所以内线变量表示一个家中的平白文字中的长寿证书
目录,可以读取所有可以读取的文件,并在每一个备份和每个备份中显示
屏幕共享 。 路径不是秘密,所以指向它,让钥匙在锁上的地方活下来
下调( e)chmod 600一个挂起的秘密,一个秘密管理 侧车的滴.
设置 两者 拒绝而不是优先解决: 意思是轮回可以降落在无人读取的半个位置上 而部署继续和旧的一起工作 键直到取消.
选择模型所能达到的
三个滤波器,最后最窄,它们都是方便而非边界(密钥的范围是: 边界 :
CAT_FACTORY_MCP_GROUPS是操作员所想的粗糙的单位:“在这个工具上没有调试工具”.CAT_FACTORY_MCP_TOOLS显示一个明确选择的集。 精准,但必须重新编辑 任何时候/api/v1不断增长,被遗忘的编辑默默地抑制了新的能力.CAT_FACTORY_MCP_EXCLUDE_TOOLS并不断承认其他一切, 包括后来增加的工具。 这是为了让一个人的能力远离一个模型而需要达到的:CAT_FACTORY_MCP_EXCLUDE_TOOLS=notifications_act在不计算成本的情况下将PR-merging工具移走 属于它的收件箱.
无论关闭什么,服务器 在它的指示中说,命名被扣留的工具 表示部署仍然支持他们。 一种无法解释的缺席是指: 平台不能这样做,然后向用户报告,或绕行.
工作流程
创建任务,运行,观看,回答公园. 这里几乎每场会议都是这样
services_list:董事会的服务框架. 一项任务是在其中一项下创建的serviceId从这里来 而不是猜测.pipelines_list: 哪些管道可以启动任务, 哪些管道可以无头启动 .tasks_create(单位:千美元)serviceId, (中文(简体) ),body.title, (中文(简体) ),body.description, (中文(简体) ),body.taskType返回taskId。还没有运行;这是一张董事会卡.tasks_start(单位:千美元)taskId(中文(简体) ) 支出额:它开始一个真正的特工 运行对一个真正的仓库,和 返回时runId。首先与人确认;工具附加了说明destructiveHint这样 大部分主机都会问.tasks_get_run(单位:千美元)runId调查一下 没有流线工具(见下文), 代理步骤 所以每15到30秒投票一次 而不是安静下来 继续走直到 状态是终端或决定已停放.decisions_list(单位:千美元)runId停止前进的跑步 通常都由人类决定, 它会无限期地等待 设计。 跟别人说decisions_*工具 (单位:千美元)decisions_incorporate, (中文(简体) ),decisions_proceed, (中文(简体) ),decisions_choose_fork, (中文(简体) ),decisions_resolve_judge或者把它留给一个人.notifications_list:人可诉尾,包括合并决定.notifications_act可以合并拉出请求,这是另一个花费的工具.
为了对一个没有挂牌和没有被推到仓库的 提供的简介进行跑步
jobs_* 组合在一步中是相同的循环 : jobs_create 民意调查 jobs_get → jobs_cancel。 。 。 .
把它装在自己的交通工具上 而不是装在地上
import { createCatFactoryMcpServer } from '@cat-factory/mcp-server'
const { server, tools } = createCatFactoryMcpServer({ baseUrl, apiKey })
await server.connect(myTransport)
自己骑去
两次出口 用于部署 想要服务 MCP 从自己的路线,而不是有 每一个呼叫者 生成一个进程 :
import { handleMcpHttpRequest, refuseMcpMethod } from '@cat-factory/mcp-server/http'
app.all('/api/v1/mcp', async (c) => {
const refused = refuseMcpMethod(c.req.method) // 405 + Allow: POST for GET/DELETE
if (refused) return refused
const key = authenticate(c) // your gate: this package never decides who may call
return handleMcpHttpRequest(c.req.raw, {
baseUrl: new URL(c.req.url).origin,
apiKey: key.secret, // the CALLER's key, so every scope rule applies unchanged
readOnly: key.scope === 'read',
readOnlyReason: 'key-scope',
})
})
没错 无国籍人:每个请求一个服务器,没有设定会话 ID 和 JSON 响应而不是 事件流。 这不是一个简化,而是唯一的形状 通过运行的时间,这必须 服务——工人要求从任何孤立的边缘取出土地,而节点部署规模超过 一个实例有同样的问题,没有粘滞的路由, 所以一个按会话键的服务器工作在一个 工艺和生产间歇性故障.
所有东西 handleMcpHttpRequest 因此,访问范围是按Web标准书写的,进口没有
节点内置( N)test/runtime-neutral.test.ts 执行, 因为类型检查不能: 这个包的
拥有 bin 是一个节点进程,但主机的一半被捆绑到部署中' 工人,在哪里 node:fs
不在建设时解决。 这也是为什么 optionsFromEnv 将其文件读取器作为
依赖性而非进口 readFileSync编辑 ./http 子路径是唯一的条目
保证: 包根再导出 stdio 靴子,其 node:process 导入捆绑器失败
摇出,所以任何捆绑进口的东西 @cat-factory/mcp-server/http 而从来无根.
对于一个运输,这两个封面, createCatFactoryMcpServer 返回空块 Server。 。 。 .
这是什么意思
表面决定了三件事: 哪些工具可以列出, 如何得出一个结果, 如何做出 一个失败。 其他一切——认证、重试、错误分类、页码、编码、截止日期——是 sDK的,所以一个工具的行为 完全像同一个调用代码。 第二次执行 这些规则会是第二处 使这些规则被错误地理解.
具体而言:
- 生成工具表 (单位:千美元)
src/tools.generated.ts,通过pnpm gen:sdk),所以是一个终点 添加到/api/v1成为一个工具,没有人决定两次pnpm check:sdkcI 失败 漂来漂去。 绝不用手编辑. - 输入计划是Spec本身的. 一个工具
body计划由相同的 合同部署验证, 因此工具无法描述请求形状服务器 将拒绝。 OPEN词汇(一个封闭的集加一个有记录的逃生舱口,例如taskType(中文(简体) ) 永远不会缩小为enum,因为这会拒绝服务器接受的价值. - 输出的图案故意会比规格松散. 每个用JSON回答的工具
对象声明
outputSchema返回时structuredContent在文字旁边。 但是一个打电话的人 拥有MCP客户端 VALIDATES 与该计划相对应的结果,以及/api/v1永远添加,所以 发射的版本没有required,没有enum,没有关闭anyOf并且没有长度或范围界限. 每一份都将成为旧的本套装副本 拒绝新部署的方法 诚实的回答。 一个词汇的已知成员在字段的描述中被描述, 如果新成员不能使其失效,而联合国联盟则除了其 诽谤者:甚至type,因为变体 后期的工会收益不必 对象. - 辩证止于出门. 检查所需的路径 ID , 以便请求 - 尸体去部署, 422名外地, 更有用 对于一个模型 比任何这个层可以说.
- 失败是工具内容,而不是协议错误 . 协议错误表示 SERVER
行为不当,主机不会向模型显示. 一张422
code, (中文(简体) ),details.reason编辑 每个外地issues这是最可操作的东西 这个外表曾经返回, 所以它通过 通过逐字记录而不是重新措辞.
工具表面
每个曝光操作一个工具, 命名 <group>_<method> 匹配 SDK 调用
(单位:千美元)client.tasks.create() ⇄ tasks_create) (中文(简体) ). 服务器报告启动时的活计数和列表
工具本身在协议上,这是它唯一不能停止的地方:
| 组 | 它包含什么 |
|---|---|
jobs_* | 无头运行 公共内线管道 与一个简报. |
services_* | 董事会的服务框架:列出它们,或创建一个(可选回放). |
spec_* | 一个服务在repo的要求树 和从它得到的Gherkin。 唯相读取. |
repos_* | 一个服务的存储器可以备份,并且每个服务已经备份. |
tasks_* | 一个任务的整个生命周期:创建,编辑,开始,停止,再试,读取它的运行,加上它的依赖性和要求链接. |
pipelines_* | 哪个管道可以启动任务. |
task_types_* | 什么样的任务可以被创造出来, 并且每个类型都接受. |
notifications_* | 人可操作收件箱,包括合并后尾. |
webhook_* | 工作空间是通知和运行周期事件的出站终点. |
usage_* | 计费期的预算状况, 并用回购,票或跑. |
me_* | 召唤的关键是什么,它可能做什么. |
decisions_* | 一个停放的跑跑的人的决定. |
debug_* | 一跑记录了遥测:LLM调用,代理语境,下行日志. |
evidence_* | 如何运行证明:核查报告,结果总结,被俘文物. |
merge_records_* | 自动化政策背后的证据, 及其每等卷起. |
keys_* | 工作空间自己的API密钥:提供,列表,撤销. |
三个行动被故意缺席,服务器在指示中说
而不是留下一个模型来完成平台不能做到这一点. GET /api/v1/jobs/{id}/events 财务报告和审定财务报表
GET /api/v1/tasks/{taskId}/events 是 SSE 流,一个工具调用返回一个结果而不是
流媒体频道:民意调查 jobs_get 编号 : tasks_get_run,或者通过 SDK 消耗溪流。 添加中
捆绑的"等待跑步"工具无法修复,因为一个跑步停在人的决定上等待
无限期 所以任何这样的工具 都是一种装作答案的超时。 第三个是
文物字节下载( o)GET /api/v1/artifacts/{artifactId}/blob: 工具结果为
文本或声明的内容块,不是任意的字节流,所以列出带有
evidence_list_artifacts 并用相同的键从 HTTP (或通过 SDK) 上获取字节.
在新的流线操作中生成 FAILS 无人分类, 所以上面的列表不能去 安静地呆着.
打电话的人应该知道的事情
readOnlyHint从 HTTP 方法设置.destructiveHint财务报告和审定财务报表idempotentHint设置在 产生实际资金或合并拉动请求的业务tasks_start, (中文(简体) ),tasks_retry, (中文(简体) ),jobs_create, (中文(简体) ),notifications_act, (中文(简体) ),tasks_delete并随地离开UNSET. 这种不对称是故意的: 协议默认一个未设定的提示已经是谨慎的提示, 毯子这么长destructiveHint: false{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}因为廉价的写作 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}会降低主持人的警惕性 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}所以你应该知道 猜对了.tasks_delete情况是readOnlyHint完全不能表示: 破坏性.- 只读模式是一种方便,而不是边界. 它从此服务器中删除工具; 密钥
仍然有它设计的任何范围。 薄荷a
read- 瞄准边框的密钥 这个 每个工具的两个过滤器也一样。 (主机端点运行此倒数: 它 DERIVES 仅从密钥的范畴读取, 和作为原因的指令名称, 所以模型问 用于更大的密钥而不是配置编辑。 ) - 不符合的结果是REFUSED,而不是截取. 信件名称
有,极限,还有从两边出去的路:
limit编号 :cursor在列表的终点,offset在调试文本上读取, 或是更大的CAT_FACTORY_MCP_MAX_RESULT_CHARS半个对象 无法满足它被切掉的输出方案, 而一个被切开的前缀将整个盖花在 一个文件,它自己的说明告诉模型不要读取它. - 结果是紧凑的JSON. 双相距缩进比模型更能读取人类 白空间的每个结果的大约三分之一。 一个想要的宿主可以重新打印 结构化内容也得到.
- 在服务器的指示中调用工具,来源于这些 注释而不是重发在散文中,所以不在此服务器上保存的工具不会被命名为 one to 小心点.
发展
pnpm --filter @cat-factory/mcp-server build
pnpm --filter @cat-factory/mcp-server test:run
pnpm gen:sdk # regenerate the tool table after a contracts change
pnpm check:sdk # the CI drift guard
pnpm check:publish # after a build: the empty-shell / publint / attw guard
三层的覆盖, 和分裂 是关于每个可以看到:
- 单位测试 (单位:千美元)
test/驱动 a 真实 MCP客户端在对真实的SDK进行内传 客户fetch因此,一个列出但不能称为失败测试的工具,而不是 航运.test/stdio.test.ts覆盖可执行文件的规则(在宣布前连接,每 人类可以读取的字节从stdout,拒绝而不是开始) 没有产物. - 二. 多边协商进程的两个阶段
backend/internal/sdk-smoketest驱动两条通道对齐一个真实 后端 :--only=mcp孕育出人类dist/bin.js作为一个真正的过程,--only=mcp-hosted连接 一个真正的可流 HTTP 客户端的部署POST /api/v1/mcp两者皆是 可以看到已公布的输出计划 与部署的实际答案, 因为客户端验证了它们; 运行两个对一板是抓住两条路径的方法 回答不一样. pnpm check:publish覆盖此套件最暴露的形状: 1bin条目指向 在一个被点缀的dist,这正是另外两个包曾经作为空壳到达npm的方式.