AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Mcp Builder

skill-rune-kit-rune-mcp-builder · by Rune-kit

Build Model Context Protocol servers from specifications. Use when creating an MCP server for a tool, resource, or service that AI agents should access. Generates tool definitions, resource handlers, and test suites in TypeScript or Python (FastMCP).

— No reviews yet
0 installs
45 views
0.0% view→install

Install

$ agentstack add skill-rune-kit-rune-mcp-builder

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-rune-kit-rune-mcp-builder)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Builder? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mcp-builder

Purpose

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).

Triggers

  • Called by cook when MCP-related task detected (keywords: "MCP server", "MCP tool", "model context protocol")
  • Called by scaffold when MCP Server template selected
  • /rune mcp-builder — manual invocation
  • Auto-trigger: when project contains mcp.json, @modelcontextprotocol/sdk, or fastmcp in dependencies

Calls (outbound)

  • ba (L2): if user description is vague — elicit requirements for what tools/resources the server should expose
  • research (L3): look up target API documentation, existing MCP servers for reference
  • test (L2): generate and run test suite for the server
  • docs (L2): generate server documentation (tool catalog, installation, configuration)
  • verification (L3): verify server builds and tests pass

Called By (inbound)

  • cook (L1): when MCP-related task detected
  • scaffold (L1): MCP Server template in Phase 5
  • User: /rune mcp-builder direct invocation

Executable Steps

Step 1 — Spec Elicitation

If description is detailed enough (tools, resources, target API specified), proceed. If vague, ask targeted questions:

  1. What tools should this MCP server expose? (actions the AI can perform)
  2. What resources does it manage? (data the AI can read)
  3. What external APIs does it connect to? (if any)
  4. TypeScript or Python? (default: TypeScript with @modelcontextprotocol/sdk)
  5. Authentication? (API keys, OAuth, none)

If user provides a detailed spec or existing API docs → extract answers, confirm.

Step 2 — Architecture Design

Determine server structure based on spec:

TypeScript (default):

mcp-server-/
├── src/
│   ├── index.ts          — server entry point, tool/resource registration
│   ├── tools/
│   │   ├── .ts — one file per tool
│   │   └── index.ts       — tool registry
│   ├── resources/
│   │   ├── .ts  — one file per resource type
│   │   └── index.ts       — resource registry
│   ├── lib/
│   │   ├── client.ts      — external API client (if applicable)
│   │   └── types.ts       — shared types
│   └── config.ts          — environment variable validation
├── tests/
│   ├── tools/
│   │   └── .test.ts
│   └── resources/
│       └── .test.ts
├── package.json
├── tsconfig.json
├── .env.example
└── README.md

Python (FastMCP):

mcp-server-/
├── src/
│   ├── server.py          — FastMCP server with tool/resource decorators
│   ├── tools/
│   │   └── .py
│   ├── resources/
│   │   └── .py
│   ├── lib/
│   │   ├── client.py      — external API client
│   │   └── types.py       — Pydantic models
│   └── config.py          — settings via pydantic-settings
├── tests/
│   ├── test_.py
│   └── test_.py
├── pyproject.toml
├── .env.example
└── README.md

Step 3 — Generate Server Code

Tool Generation

For each tool:

TypeScript:

import { z } from 'zod';

export const toolName = {
  name: 'tool_name',
  description: 'What this tool does — used by AI to decide when to call it',
  inputSchema: z.object({
    param1: z.string().describe('Description for AI'),
    param2: z.number().optional().describe('Optional parameter'),
  }),
  async handler(input: { param1: string; param2?: number }) {
    // Implementation
    return { content: [{ type: 'text', text: JSON.stringify(result) }] };
  },
};

Python (FastMCP):

from fastmcp import FastMCP

mcp = FastMCP("server-name")

@mcp.tool()
async def tool_name(param1: str, param2: int | None = None) -> str:
    """What this tool does — used by AI to decide when to call it."""
    # Implementation
    return json.dumps(result)
Resource Generation

For each resource:

  • URI template with parameters
  • Read handler that returns structured content
  • List handler for collections
Configuration

Generate .env.example with all required environment variables:

# Required
API_KEY=your_api_key_here
API_BASE_URL=https://api.example.com

# Optional
LOG_LEVEL=info
CACHE_TTL=300

