@rune-kit/rune 2.10.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +65 -6
- package/commands/rune.md +168 -168
- package/compiler/__tests__/detect-invariants.test.js +136 -0
- package/compiler/__tests__/doctor-mesh.test.js +229 -0
- package/compiler/__tests__/hook-dispatch.test.js +91 -0
- package/compiler/__tests__/hooks-antigravity.test.js +118 -0
- package/compiler/__tests__/hooks-cursor.test.js +139 -0
- package/compiler/__tests__/hooks-install.test.js +305 -0
- package/compiler/__tests__/hooks-merge.test.js +204 -0
- package/compiler/__tests__/hooks-tiers.test.js +519 -0
- package/compiler/__tests__/hooks-windsurf.test.js +115 -0
- package/compiler/__tests__/inject-claude-md.test.js +152 -0
- package/compiler/__tests__/load-invariants.test.js +408 -0
- package/compiler/__tests__/onboard-invariants.test.js +240 -0
- package/compiler/adapters/hooks/antigravity.js +140 -0
- package/compiler/adapters/hooks/claude.js +166 -0
- package/compiler/adapters/hooks/cursor.js +191 -0
- package/compiler/adapters/hooks/index.js +82 -0
- package/compiler/adapters/hooks/tier-emitter.js +182 -0
- package/compiler/adapters/hooks/windsurf.js +202 -0
- package/compiler/bin/rune.js +196 -6
- package/compiler/commands/hook-dispatch.js +87 -0
- package/compiler/commands/hooks/install.js +120 -0
- package/compiler/commands/hooks/merge.js +211 -0
- package/compiler/commands/hooks/presets.js +116 -0
- package/compiler/commands/hooks/status.js +112 -0
- package/compiler/commands/hooks/tiers.js +221 -0
- package/compiler/commands/hooks/uninstall.js +94 -0
- package/compiler/doctor.js +236 -0
- package/contexts/dev.md +34 -34
- package/contexts/research.md +43 -43
- package/contexts/review.md +55 -55
- package/extensions/ai-ml/PACK.md +88 -88
- package/extensions/ai-ml/skills/ai-agents.md +172 -172
- package/extensions/ai-ml/skills/code-sandbox.md +187 -187
- package/extensions/ai-ml/skills/deep-research.md +146 -146
- package/extensions/ai-ml/skills/embedding-search.md +66 -66
- package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -74
- package/extensions/ai-ml/skills/llm-architect.md +125 -125
- package/extensions/ai-ml/skills/llm-integration.md +64 -64
- package/extensions/ai-ml/skills/prompt-patterns.md +72 -72
- package/extensions/ai-ml/skills/rag-patterns.md +66 -66
- package/extensions/ai-ml/skills/web-extraction.md +114 -114
- package/extensions/analytics/PACK.md +92 -92
- package/extensions/analytics/skills/ab-testing.md +72 -72
- package/extensions/analytics/skills/dashboard-patterns.md +83 -83
- package/extensions/analytics/skills/data-validation.md +68 -68
- package/extensions/analytics/skills/funnel-analysis.md +81 -81
- package/extensions/analytics/skills/sql-patterns.md +57 -57
- package/extensions/analytics/skills/statistical-analysis.md +79 -79
- package/extensions/analytics/skills/tracking-setup.md +71 -71
- package/extensions/backend/PACK.md +104 -104
- package/extensions/backend/skills/api-patterns.md +84 -84
- package/extensions/backend/skills/async-pipeline.md +193 -193
- package/extensions/backend/skills/auth-patterns.md +97 -97
- package/extensions/backend/skills/background-jobs.md +133 -133
- package/extensions/backend/skills/caching-patterns.md +108 -108
- package/extensions/backend/skills/cli-generation.md +133 -133
- package/extensions/backend/skills/database-patterns.md +87 -87
- package/extensions/backend/skills/middleware-patterns.md +104 -104
- package/extensions/chrome-ext/PACK.md +93 -93
- package/extensions/chrome-ext/skills/cws-preflight.md +143 -143
- package/extensions/chrome-ext/skills/cws-publish.md +104 -104
- package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -251
- package/extensions/chrome-ext/skills/ext-messaging.md +139 -139
- package/extensions/chrome-ext/skills/ext-storage.md +133 -133
- package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -164
- package/extensions/content/PACK.md +96 -96
- package/extensions/content/skills/blog-patterns.md +88 -88
- package/extensions/content/skills/cms-integration.md +131 -131
- package/extensions/content/skills/content-scoring.md +107 -107
- package/extensions/content/skills/i18n.md +83 -83
- package/extensions/content/skills/mdx-authoring.md +137 -137
- package/extensions/content/skills/reference.md +1014 -1014
- package/extensions/content/skills/seo-patterns.md +67 -67
- package/extensions/content/skills/video-repurpose.md +153 -153
- package/extensions/devops/PACK.md +101 -101
- package/extensions/devops/skills/chaos-testing.md +67 -67
- package/extensions/devops/skills/ci-cd.md +75 -75
- package/extensions/devops/skills/docker.md +58 -58
- package/extensions/devops/skills/edge-serverless.md +163 -163
- package/extensions/devops/skills/infra-as-code.md +158 -158
- package/extensions/devops/skills/kubernetes.md +110 -110
- package/extensions/devops/skills/monitoring.md +57 -57
- package/extensions/devops/skills/server-setup.md +64 -64
- package/extensions/devops/skills/ssl-domain.md +42 -42
- package/extensions/ecommerce/PACK.md +116 -116
- package/extensions/ecommerce/skills/cart-system.md +79 -79
- package/extensions/ecommerce/skills/inventory-mgmt.md +102 -102
- package/extensions/ecommerce/skills/order-management.md +126 -126
- package/extensions/ecommerce/skills/payment-integration.md +472 -472
- package/extensions/ecommerce/skills/shopify-dev.md +69 -69
- package/extensions/ecommerce/skills/subscription-billing.md +93 -93
- package/extensions/ecommerce/skills/tax-compliance.md +117 -117
- package/extensions/gamedev/PACK.md +142 -142
- package/extensions/gamedev/skills/asset-pipeline.md +74 -74
- package/extensions/gamedev/skills/audio-system.md +129 -129
- package/extensions/gamedev/skills/camera-system.md +87 -87
- package/extensions/gamedev/skills/ecs.md +98 -98
- package/extensions/gamedev/skills/game-loops.md +72 -72
- package/extensions/gamedev/skills/input-system.md +199 -199
- package/extensions/gamedev/skills/multiplayer.md +180 -180
- package/extensions/gamedev/skills/particles.md +105 -105
- package/extensions/gamedev/skills/physics-engine.md +89 -89
- package/extensions/gamedev/skills/scene-management.md +146 -146
- package/extensions/gamedev/skills/threejs-patterns.md +90 -90
- package/extensions/gamedev/skills/webgl.md +71 -71
- package/extensions/mobile/PACK.md +106 -106
- package/extensions/mobile/skills/app-store-connect.md +152 -152
- package/extensions/mobile/skills/app-store-prep.md +66 -66
- package/extensions/mobile/skills/deep-linking.md +109 -109
- package/extensions/mobile/skills/flutter.md +60 -60
- package/extensions/mobile/skills/ios-build-pipeline.md +142 -142
- package/extensions/mobile/skills/native-bridge.md +66 -66
- package/extensions/mobile/skills/ota-updates.md +97 -97
- package/extensions/mobile/skills/push-notifications.md +111 -111
- package/extensions/mobile/skills/react-native.md +82 -82
- package/extensions/saas/PACK.md +116 -116
- package/extensions/saas/skills/billing-integration.md +200 -200
- package/extensions/saas/skills/feature-flags.md +130 -130
- package/extensions/saas/skills/multi-tenant.md +103 -103
- package/extensions/saas/skills/onboarding-flow.md +139 -139
- package/extensions/saas/skills/subscription-flow.md +95 -95
- package/extensions/saas/skills/team-management.md +144 -144
- package/extensions/security/PACK.md +99 -99
- package/extensions/security/skills/api-security.md +140 -140
- package/extensions/security/skills/compliance.md +68 -68
- package/extensions/security/skills/owasp-audit.md +64 -64
- package/extensions/security/skills/pentest-patterns.md +77 -77
- package/extensions/security/skills/secret-mgmt.md +65 -65
- package/extensions/security/skills/supply-chain.md +65 -65
- package/extensions/trading/PACK.md +80 -80
- package/extensions/trading/skills/chart-components.md +55 -55
- package/extensions/trading/skills/experiment-loop.md +125 -125
- package/extensions/trading/skills/fintech-patterns.md +47 -47
- package/extensions/trading/skills/indicator-library.md +58 -58
- package/extensions/trading/skills/quant-analysis.md +111 -111
- package/extensions/trading/skills/realtime-data.md +58 -58
- package/extensions/trading/skills/trade-logic.md +104 -104
- package/extensions/ui/PACK.md +130 -130
- package/extensions/ui/skills/a11y-audit.md +91 -91
- package/extensions/ui/skills/animation-patterns.md +127 -127
- package/extensions/ui/skills/component-patterns.md +100 -100
- package/extensions/ui/skills/design-decision.md +108 -108
- package/extensions/ui/skills/design-system.md +68 -68
- package/extensions/ui/skills/landing-patterns.md +155 -155
- package/extensions/ui/skills/palette-picker.md +173 -173
- package/extensions/ui/skills/react-health.md +90 -90
- package/extensions/ui/skills/type-system.md +125 -125
- package/extensions/ui/skills/web-vitals.md +153 -153
- package/extensions/zalo/PACK.md +145 -145
- package/extensions/zalo/skills/zalo-oa-mcp.md +317 -317
- package/extensions/zalo/skills/zalo-oa-messaging.md +429 -429
- package/extensions/zalo/skills/zalo-oa-setup.md +236 -236
- package/extensions/zalo/skills/zalo-oa-webhook.md +189 -189
- package/extensions/zalo/skills/zalo-personal-messaging.md +194 -194
- package/extensions/zalo/skills/zalo-personal-setup.md +153 -153
- package/extensions/zalo/skills/zalo-rate-guard.md +219 -219
- package/hooks/auto-format/index.cjs +48 -48
- package/hooks/hooks.json +111 -111
- package/hooks/post-session-reflect/index.cjs +189 -189
- package/hooks/pre-compact/index.cjs +95 -95
- package/hooks/run-hook.cmd +1 -1
- package/hooks/secrets-scan/index.cjs +100 -100
- package/hooks/session-start/index.cjs +71 -71
- package/hooks/typecheck/index.cjs +65 -65
- package/package.json +63 -63
- package/references/ui-pro-max-data/LICENSE-UI-PRO-MAX +21 -21
- package/references/ui-pro-max-data/charts.csv +26 -26
- package/references/ui-pro-max-data/colors.csv +161 -161
- package/references/ui-pro-max-data/styles.csv +68 -68
- package/references/ui-pro-max-data/typography.csv +74 -74
- package/references/ui-pro-max-data/ui-reasoning.csv +162 -162
- package/references/ui-pro-max-data/ux-guidelines.csv +99 -99
- package/skills/adversary/SKILL.md +283 -283
- package/skills/asset-creator/SKILL.md +157 -157
- package/skills/audit/SKILL.md +147 -2
- package/skills/autopsy/SKILL.md +335 -335
- package/skills/ba/SKILL.md +85 -1
- package/skills/brainstorm/SKILL.md +380 -342
- package/skills/browser-pilot/SKILL.md +169 -168
- package/skills/constraint-check/SKILL.md +165 -165
- package/skills/context-engine/SKILL.md +408 -404
- package/skills/cook/SKILL.md +917 -863
- package/skills/db/SKILL.md +273 -273
- package/skills/debug/SKILL.md +465 -465
- package/skills/dependency-doctor/SKILL.md +265 -235
- package/skills/deploy/SKILL.md +274 -231
- package/skills/design/DESIGN-REFERENCE.md +365 -365
- package/skills/design/SKILL.md +590 -589
- package/skills/doc-processor/SKILL.md +254 -254
- package/skills/docs/SKILL.md +374 -374
- package/skills/docs-seeker/SKILL.md +178 -177
- package/skills/fix/SKILL.md +332 -330
- package/skills/git/SKILL.md +339 -339
- package/skills/hallucination-guard/SKILL.md +220 -219
- package/skills/incident/SKILL.md +254 -253
- package/skills/integrity-check/SKILL.md +169 -169
- package/skills/journal/SKILL.md +241 -240
- package/skills/launch/SKILL.md +344 -344
- package/skills/logic-guardian/SKILL.md +269 -251
- package/skills/marketing/SKILL.md +351 -289
- package/skills/mcp-builder/SKILL.md +425 -425
- package/skills/neural-memory/SKILL.md +359 -362
- package/skills/onboard/SKILL.md +432 -403
- package/skills/onboard/references/invariants-template.md +76 -0
- package/skills/onboard/scripts/detect-invariants.js +439 -0
- package/skills/onboard/scripts/inject-claude-md.js +150 -0
- package/skills/onboard/scripts/onboard-invariants.js +194 -0
- package/skills/perf/SKILL.md +347 -346
- package/skills/plan/SKILL.md +435 -428
- package/skills/preflight/SKILL.md +415 -415
- package/skills/problem-solver/SKILL.md +380 -284
- package/skills/rescue/SKILL.md +474 -474
- package/skills/research/SKILL.md +4 -0
- package/skills/retro/SKILL.md +3 -1
- package/skills/review/SKILL.md +614 -588
- package/skills/review-intake/SKILL.md +249 -249
- package/skills/safeguard/SKILL.md +200 -200
- package/skills/sast/SKILL.md +190 -190
- package/skills/scaffold/SKILL.md +328 -287
- package/skills/scope-guard/SKILL.md +183 -180
- package/skills/scout/SKILL.md +269 -263
- package/skills/sentinel/SKILL.md +384 -381
- package/skills/sentinel-env/SKILL.md +254 -254
- package/skills/sequential-thinking/SKILL.md +234 -234
- package/skills/session-bridge/SKILL.md +595 -543
- package/skills/session-bridge/scripts/load-invariants.js +397 -0
- package/skills/skill-forge/SKILL.md +581 -581
- package/skills/skill-router/SKILL.md +3 -0
- package/skills/slides/SKILL.md +19 -0
- package/skills/surgeon/SKILL.md +215 -215
- package/skills/team/SKILL.md +557 -537
- package/skills/test/SKILL.md +620 -614
- package/skills/trend-scout/SKILL.md +145 -145
- package/skills/verification/SKILL.md +334 -326
- package/skills/video-creator/SKILL.md +201 -201
- package/skills/watchdog/SKILL.md +168 -168
- package/skills/worktree/SKILL.md +140 -140
|
@@ -1,425 +1,425 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: mcp-builder
|
|
3
|
-
description: Build Model Context Protocol servers from specifications. Generates tool definitions, resource handlers, and test suites for MCP servers in TypeScript or Python (FastMCP).
|
|
4
|
-
metadata:
|
|
5
|
-
author: runedev
|
|
6
|
-
version: "0.5.0"
|
|
7
|
-
layer: L2
|
|
8
|
-
model: sonnet
|
|
9
|
-
group: creation
|
|
10
|
-
tools: "Read, Write, Edit, Bash, Glob, Grep"
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# mcp-builder
|
|
14
|
-
|
|
15
|
-
## Purpose
|
|
16
|
-
|
|
17
|
-
MCP server builder. Generates complete, tested MCP servers from a natural language description or specification. Handles tool definitions, resource handlers, input validation, error handling, configuration, tests, and documentation. Supports TypeScript (official SDK) and Python (FastMCP).
|
|
18
|
-
|
|
19
|
-
## Triggers
|
|
20
|
-
|
|
21
|
-
- Called by `cook` when MCP-related task detected (keywords: "MCP server", "MCP tool", "model context protocol")
|
|
22
|
-
- Called by `scaffold` when MCP Server template selected
|
|
23
|
-
- `/rune mcp-builder <description>` — manual invocation
|
|
24
|
-
- Auto-trigger: when project contains `mcp.json`, `@modelcontextprotocol/sdk`, or `fastmcp` in dependencies
|
|
25
|
-
|
|
26
|
-
## Calls (outbound)
|
|
27
|
-
|
|
28
|
-
- `ba` (L2): if user description is vague — elicit requirements for what tools/resources the server should expose
|
|
29
|
-
- `research` (L3): look up target API documentation, existing MCP servers for reference
|
|
30
|
-
- `test` (L2): generate and run test suite for the server
|
|
31
|
-
- `docs` (L2): generate server documentation (tool catalog, installation, configuration)
|
|
32
|
-
- `verification` (L3): verify server builds and tests pass
|
|
33
|
-
|
|
34
|
-
## Called By (inbound)
|
|
35
|
-
|
|
36
|
-
- `cook` (L1): when MCP-related task detected
|
|
37
|
-
- `scaffold` (L1): MCP Server template in Phase 5
|
|
38
|
-
- User: `/rune mcp-builder` direct invocation
|
|
39
|
-
|
|
40
|
-
## Executable Steps
|
|
41
|
-
|
|
42
|
-
### Step 1 — Spec Elicitation
|
|
43
|
-
|
|
44
|
-
If description is detailed enough (tools, resources, target API specified), proceed.
|
|
45
|
-
If vague, ask targeted questions:
|
|
46
|
-
|
|
47
|
-
1. **What tools should this MCP server expose?** (actions the AI can perform)
|
|
48
|
-
2. **What resources does it manage?** (data the AI can read)
|
|
49
|
-
3. **What external APIs does it connect to?** (if any)
|
|
50
|
-
4. **TypeScript or Python?** (default: TypeScript with @modelcontextprotocol/sdk)
|
|
51
|
-
5. **Authentication?** (API keys, OAuth, none)
|
|
52
|
-
|
|
53
|
-
If user provides a detailed spec or existing API docs → extract answers, confirm.
|
|
54
|
-
|
|
55
|
-
### Step 2 — Architecture Design
|
|
56
|
-
|
|
57
|
-
<MUST-READ path="references/auto-discovery-pattern.md" trigger="when the server has 5+ tools OR multiple API providers — use auto-discovery registry for graceful degradation"/>
|
|
58
|
-
|
|
59
|
-
Determine server structure based on spec:
|
|
60
|
-
|
|
61
|
-
**TypeScript (default):**
|
|
62
|
-
```
|
|
63
|
-
mcp-server-<name>/
|
|
64
|
-
├── src/
|
|
65
|
-
│ ├── index.ts — server entry point, tool/resource registration
|
|
66
|
-
│ ├── tools/
|
|
67
|
-
│ │ ├── <tool-name>.ts — one file per tool
|
|
68
|
-
│ │ └── index.ts — tool registry
|
|
69
|
-
│ ├── resources/
|
|
70
|
-
│ │ ├── <resource>.ts — one file per resource type
|
|
71
|
-
│ │ └── index.ts — resource registry
|
|
72
|
-
│ ├── lib/
|
|
73
|
-
│ │ ├── client.ts — external API client (if applicable)
|
|
74
|
-
│ │ └── types.ts — shared types
|
|
75
|
-
│ └── config.ts — environment variable validation
|
|
76
|
-
├── tests/
|
|
77
|
-
│ ├── tools/
|
|
78
|
-
│ │ └── <tool-name>.test.ts
|
|
79
|
-
│ └── resources/
|
|
80
|
-
│ └── <resource>.test.ts
|
|
81
|
-
├── package.json
|
|
82
|
-
├── tsconfig.json
|
|
83
|
-
├── .env.example
|
|
84
|
-
└── README.md
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Python (FastMCP):**
|
|
88
|
-
```
|
|
89
|
-
mcp-server-<name>/
|
|
90
|
-
├── src/
|
|
91
|
-
│ ├── server.py — FastMCP server with tool/resource decorators
|
|
92
|
-
│ ├── tools/
|
|
93
|
-
│ │ └── <tool_name>.py
|
|
94
|
-
│ ├── resources/
|
|
95
|
-
│ │ └── <resource>.py
|
|
96
|
-
│ ├── lib/
|
|
97
|
-
│ │ ├── client.py — external API client
|
|
98
|
-
│ │ └── types.py — Pydantic models
|
|
99
|
-
│ └── config.py — settings via pydantic-settings
|
|
100
|
-
├── tests/
|
|
101
|
-
│ ├── test_<tool_name>.py
|
|
102
|
-
│ └── test_<resource>.py
|
|
103
|
-
├── pyproject.toml
|
|
104
|
-
├── .env.example
|
|
105
|
-
└── README.md
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Step 3 — Generate Server Code
|
|
109
|
-
|
|
110
|
-
#### Tool Generation
|
|
111
|
-
|
|
112
|
-
For each tool:
|
|
113
|
-
|
|
114
|
-
**TypeScript:**
|
|
115
|
-
```typescript
|
|
116
|
-
import { z } from 'zod';
|
|
117
|
-
|
|
118
|
-
export const toolName = {
|
|
119
|
-
name: 'tool_name',
|
|
120
|
-
description: 'What this tool does — used by AI to decide when to call it',
|
|
121
|
-
inputSchema: z.object({
|
|
122
|
-
param1: z.string().describe('Description for AI'),
|
|
123
|
-
param2: z.number().optional().describe('Optional parameter'),
|
|
124
|
-
}),
|
|
125
|
-
async handler(input: { param1: string; param2?: number }) {
|
|
126
|
-
// Implementation
|
|
127
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**Python (FastMCP):**
|
|
133
|
-
```python
|
|
134
|
-
from fastmcp import FastMCP
|
|
135
|
-
|
|
136
|
-
mcp = FastMCP("server-name")
|
|
137
|
-
|
|
138
|
-
@mcp.tool()
|
|
139
|
-
async def tool_name(param1: str, param2: int | None = None) -> str:
|
|
140
|
-
"""What this tool does — used by AI to decide when to call it."""
|
|
141
|
-
# Implementation
|
|
142
|
-
return json.dumps(result)
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
#### Resource Generation
|
|
146
|
-
|
|
147
|
-
For each resource:
|
|
148
|
-
- URI template with parameters
|
|
149
|
-
- Read handler that returns structured content
|
|
150
|
-
- List handler for collections
|
|
151
|
-
|
|
152
|
-
#### Configuration
|
|
153
|
-
|
|
154
|
-
Generate `.env.example` with all required environment variables:
|
|
155
|
-
```env
|
|
156
|
-
# Required
|
|
157
|
-
API_KEY=your_api_key_here
|
|
158
|
-
API_BASE_URL=https://api.example.com
|
|
159
|
-
|
|
160
|
-
# Optional
|
|
161
|
-
LOG_LEVEL=info
|
|
162
|
-
CACHE_TTL=300
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
Generate config validation:
|
|
166
|
-
```typescript
|
|
167
|
-
// config.ts
|
|
168
|
-
import { z } from 'zod';
|
|
169
|
-
|
|
170
|
-
const envSchema = z.object({
|
|
171
|
-
API_KEY: z.string().min(1, 'API_KEY is required'),
|
|
172
|
-
API_BASE_URL: z.string().url().default('https://api.example.com'),
|
|
173
|
-
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
export const config = envSchema.parse(process.env);
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Step 3.5 — Tool Safety Classification
|
|
180
|
-
|
|
181
|
-
Before generating tests, classify every tool as `query` or `mutation`:
|
|
182
|
-
|
|
183
|
-
| Category | Examples | Behavior |
|
|
184
|
-
|---|---|---|
|
|
185
|
-
| `query` | read, list, search, get, fetch | Auto-approve — no confirmation needed |
|
|
186
|
-
| `mutation` | create, update, delete, send, write, publish | Require user confirmation before execution |
|
|
187
|
-
|
|
188
|
-
**Implementation rules:**
|
|
189
|
-
|
|
190
|
-
1. Add `safety` metadata to each tool definition:
|
|
191
|
-
```typescript
|
|
192
|
-
export const deleteTool = {
|
|
193
|
-
name: 'delete_user',
|
|
194
|
-
description: '...',
|
|
195
|
-
safety: 'mutation' as const, // ← add this
|
|
196
|
-
inputSchema: z.object({ id: z.string() }),
|
|
197
|
-
async handler(input) { ... },
|
|
198
|
-
};
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
2. For every `mutation` tool, generate a preview step that surfaces WHAT WILL HAPPEN before the action runs:
|
|
202
|
-
```typescript
|
|
203
|
-
// In the handler, before executing:
|
|
204
|
-
if (tool.safety === 'mutation') {
|
|
205
|
-
return {
|
|
206
|
-
content: [{ type: 'text', text:
|
|
207
|
-
`⚠️ Will delete user "${user.name}" (ID: ${input.id}). This cannot be undone.\nConfirm? (yes/no)`
|
|
208
|
-
}],
|
|
209
|
-
requiresConfirmation: true,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
// Proceed only after confirmation received
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
3. For Python (FastMCP), add a `@confirm_mutation` decorator or inline guard in the docstring:
|
|
216
|
-
```python
|
|
217
|
-
@mcp.tool()
|
|
218
|
-
async def delete_user(id: str) -> str:
|
|
219
|
-
"""[MUTATION] Delete a user by ID. Will prompt for confirmation before executing."""
|
|
220
|
-
...
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
4. Document the safety classification in the README tool catalog (add a `🔒` badge on mutation tools).
|
|
224
|
-
|
|
225
|
-
### Step 4 — Generate Tests
|
|
226
|
-
|
|
227
|
-
For each tool:
|
|
228
|
-
- **Happy path**: valid input → expected output
|
|
229
|
-
- **Validation**: invalid input → proper error message
|
|
230
|
-
- **Error handling**: API failure → graceful error response
|
|
231
|
-
- **Edge cases**: empty input, max limits, special characters
|
|
232
|
-
|
|
233
|
-
For each resource:
|
|
234
|
-
- **Read**: valid URI → expected content
|
|
235
|
-
- **Not found**: invalid URI → proper error
|
|
236
|
-
- **List**: collection URI → paginated results
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
describe('tool_name', () => {
|
|
240
|
-
it('should return results for valid input', async () => {
|
|
241
|
-
const result = await toolName.handler({ param1: 'test' });
|
|
242
|
-
expect(result.content[0].type).toBe('text');
|
|
243
|
-
// Assert expected structure
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it('should handle API errors gracefully', async () => {
|
|
247
|
-
// Mock API failure
|
|
248
|
-
const result = await toolName.handler({ param1: 'trigger-error' });
|
|
249
|
-
expect(result.isError).toBe(true);
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Step 5 — Generate Documentation
|
|
255
|
-
|
|
256
|
-
Produce README.md with:
|
|
257
|
-
- Server description and purpose
|
|
258
|
-
- Tool catalog (name, description, parameters, example usage)
|
|
259
|
-
- Resource catalog (URI templates, content types)
|
|
260
|
-
- Installation instructions (npm/pip, Claude Code config, Cursor config)
|
|
261
|
-
- Configuration reference (all env vars with descriptions)
|
|
262
|
-
- Example usage showing AI interactions
|
|
263
|
-
|
|
264
|
-
Claude Code installation snippet:
|
|
265
|
-
```json
|
|
266
|
-
{
|
|
267
|
-
"mcpServers": {
|
|
268
|
-
"server-name": {
|
|
269
|
-
"command": "node",
|
|
270
|
-
"args": ["path/to/dist/index.js"],
|
|
271
|
-
"env": {
|
|
272
|
-
"API_KEY": "your_key"
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Step 6 — Verify
|
|
280
|
-
|
|
281
|
-
Invoke `rune:verification`:
|
|
282
|
-
- TypeScript: `tsc --noEmit` + `npm test`
|
|
283
|
-
- Python: `mypy src/` + `pytest`
|
|
284
|
-
- Ensure all tools respond correctly
|
|
285
|
-
- Ensure configuration validation works
|
|
286
|
-
|
|
287
|
-
## Output Format
|
|
288
|
-
|
|
289
|
-
### Generated Project Structure
|
|
290
|
-
|
|
291
|
-
**TypeScript:**
|
|
292
|
-
```
|
|
293
|
-
mcp-server-<name>/
|
|
294
|
-
├── src/
|
|
295
|
-
│ ├── index.ts — server entry, tool/resource registration
|
|
296
|
-
│ ├── tools/<name>.ts — one file per tool (Zod input schema + handler)
|
|
297
|
-
│ ├── resources/<name>.ts — one file per resource (URI template + reader)
|
|
298
|
-
│ ├── lib/client.ts — external API client
|
|
299
|
-
│ ├── lib/types.ts — shared TypeScript interfaces
|
|
300
|
-
│ └── config.ts — env var validation (Zod schema)
|
|
301
|
-
├── tests/tools/<name>.test.ts — per-tool tests (happy, validation, error, edge)
|
|
302
|
-
├── tests/resources/<name>.test.ts
|
|
303
|
-
├── package.json, tsconfig.json, .env.example, README.md
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
**Python (FastMCP):**
|
|
307
|
-
```
|
|
308
|
-
mcp-server-<name>/
|
|
309
|
-
├── src/
|
|
310
|
-
│ ├── server.py — FastMCP server with @mcp.tool() decorators
|
|
311
|
-
│ ├── tools/<name>.py — tool implementations
|
|
312
|
-
│ ├── resources/<name>.py
|
|
313
|
-
│ ├── lib/client.py — external API client
|
|
314
|
-
│ ├── lib/types.py — Pydantic models
|
|
315
|
-
│ └── config.py — pydantic-settings
|
|
316
|
-
├── tests/test_<name>.py
|
|
317
|
-
├── pyproject.toml, .env.example, README.md
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### README Structure
|
|
321
|
-
- Server description + tool catalog (name, description, params, example)
|
|
322
|
-
- Resource catalog (URI templates, content types)
|
|
323
|
-
- Installation: Claude Code, Cursor, Windsurf config snippets
|
|
324
|
-
- Configuration reference (env vars with descriptions)
|
|
325
|
-
|
|
326
|
-
## Reference Pattern: Multi-Provider Adapter
|
|
327
|
-
|
|
328
|
-
When the MCP server needs to call multiple AI providers (e.g., both Anthropic and OpenAI), use the **Provider Adapter** pattern to normalize different APIs behind a unified interface.
|
|
329
|
-
|
|
330
|
-
### Interface
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
interface ProviderAdapter {
|
|
334
|
-
formatRequest(params: RequestParams): { url: string; init: RequestInit };
|
|
335
|
-
parseResponse(data: unknown): { content: string; usage: TokenUsage | null };
|
|
336
|
-
formatStreamRequest(params: RequestParams): { url: string; init: RequestInit };
|
|
337
|
-
parseSSEEvent(eventType: string, data: string): StreamChunk | null;
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### Discriminated Union for Stream Chunks
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
type StreamChunk =
|
|
345
|
-
| { type: "thinking"; content: string }
|
|
346
|
-
| { type: "text"; content: string }
|
|
347
|
-
| { type: "done" }
|
|
348
|
-
| { type: "done_with_usage"; usage: TokenUsage }
|
|
349
|
-
| { type: "usage_delta"; inputTokens?: number; outputTokens?: number }
|
|
350
|
-
| { type: "error"; message: string };
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### When to Apply
|
|
354
|
-
|
|
355
|
-
- MCP server wraps multiple AI providers (e.g., a router server that dispatches to Claude, GPT, or local models)
|
|
356
|
-
- MCP server aggregates responses from multiple APIs with different response formats
|
|
357
|
-
- MCP server needs to support streaming from providers with different SSE event schemas
|
|
358
|
-
|
|
359
|
-
### Key Implementation Notes
|
|
360
|
-
|
|
361
|
-
- Each provider adapter handles its own SSE event types (Anthropic: `content_block_delta`, `message_start`; OpenAI: `response.output_text.delta`, `[DONE]`)
|
|
362
|
-
- Buffer management for SSE: handle incomplete lines, track event types, manage abort signals
|
|
363
|
-
- Provider-specific prompt tuning: some models benefit from additional constraints (e.g., "Maximum 2-3 paragraphs" for verbose models)
|
|
364
|
-
- Per-provider token tracking: normalize different usage reporting formats into a single `TokenUsage` type
|
|
365
|
-
|
|
366
|
-
### Cost-Aware Model Selection
|
|
367
|
-
|
|
368
|
-
When building MCP servers that call AI providers, support **dual-model configuration** — allow users to specify a primary model for critical operations and a cheaper model for background tasks (summarization, classification, metadata extraction). This avoids burning expensive API credits on tasks that don't need maximum quality.
|
|
369
|
-
|
|
370
|
-
```typescript
|
|
371
|
-
// config.ts
|
|
372
|
-
const config = {
|
|
373
|
-
primaryModel: process.env.PRIMARY_MODEL || 'claude-sonnet-4-20250514',
|
|
374
|
-
backgroundModel: process.env.BACKGROUND_MODEL || 'claude-haiku-4-5-20251001',
|
|
375
|
-
};
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
## Constraints
|
|
379
|
-
|
|
380
|
-
1. MUST validate all tool inputs with Zod (TS) or Pydantic (Python) — never trust AI-provided inputs
|
|
381
|
-
2. MUST handle API errors gracefully — return MCP error responses, don't crash the server
|
|
382
|
-
3. MUST generate .env.example — never hardcode API keys or secrets
|
|
383
|
-
4. MUST generate tests — no MCP server without test suite
|
|
384
|
-
5. MUST generate installation docs for at least Claude Code — other IDEs are bonus
|
|
385
|
-
6. MUST use official MCP SDK (@modelcontextprotocol/sdk for TS, fastmcp for Python)
|
|
386
|
-
7. Tool descriptions MUST be AI-friendly — clear, specific, include parameter semantics
|
|
387
|
-
|
|
388
|
-
## Sharp Edges
|
|
389
|
-
|
|
390
|
-
| Failure Mode | Severity | Mitigation |
|
|
391
|
-
|---|---|---|
|
|
392
|
-
| Tool descriptions too vague for AI to use effectively | HIGH | Step 3: descriptions must explain WHEN to use the tool, not just WHAT it does |
|
|
393
|
-
| Missing input validation → server crashes on bad input | HIGH | Constraint 1: Zod/Pydantic validation on all inputs |
|
|
394
|
-
| Hardcoded API keys in generated code | CRITICAL | Constraint 3: always use env vars + .env.example |
|
|
395
|
-
| Tests mock everything → no real integration coverage | MEDIUM | Generate both unit tests (mocked) and integration test template (real API) |
|
|
396
|
-
| Generated server doesn't match MCP spec | HIGH | Use official SDK — don't hand-roll protocol handling |
|
|
397
|
-
| Installation docs only for Claude Code | LOW | Include Cursor/Windsurf config examples too |
|
|
398
|
-
| Mutation tool without confirmation gate | CRITICAL | Step 3.5: classify every tool — any write/delete/send without a preview+confirm step is a footgun |
|
|
399
|
-
|
|
400
|
-
## Done When
|
|
401
|
-
|
|
402
|
-
- Server specification elicited (tools, resources, target API, language)
|
|
403
|
-
- Architecture designed (file structure, module boundaries)
|
|
404
|
-
- Server code generated (tools, resources, config, types)
|
|
405
|
-
- Test suite generated (happy path, validation, errors, edge cases)
|
|
406
|
-
- Documentation generated (README with tool catalog, installation, config)
|
|
407
|
-
- Verification passed (types + tests)
|
|
408
|
-
- Ready to install in Claude Code / Cursor / other IDEs
|
|
409
|
-
|
|
410
|
-
## Returns
|
|
411
|
-
|
|
412
|
-
| Artifact | Format | Location |
|
|
413
|
-
|----------|--------|----------|
|
|
414
|
-
| MCP server source code | TypeScript or Python | `mcp-server-<name>/src/` |
|
|
415
|
-
| Tool definitions (one per tool) | TS/Python files | `src/tools/<name>.ts` or `.py` |
|
|
416
|
-
| Resource handlers | TS/Python files | `src/resources/<name>.ts` or `.py` |
|
|
417
|
-
| Test suite | TS/Python test files | `tests/` |
|
|
418
|
-
| README with tool catalog | Markdown | `mcp-server-<name>/README.md` |
|
|
419
|
-
| Environment config template | `.env.example` | project root |
|
|
420
|
-
|
|
421
|
-
## Cost Profile
|
|
422
|
-
|
|
423
|
-
~3000-6000 tokens input, ~2000-5000 tokens output. Sonnet — MCP server generation is a structured code task, not architectural reasoning.
|
|
424
|
-
|
|
425
|
-
**Scope guardrail:** mcp-builder generates the server and tests — it does not deploy, register with MCP registries, or configure the host IDE beyond providing the installation snippet.
|
|
1
|
+
---
|
|
2
|
+
name: mcp-builder
|
|
3
|
+
description: Build Model Context Protocol servers from specifications. Generates tool definitions, resource handlers, and test suites for MCP servers in TypeScript or Python (FastMCP).
|
|
4
|
+
metadata:
|
|
5
|
+
author: runedev
|
|
6
|
+
version: "0.5.0"
|
|
7
|
+
layer: L2
|
|
8
|
+
model: sonnet
|
|
9
|
+
group: creation
|
|
10
|
+
tools: "Read, Write, Edit, Bash, Glob, Grep"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# mcp-builder
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
MCP server builder. Generates complete, tested MCP servers from a natural language description or specification. Handles tool definitions, resource handlers, input validation, error handling, configuration, tests, and documentation. Supports TypeScript (official SDK) and Python (FastMCP).
|
|
18
|
+
|
|
19
|
+
## Triggers
|
|
20
|
+
|
|
21
|
+
- Called by `cook` when MCP-related task detected (keywords: "MCP server", "MCP tool", "model context protocol")
|
|
22
|
+
- Called by `scaffold` when MCP Server template selected
|
|
23
|
+
- `/rune mcp-builder <description>` — manual invocation
|
|
24
|
+
- Auto-trigger: when project contains `mcp.json`, `@modelcontextprotocol/sdk`, or `fastmcp` in dependencies
|
|
25
|
+
|
|
26
|
+
## Calls (outbound)
|
|
27
|
+
|
|
28
|
+
- `ba` (L2): if user description is vague — elicit requirements for what tools/resources the server should expose
|
|
29
|
+
- `research` (L3): look up target API documentation, existing MCP servers for reference
|
|
30
|
+
- `test` (L2): generate and run test suite for the server
|
|
31
|
+
- `docs` (L2): generate server documentation (tool catalog, installation, configuration)
|
|
32
|
+
- `verification` (L3): verify server builds and tests pass
|
|
33
|
+
|
|
34
|
+
## Called By (inbound)
|
|
35
|
+
|
|
36
|
+
- `cook` (L1): when MCP-related task detected
|
|
37
|
+
- `scaffold` (L1): MCP Server template in Phase 5
|
|
38
|
+
- User: `/rune mcp-builder` direct invocation
|
|
39
|
+
|
|
40
|
+
## Executable Steps
|
|
41
|
+
|
|
42
|
+
### Step 1 — Spec Elicitation
|
|
43
|
+
|
|
44
|
+
If description is detailed enough (tools, resources, target API specified), proceed.
|
|
45
|
+
If vague, ask targeted questions:
|
|
46
|
+
|
|
47
|
+
1. **What tools should this MCP server expose?** (actions the AI can perform)
|
|
48
|
+
2. **What resources does it manage?** (data the AI can read)
|
|
49
|
+
3. **What external APIs does it connect to?** (if any)
|
|
50
|
+
4. **TypeScript or Python?** (default: TypeScript with @modelcontextprotocol/sdk)
|
|
51
|
+
5. **Authentication?** (API keys, OAuth, none)
|
|
52
|
+
|
|
53
|
+
If user provides a detailed spec or existing API docs → extract answers, confirm.
|
|
54
|
+
|
|
55
|
+
### Step 2 — Architecture Design
|
|
56
|
+
|
|
57
|
+
<MUST-READ path="references/auto-discovery-pattern.md" trigger="when the server has 5+ tools OR multiple API providers — use auto-discovery registry for graceful degradation"/>
|
|
58
|
+
|
|
59
|
+
Determine server structure based on spec:
|
|
60
|
+
|
|
61
|
+
**TypeScript (default):**
|
|
62
|
+
```
|
|
63
|
+
mcp-server-<name>/
|
|
64
|
+
├── src/
|
|
65
|
+
│ ├── index.ts — server entry point, tool/resource registration
|
|
66
|
+
│ ├── tools/
|
|
67
|
+
│ │ ├── <tool-name>.ts — one file per tool
|
|
68
|
+
│ │ └── index.ts — tool registry
|
|
69
|
+
│ ├── resources/
|
|
70
|
+
│ │ ├── <resource>.ts — one file per resource type
|
|
71
|
+
│ │ └── index.ts — resource registry
|
|
72
|
+
│ ├── lib/
|
|
73
|
+
│ │ ├── client.ts — external API client (if applicable)
|
|
74
|
+
│ │ └── types.ts — shared types
|
|
75
|
+
│ └── config.ts — environment variable validation
|
|
76
|
+
├── tests/
|
|
77
|
+
│ ├── tools/
|
|
78
|
+
│ │ └── <tool-name>.test.ts
|
|
79
|
+
│ └── resources/
|
|
80
|
+
│ └── <resource>.test.ts
|
|
81
|
+
├── package.json
|
|
82
|
+
├── tsconfig.json
|
|
83
|
+
├── .env.example
|
|
84
|
+
└── README.md
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Python (FastMCP):**
|
|
88
|
+
```
|
|
89
|
+
mcp-server-<name>/
|
|
90
|
+
├── src/
|
|
91
|
+
│ ├── server.py — FastMCP server with tool/resource decorators
|
|
92
|
+
│ ├── tools/
|
|
93
|
+
│ │ └── <tool_name>.py
|
|
94
|
+
│ ├── resources/
|
|
95
|
+
│ │ └── <resource>.py
|
|
96
|
+
│ ├── lib/
|
|
97
|
+
│ │ ├── client.py — external API client
|
|
98
|
+
│ │ └── types.py — Pydantic models
|
|
99
|
+
│ └── config.py — settings via pydantic-settings
|
|
100
|
+
├── tests/
|
|
101
|
+
│ ├── test_<tool_name>.py
|
|
102
|
+
│ └── test_<resource>.py
|
|
103
|
+
├── pyproject.toml
|
|
104
|
+
├── .env.example
|
|
105
|
+
└── README.md
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Step 3 — Generate Server Code
|
|
109
|
+
|
|
110
|
+
#### Tool Generation
|
|
111
|
+
|
|
112
|
+
For each tool:
|
|
113
|
+
|
|
114
|
+
**TypeScript:**
|
|
115
|
+
```typescript
|
|
116
|
+
import { z } from 'zod';
|
|
117
|
+
|
|
118
|
+
export const toolName = {
|
|
119
|
+
name: 'tool_name',
|
|
120
|
+
description: 'What this tool does — used by AI to decide when to call it',
|
|
121
|
+
inputSchema: z.object({
|
|
122
|
+
param1: z.string().describe('Description for AI'),
|
|
123
|
+
param2: z.number().optional().describe('Optional parameter'),
|
|
124
|
+
}),
|
|
125
|
+
async handler(input: { param1: string; param2?: number }) {
|
|
126
|
+
// Implementation
|
|
127
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Python (FastMCP):**
|
|
133
|
+
```python
|
|
134
|
+
from fastmcp import FastMCP
|
|
135
|
+
|
|
136
|
+
mcp = FastMCP("server-name")
|
|
137
|
+
|
|
138
|
+
@mcp.tool()
|
|
139
|
+
async def tool_name(param1: str, param2: int | None = None) -> str:
|
|
140
|
+
"""What this tool does — used by AI to decide when to call it."""
|
|
141
|
+
# Implementation
|
|
142
|
+
return json.dumps(result)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Resource Generation
|
|
146
|
+
|
|
147
|
+
For each resource:
|
|
148
|
+
- URI template with parameters
|
|
149
|
+
- Read handler that returns structured content
|
|
150
|
+
- List handler for collections
|
|
151
|
+
|
|
152
|
+
#### Configuration
|
|
153
|
+
|
|
154
|
+
Generate `.env.example` with all required environment variables:
|
|
155
|
+
```env
|
|
156
|
+
# Required
|
|
157
|
+
API_KEY=your_api_key_here
|
|
158
|
+
API_BASE_URL=https://api.example.com
|
|
159
|
+
|
|
160
|
+
# Optional
|
|
161
|
+
LOG_LEVEL=info
|
|
162
|
+
CACHE_TTL=300
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Generate config validation:
|
|
166
|
+
```typescript
|
|
167
|
+
// config.ts
|
|
168
|
+
import { z } from 'zod';
|
|
169
|
+
|
|
170
|
+
const envSchema = z.object({
|
|
171
|
+
API_KEY: z.string().min(1, 'API_KEY is required'),
|
|
172
|
+
API_BASE_URL: z.string().url().default('https://api.example.com'),
|
|
173
|
+
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
export const config = envSchema.parse(process.env);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Step 3.5 — Tool Safety Classification
|
|
180
|
+
|
|
181
|
+
Before generating tests, classify every tool as `query` or `mutation`:
|
|
182
|
+
|
|
183
|
+
| Category | Examples | Behavior |
|
|
184
|
+
|---|---|---|
|
|
185
|
+
| `query` | read, list, search, get, fetch | Auto-approve — no confirmation needed |
|
|
186
|
+
| `mutation` | create, update, delete, send, write, publish | Require user confirmation before execution |
|
|
187
|
+
|
|
188
|
+
**Implementation rules:**
|
|
189
|
+
|
|
190
|
+
1. Add `safety` metadata to each tool definition:
|
|
191
|
+
```typescript
|
|
192
|
+
export const deleteTool = {
|
|
193
|
+
name: 'delete_user',
|
|
194
|
+
description: '...',
|
|
195
|
+
safety: 'mutation' as const, // ← add this
|
|
196
|
+
inputSchema: z.object({ id: z.string() }),
|
|
197
|
+
async handler(input) { ... },
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
2. For every `mutation` tool, generate a preview step that surfaces WHAT WILL HAPPEN before the action runs:
|
|
202
|
+
```typescript
|
|
203
|
+
// In the handler, before executing:
|
|
204
|
+
if (tool.safety === 'mutation') {
|
|
205
|
+
return {
|
|
206
|
+
content: [{ type: 'text', text:
|
|
207
|
+
`⚠️ Will delete user "${user.name}" (ID: ${input.id}). This cannot be undone.\nConfirm? (yes/no)`
|
|
208
|
+
}],
|
|
209
|
+
requiresConfirmation: true,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
// Proceed only after confirmation received
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
3. For Python (FastMCP), add a `@confirm_mutation` decorator or inline guard in the docstring:
|
|
216
|
+
```python
|
|
217
|
+
@mcp.tool()
|
|
218
|
+
async def delete_user(id: str) -> str:
|
|
219
|
+
"""[MUTATION] Delete a user by ID. Will prompt for confirmation before executing."""
|
|
220
|
+
...
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
4. Document the safety classification in the README tool catalog (add a `🔒` badge on mutation tools).
|
|
224
|
+
|
|
225
|
+
### Step 4 — Generate Tests
|
|
226
|
+
|
|
227
|
+
For each tool:
|
|
228
|
+
- **Happy path**: valid input → expected output
|
|
229
|
+
- **Validation**: invalid input → proper error message
|
|
230
|
+
- **Error handling**: API failure → graceful error response
|
|
231
|
+
- **Edge cases**: empty input, max limits, special characters
|
|
232
|
+
|
|
233
|
+
For each resource:
|
|
234
|
+
- **Read**: valid URI → expected content
|
|
235
|
+
- **Not found**: invalid URI → proper error
|
|
236
|
+
- **List**: collection URI → paginated results
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
describe('tool_name', () => {
|
|
240
|
+
it('should return results for valid input', async () => {
|
|
241
|
+
const result = await toolName.handler({ param1: 'test' });
|
|
242
|
+
expect(result.content[0].type).toBe('text');
|
|
243
|
+
// Assert expected structure
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should handle API errors gracefully', async () => {
|
|
247
|
+
// Mock API failure
|
|
248
|
+
const result = await toolName.handler({ param1: 'trigger-error' });
|
|
249
|
+
expect(result.isError).toBe(true);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Step 5 — Generate Documentation
|
|
255
|
+
|
|
256
|
+
Produce README.md with:
|
|
257
|
+
- Server description and purpose
|
|
258
|
+
- Tool catalog (name, description, parameters, example usage)
|
|
259
|
+
- Resource catalog (URI templates, content types)
|
|
260
|
+
- Installation instructions (npm/pip, Claude Code config, Cursor config)
|
|
261
|
+
- Configuration reference (all env vars with descriptions)
|
|
262
|
+
- Example usage showing AI interactions
|
|
263
|
+
|
|
264
|
+
Claude Code installation snippet:
|
|
265
|
+
```json
|
|
266
|
+
{
|
|
267
|
+
"mcpServers": {
|
|
268
|
+
"server-name": {
|
|
269
|
+
"command": "node",
|
|
270
|
+
"args": ["path/to/dist/index.js"],
|
|
271
|
+
"env": {
|
|
272
|
+
"API_KEY": "your_key"
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Step 6 — Verify
|
|
280
|
+
|
|
281
|
+
Invoke `rune:verification`:
|
|
282
|
+
- TypeScript: `tsc --noEmit` + `npm test`
|
|
283
|
+
- Python: `mypy src/` + `pytest`
|
|
284
|
+
- Ensure all tools respond correctly
|
|
285
|
+
- Ensure configuration validation works
|
|
286
|
+
|
|
287
|
+
## Output Format
|
|
288
|
+
|
|
289
|
+
### Generated Project Structure
|
|
290
|
+
|
|
291
|
+
**TypeScript:**
|
|
292
|
+
```
|
|
293
|
+
mcp-server-<name>/
|
|
294
|
+
├── src/
|
|
295
|
+
│ ├── index.ts — server entry, tool/resource registration
|
|
296
|
+
│ ├── tools/<name>.ts — one file per tool (Zod input schema + handler)
|
|
297
|
+
│ ├── resources/<name>.ts — one file per resource (URI template + reader)
|
|
298
|
+
│ ├── lib/client.ts — external API client
|
|
299
|
+
│ ├── lib/types.ts — shared TypeScript interfaces
|
|
300
|
+
│ └── config.ts — env var validation (Zod schema)
|
|
301
|
+
├── tests/tools/<name>.test.ts — per-tool tests (happy, validation, error, edge)
|
|
302
|
+
├── tests/resources/<name>.test.ts
|
|
303
|
+
├── package.json, tsconfig.json, .env.example, README.md
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Python (FastMCP):**
|
|
307
|
+
```
|
|
308
|
+
mcp-server-<name>/
|
|
309
|
+
├── src/
|
|
310
|
+
│ ├── server.py — FastMCP server with @mcp.tool() decorators
|
|
311
|
+
│ ├── tools/<name>.py — tool implementations
|
|
312
|
+
│ ├── resources/<name>.py
|
|
313
|
+
│ ├── lib/client.py — external API client
|
|
314
|
+
│ ├── lib/types.py — Pydantic models
|
|
315
|
+
│ └── config.py — pydantic-settings
|
|
316
|
+
├── tests/test_<name>.py
|
|
317
|
+
├── pyproject.toml, .env.example, README.md
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### README Structure
|
|
321
|
+
- Server description + tool catalog (name, description, params, example)
|
|
322
|
+
- Resource catalog (URI templates, content types)
|
|
323
|
+
- Installation: Claude Code, Cursor, Windsurf config snippets
|
|
324
|
+
- Configuration reference (env vars with descriptions)
|
|
325
|
+
|
|
326
|
+
## Reference Pattern: Multi-Provider Adapter
|
|
327
|
+
|
|
328
|
+
When the MCP server needs to call multiple AI providers (e.g., both Anthropic and OpenAI), use the **Provider Adapter** pattern to normalize different APIs behind a unified interface.
|
|
329
|
+
|
|
330
|
+
### Interface
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
interface ProviderAdapter {
|
|
334
|
+
formatRequest(params: RequestParams): { url: string; init: RequestInit };
|
|
335
|
+
parseResponse(data: unknown): { content: string; usage: TokenUsage | null };
|
|
336
|
+
formatStreamRequest(params: RequestParams): { url: string; init: RequestInit };
|
|
337
|
+
parseSSEEvent(eventType: string, data: string): StreamChunk | null;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Discriminated Union for Stream Chunks
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
type StreamChunk =
|
|
345
|
+
| { type: "thinking"; content: string }
|
|
346
|
+
| { type: "text"; content: string }
|
|
347
|
+
| { type: "done" }
|
|
348
|
+
| { type: "done_with_usage"; usage: TokenUsage }
|
|
349
|
+
| { type: "usage_delta"; inputTokens?: number; outputTokens?: number }
|
|
350
|
+
| { type: "error"; message: string };
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### When to Apply
|
|
354
|
+
|
|
355
|
+
- MCP server wraps multiple AI providers (e.g., a router server that dispatches to Claude, GPT, or local models)
|
|
356
|
+
- MCP server aggregates responses from multiple APIs with different response formats
|
|
357
|
+
- MCP server needs to support streaming from providers with different SSE event schemas
|
|
358
|
+
|
|
359
|
+
### Key Implementation Notes
|
|
360
|
+
|
|
361
|
+
- Each provider adapter handles its own SSE event types (Anthropic: `content_block_delta`, `message_start`; OpenAI: `response.output_text.delta`, `[DONE]`)
|
|
362
|
+
- Buffer management for SSE: handle incomplete lines, track event types, manage abort signals
|
|
363
|
+
- Provider-specific prompt tuning: some models benefit from additional constraints (e.g., "Maximum 2-3 paragraphs" for verbose models)
|
|
364
|
+
- Per-provider token tracking: normalize different usage reporting formats into a single `TokenUsage` type
|
|
365
|
+
|
|
366
|
+
### Cost-Aware Model Selection
|
|
367
|
+
|
|
368
|
+
When building MCP servers that call AI providers, support **dual-model configuration** — allow users to specify a primary model for critical operations and a cheaper model for background tasks (summarization, classification, metadata extraction). This avoids burning expensive API credits on tasks that don't need maximum quality.
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// config.ts
|
|
372
|
+
const config = {
|
|
373
|
+
primaryModel: process.env.PRIMARY_MODEL || 'claude-sonnet-4-20250514',
|
|
374
|
+
backgroundModel: process.env.BACKGROUND_MODEL || 'claude-haiku-4-5-20251001',
|
|
375
|
+
};
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Constraints
|
|
379
|
+
|
|
380
|
+
1. MUST validate all tool inputs with Zod (TS) or Pydantic (Python) — never trust AI-provided inputs
|
|
381
|
+
2. MUST handle API errors gracefully — return MCP error responses, don't crash the server
|
|
382
|
+
3. MUST generate .env.example — never hardcode API keys or secrets
|
|
383
|
+
4. MUST generate tests — no MCP server without test suite
|
|
384
|
+
5. MUST generate installation docs for at least Claude Code — other IDEs are bonus
|
|
385
|
+
6. MUST use official MCP SDK (@modelcontextprotocol/sdk for TS, fastmcp for Python)
|
|
386
|
+
7. Tool descriptions MUST be AI-friendly — clear, specific, include parameter semantics
|
|
387
|
+
|
|
388
|
+
## Sharp Edges
|
|
389
|
+
|
|
390
|
+
| Failure Mode | Severity | Mitigation |
|
|
391
|
+
|---|---|---|
|
|
392
|
+
| Tool descriptions too vague for AI to use effectively | HIGH | Step 3: descriptions must explain WHEN to use the tool, not just WHAT it does |
|
|
393
|
+
| Missing input validation → server crashes on bad input | HIGH | Constraint 1: Zod/Pydantic validation on all inputs |
|
|
394
|
+
| Hardcoded API keys in generated code | CRITICAL | Constraint 3: always use env vars + .env.example |
|
|
395
|
+
| Tests mock everything → no real integration coverage | MEDIUM | Generate both unit tests (mocked) and integration test template (real API) |
|
|
396
|
+
| Generated server doesn't match MCP spec | HIGH | Use official SDK — don't hand-roll protocol handling |
|
|
397
|
+
| Installation docs only for Claude Code | LOW | Include Cursor/Windsurf config examples too |
|
|
398
|
+
| Mutation tool without confirmation gate | CRITICAL | Step 3.5: classify every tool — any write/delete/send without a preview+confirm step is a footgun |
|
|
399
|
+
|
|
400
|
+
## Done When
|
|
401
|
+
|
|
402
|
+
- Server specification elicited (tools, resources, target API, language)
|
|
403
|
+
- Architecture designed (file structure, module boundaries)
|
|
404
|
+
- Server code generated (tools, resources, config, types)
|
|
405
|
+
- Test suite generated (happy path, validation, errors, edge cases)
|
|
406
|
+
- Documentation generated (README with tool catalog, installation, config)
|
|
407
|
+
- Verification passed (types + tests)
|
|
408
|
+
- Ready to install in Claude Code / Cursor / other IDEs
|
|
409
|
+
|
|
410
|
+
## Returns
|
|
411
|
+
|
|
412
|
+
| Artifact | Format | Location |
|
|
413
|
+
|----------|--------|----------|
|
|
414
|
+
| MCP server source code | TypeScript or Python | `mcp-server-<name>/src/` |
|
|
415
|
+
| Tool definitions (one per tool) | TS/Python files | `src/tools/<name>.ts` or `.py` |
|
|
416
|
+
| Resource handlers | TS/Python files | `src/resources/<name>.ts` or `.py` |
|
|
417
|
+
| Test suite | TS/Python test files | `tests/` |
|
|
418
|
+
| README with tool catalog | Markdown | `mcp-server-<name>/README.md` |
|
|
419
|
+
| Environment config template | `.env.example` | project root |
|
|
420
|
+
|
|
421
|
+
## Cost Profile
|
|
422
|
+
|
|
423
|
+
~3000-6000 tokens input, ~2000-5000 tokens output. Sonnet — MCP server generation is a structured code task, not architectural reasoning.
|
|
424
|
+
|
|
425
|
+
**Scope guardrail:** mcp-builder generates the server and tests — it does not deploy, register with MCP registries, or configure the host IDE beyond providing the installation snippet.
|