graft
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGraft
Graft
Use this skill when the task is about creating or refining a Graft server, wrapping an existing API with Graft proxy mode, or updating contributor-facing docs and examples so they match the current package behavior.
graft当任务涉及创建或优化Graft服务器、使用Graft代理模式包装现有API,或者更新面向贡献者的文档与示例以匹配当前包的行为时,可使用本技能。
graftProduct thesis
产品理念
Graft's core value has three parts:
- Define once — tools with a name, schema, and handler.
- Serve as HTTP and MCP — from the same server, through a single shared pipeline (same auth, validation, middleware).
- Discovery is automatic — agents find tools via ,
agent.json,mcp.json. Humans get interactive docs (llms.txt) and an OpenAPI spec (/docs). Zero configuration./openapi.json
When explaining Graft, lead with all three parts. When showing examples, demonstrate both access patterns (MCP and HTTP) and mention what the server auto-serves. This applies to both source-based apps and proxy mode.
Graft的核心价值包含三部分:
- 一次定义 — 工具包含名称、模式和处理器。
- 双协议服务 — 在同一服务器上通过单一共享管道(相同的认证、验证、中间件)同时提供HTTP和MCP服务。
- 自动发现 — 代理可通过、
agent.json、mcp.json发现工具。用户可获取交互式文档(llms.txt)和OpenAPI规范(/docs),无需任何配置。/openapi.json
在介绍Graft时,需涵盖以上三点。展示示例时,需同时演示两种访问方式(MCP和HTTP),并提及服务器自动提供的内容。这适用于基于源码的应用和代理模式。
Workflow
工作流
- Identify the mode before proposing changes:
- App authoring: , tools, resources, prompts, HTTP routes, Node or fetch integration.
createApp(...) - Proxy/OpenAPI: or
graft serve --openapi ....graft.proxy.yaml - Docs/release hygiene: README, install instructions, skills, examples, contributor checks.
- Ground in the current repo before using memory:
- If tool access is available, inspect the current source, public exports, CLI commands, scaffold templates, and tests.
- If tool access is not available, ask for the smallest set of files or examples needed to avoid guessing.
- Follow the current public contract in examples and reviews:
- Inline tool examples: prefer .
app.tool('name', config) - Modular tool examples: prefer plus
defineTool(...).app.tool(definedTool) - Auth shapes: ,
true, or['role'].{ roles: [...] } - MCP Streamable HTTP endpoint: .
POST /mcp - Auto-served framework endpoints: ,
/.well-known/agent.json,/.well-known/mcp.json,/openapi.json,/docs,/llms.txt,/llms-full.txt./health - Full CLI: ,
serve,dev,check,test,studio,install.add-tool - When showing tool examples, demonstrate both the MCP invocation and the equivalent HTTP request (e.g.
tools/callorGET /list-items?q=hello).POST /create-entry
- Use tools where they materially improve correctness, but stay portable:
- With repo or shell access, inspect files and run validation commands after making changes.
- Without repo or shell access, state assumptions explicitly and keep recommendations tied to visible source or user-provided snippets.
- Load only the reference you need:
- App authoring: references/app-authoring.md
- Proxy/OpenAPI wrapping: references/proxy-openapi.md
- Validation, docs, and release hygiene: references/validation-release.md
- 提出修改前先确定模式:
- 应用开发:、工具、资源、提示词、HTTP路由、Node或fetch集成。
createApp(...) - 代理/OpenAPI模式:或
graft serve --openapi ...。graft.proxy.yaml - 文档/发布维护:README、安装说明、技能文档、示例、贡献者检查项。
- 优先基于当前仓库内容,而非依赖记忆:
- 若可访问工具,检查当前源码、公开导出、CLI命令、脚手架模板和测试用例。
- 若无法访问工具,请求所需的最小文件集或示例,避免猜测。
- 示例与评审需遵循当前公开约定:
- 内联工具示例:优先使用。
app.tool('name', config) - 模块化工具示例:优先使用搭配
defineTool(...)。app.tool(definedTool) - 认证格式:、
true或['role']。{ roles: [...] } - MCP流式HTTP端点:。
POST /mcp - 自动提供的框架端点:、
/.well-known/agent.json、/.well-known/mcp.json、/openapi.json、/docs、/llms.txt、/llms-full.txt。/health - 完整CLI命令:、
serve、dev、check、test、studio、install。add-tool - 展示工具示例时,需同时演示MCP的调用方式和对应的HTTP请求(例如
tools/call或GET /list-items?q=hello)。POST /create-entry
- 合理使用工具提升正确性,同时保持可移植性:
- 若可访问仓库或终端,修改后检查文件并运行验证命令。
- 若无法访问仓库或终端,明确说明假设,并确保建议与可见源码或用户提供的代码片段一致。
- 仅加载所需的参考文档:
- 应用开发:references/app-authoring.md
- 代理/OpenAPI包装:references/proxy-openapi.md
- 验证、文档与发布维护:references/validation-release.md
Quick examples
快速示例
Inline tool — both access patterns
内联工具 — 两种访问方式
ts
import { createApp } from '@schrepa/graft'
import { z } from 'zod'
const app = createApp()
app.tool('list_items', {
description: 'List items matching a query.',
params: z.object({ q: z.string() }),
auth: true,
handler: async ({ q }) => ({
items: ['hello', 'world'].filter((item) => item.includes(q)),
}),
})
export default appMCP ():
tools/calljson
{ "method": "tools/call", "params": { "name": "list_items", "arguments": { "q": "hello" } } }HTTP equivalent:
GET /list-items?q=hello
Authorization: Bearer <token>The same handler, auth middleware, and validation run for both.
ts
import { createApp } from '@schrepa/graft'
import { z } from 'zod'
const app = createApp()
app.tool('list_items', {
description: 'List items matching a query.',
params: z.object({ q: z.string() }),
auth: true,
handler: async ({ q }) => ({
items: ['hello', 'world'].filter((item) => item.includes(q)),
}),
})
export default appMCP ():
tools/calljson
{ "method": "tools/call", "params": { "name": "list_items", "arguments": { "q": "hello" } } }HTTP等效请求:
GET /list-items?q=hello
Authorization: Bearer <token>两种方式会运行相同的处理器、认证中间件和验证逻辑。
Proxy mode — graft.proxy.yaml
graft.proxy.yaml代理模式 — graft.proxy.yaml
graft.proxy.yamlyaml
target: https://petstore3.swagger.io/api/v3
tools:
- method: GET
path: /pet/findByStatus
name: find_pets_by_status
description: Find pets by status.
parameters:
type: object
properties:
status:
type: string
- method: POST
path: /pet
name: create_pet
description: Create a pet.
parameters:
type: object
properties:
name:
type: string
required: [name]Start the proxy server:
graft serve --config graft.proxy.yamlGraft exposes each configured operation as both an HTTP endpoint and an MCP tool, and auto-generates , , and discovery files.
/openapi.json/docsFor the direct OpenAPI path, use:
graft serve --openapi ./openapi.yaml --target https://api.example.comyaml
target: https://petstore3.swagger.io/api/v3
tools:
- method: GET
path: /pet/findByStatus
name: find_pets_by_status
description: Find pets by status.
parameters:
type: object
properties:
status:
type: string
- method: POST
path: /pet
name: create_pet
description: Create a pet.
parameters:
type: object
properties:
name:
type: string
required: [name]启动代理服务器:
graft serve --config graft.proxy.yamlGraft会将每个配置的操作同时暴露为HTTP端点和MCP工具,并自动生成、和服务发现文件。
/openapi.json/docs若要直接使用OpenAPI路径,可执行:
graft serve --openapi ./openapi.yaml --target https://api.example.comGuardrails
注意事项
- Do not document unsupported behavior just because an older example mentioned it.
- Keep examples executable and small; prefer one correct pattern over many variants.
- Prefer current source and tests over stale notes, blog posts, or memory.
- Do not mention registry or publishing artifacts unless they actually exist in the repo being edited.
- When a docs claim is likely to drift, add or update an automated check.
- 不要仅因旧示例提及就记录不支持的行为。
- 示例需可执行且精简;优先展示一种正确模式,而非多种变体。
- 优先参考当前源码和测试用例,而非过时的笔记、博客或记忆。
- 除非正在编辑的仓库中确实存在相关内容,否则不要提及注册表或发布制品。
- 若文档内容容易出现偏差,添加或更新自动化检查项。