Generate config validation:

// config.ts
import { z } from 'zod';

const envSchema = z.object({
  API_KEY: z.string().min(1, 'API_KEY is required'),
  API_BASE_URL: z.string().url().default('https://api.example.com'),
  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
});

export const config = envSchema.parse(process.env);

Step 3.5 — Tool Safety Classification

Before generating tests, classify every tool as query or mutation:

| Category | Examples | Behavior | |---|---|---| | query | read, list, search, get, fetch | Auto-approve — no confirmation needed | | mutation | create, update, delete, send, write, publish | Require user confirmation before execution |

Implementation rules:

  1. Add safety metadata to each tool definition:
export const deleteTool = {
  name: 'delete_user',
  description: '...',
  safety: 'mutation' as const,   // ← add this
  inputSchema: z.object({ id: z.string() }),
  async handler(input) { ... },
};
  1. For every mutation tool, generate a preview step that surfaces WHAT WILL HAPPEN before the action runs:
// In the handler, before executing:
if (tool.safety === 'mutation') {
  return {
    content: [{ type: 'text', text:
      `⚠️ Will delete user "${user.name}" (ID: ${input.id}). This cannot be undone.\nConfirm? (yes/no)`
    }],
    requiresConfirmation: true,
  };
}
// Proceed only after confirmation received
  1. For Python (FastMCP), add a @confirm_mutation decorator or inline guard in the docstring:
@mcp.tool()
async def delete_user(id: str) -> str:
    """[MUTATION] Delete a user by ID. Will prompt for confirmation before executing."""
    ...
  1. Document the safety classification in the README tool catalog (add a 🔒 badge on mutation tools).

Step 4 — Generate Tests

For each tool:

  • Happy path: valid input → expected output
  • Validation: invalid input → proper error message
  • Error handling: API failure → graceful error response
  • Edge cases: empty input, max limits, special characters

For each resource:

  • Read: valid URI → expected content
  • Not found: invalid URI → proper error
  • List: collection URI → paginated results
describe('tool_name', () => {
  it('should return results for valid input', async () => {
    const result = await toolName.handler({ param1: 'test' });
    expect(result.content[0].type).toBe('text');
    // Assert expected structure
  });

  it('should handle API errors gracefully', async () => {
    // Mock API failure
    const result = await toolName.handler({ param1: 'trigger-error' });
    expect(result.isError).toBe(true);
  });
});

Step 5 — Generate Documentation

Produce README.md with:

  • Server description and purpose
  • Tool catalog (name, description, parameters, example usage)
  • Resource catalog (URI templates, content types)
  • Installation instructions (npm/pip, Claude Code config, Cursor config)
  • Configuration reference (all env vars with descriptions)
  • Example usage showing AI interactions

Claude Code installation snippet:

{
  "mcpServers": {
    "server-name": {
      "command": "node",
      "args": ["path/to/dist/index.js"],
      "env": {
        "API_KEY": "your_key"
      }
    }
  }
}

Step 6 — Verify

Invoke rune:verification:

  • TypeScript: tsc --noEmit + npm test
  • Python: mypy src/ + pytest
  • Ensure all tools respond correctly
  • Ensure configuration validation works

Output Format

Generated Project Structure

TypeScript:

mcp-server-/
├── src/
│   ├── index.ts          — server entry, tool/resource registration
│   ├── tools/.ts   — one file per tool (Zod input schema + handler)
│   ├── resources/.ts — one file per resource (URI template + reader)
│   ├── lib/client.ts     — external API client
│   ├── lib/types.ts      — shared TypeScript interfaces
│   └── config.ts         — env var validation (Zod schema)
├── tests/tools/.test.ts — per-tool tests (happy, validation, error, edge)
├── tests/resources/.test.ts
├── package.json, tsconfig.json, .env.example, README.md

Python (FastMCP):

mcp-server-/
├── src/
│   ├── server.py         — FastMCP server with @mcp.tool() decorators
│   ├── tools/.py   — tool implementations
│   ├── resources/.py
│   ├── lib/client.py     — external API client
│   ├── lib/types.py      — Pydantic models
│   └── config.py         — pydantic-settings
├── tests/test_.py
├── pyproject.toml, .env.example, README.md

