Loading...
Loading...
Use when building, refactoring, or documenting Graft apps and proxies, including when asked to create a tool server, API server, dual-protocol server, or MCP-HTTP bridge. Graft's core thesis: define tools once and serve them as both HTTP REST endpoints and MCP tools from the same server, with discovery, docs, and OpenAPI generated automatically. Covers concrete actions such as defining tools and handlers, configuring authentication middleware, setting up HTTP and stdio transports, generating OpenAPI documentation, wrapping existing APIs via proxy mode, and wiring up the full CLI workflow.
npx skill4agent add schrepa/graft graftgraftagent.jsonmcp.jsonllms.txt/docs/openapi.jsoncreateApp(...)graft serve --openapi ...graft.proxy.yamlapp.tool('name', config)defineTool(...)app.tool(definedTool)true['role']{ roles: [...] }POST /mcp/.well-known/agent.json/.well-known/mcp.json/openapi.json/docs/llms.txt/llms-full.txt/healthservedevcheckteststudioinstalladd-tooltools/callGET /list-items?q=helloPOST /create-entryimport { 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 apptools/call{ "method": "tools/call", "params": { "name": "list_items", "arguments": { "q": "hello" } } }GET /list-items?q=hello
Authorization: Bearer <token>graft.proxy.yamltarget: 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.yaml/openapi.json/docsgraft serve --openapi ./openapi.yaml --target https://api.example.com