README Structure

  • Server description + tool catalog (name, description, params, example)
  • Resource catalog (URI templates, content types)
  • Installation: Claude Code, Cursor, Windsurf config snippets
  • Configuration reference (env vars with descriptions)

Reference Pattern: Multi-Provider Adapter

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.

Interface

interface ProviderAdapter {
  formatRequest(params: RequestParams): { url: string; init: RequestInit };
  parseResponse(data: unknown): { content: string; usage: TokenUsage | null };
  formatStreamRequest(params: RequestParams): { url: string; init: RequestInit };
  parseSSEEvent(eventType: string, data: string): StreamChunk | null;
}

Discriminated Union for Stream Chunks

type StreamChunk =
  | { type: "thinking"; content: string }
  | { type: "text"; content: string }
  | { type: "done" }
  | { type: "done_with_usage"; usage: TokenUsage }
  | { type: "usage_delta"; inputTokens?: number; outputTokens?: number }
  | { type: "error"; message: string };

When to Apply

  • MCP server wraps multiple AI providers (e.g., a router server that dispatches to Claude, GPT, or local models)
  • MCP server aggregates responses from multiple APIs with different response formats
  • MCP server needs to support streaming from providers with different SSE event schemas

Key Implementation Notes

  • Each provider adapter handles its own SSE event types (Anthropic: content_block_delta, message_start; OpenAI: response.output_text.delta, [DONE])
  • Buffer management for SSE: handle incomplete lines, track event types, manage abort signals
  • Provider-specific prompt tuning: some models benefit from additional constraints (e.g., "Maximum 2-3 paragraphs" for verbose models)
  • Per-provider token tracking: normalize different usage reporting formats into a single TokenUsage type

Cost-Aware Model Selection

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.

// config.ts
const config = {
  primaryModel: process.env.PRIMARY_MODEL || 'claude-sonnet-4-20250514',
  backgroundModel: process.env.BACKGROUND_MODEL || 'claude-haiku-4-5-20251001',
};

Constraints

  1. MUST validate all tool inputs with Zod (TS) or Pydantic (Python) — never trust AI-provided inputs
  2. MUST handle API errors gracefully — return MCP error responses, don't crash the server
  3. MUST generate .env.example — never hardcode API keys or secrets
  4. MUST generate tests — no MCP server without test suite
  5. MUST generate installation docs for at least Claude Code — other IDEs are bonus
  6. MUST use official MCP SDK (@modelcontextprotocol/sdk for TS, fastmcp for Python)
  7. Tool descriptions MUST be AI-friendly — clear, specific, include parameter semantics

Sharp Edges

| Failure Mode | Severity | Mitigation | |---|---|---| | 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 | | Missing input validation → server crashes on bad input | HIGH | Constraint 1: Zod/Pydantic validation on all inputs | | Hardcoded API keys in generated code | CRITICAL | Constraint 3: always use env vars + .env.example | | Tests mock everything → no real integration coverage | MEDIUM | Generate both unit tests (mocked) and integration test template (real API) | | Generated server doesn't match MCP spec | HIGH | Use official SDK — don't hand-roll protocol handling | | Installation docs only for Claude Code | LOW | Include Cursor/Windsurf config examples too | | Mutation tool without confirmation gate | CRITICAL | Step 3.5: classify every tool — any write/delete/send without a preview+confirm step is a footgun |

Done When

  • Server specification elicited (tools, resources, target API, language)
  • Architecture designed (file structure, module boundaries)
  • Server code generated (tools, resources, config, types)
  • Test suite generated (happy path, validation, errors, edge cases)
  • Documentation generated (README with tool catalog, installation, config)
  • Verification passed (types + tests)
  • Ready to install in Claude Code / Cursor / other IDEs

Returns

| Artifact | Format | Location | |----------|--------|----------| | MCP server source code | TypeScript or Python | mcp-server-/src/ | | Tool definitions (one per tool) | TS/Python files | src/tools/.ts or .py | | Resource handlers | TS/Python files | src/resources/.ts or .py | | Test suite | TS/Python test files | tests/ | | README with tool catalog | Markdown | mcp-server-/README.md | | Environment config template | .env.example | project root |

Cost Profile

~3000-6000 tokens input, ~2000-5000 tokens output. Sonnet — MCP server generation is a structured code task, not architectural reasoning.

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.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.