| name | mcp-crafting |
| description | Building MCP (Model Context Protocol) servers with official SDKs: protocol concepts (tools, resources, prompts), transports (stdio, streamable HTTP), bundles (.mcpb), MCP Inspector testing, client integration with Claude Desktop and Claude Code, logging, error handling, security. Triggers: creating MCP servers, defining MCP tools/resources, configuring transports, packaging bundles, testing servers, integrating with Claude; MCP tool definition, MCP resource exposure, FastMCP server patterns. Language modules available for Python (FastMCP) and TypeScript (@modelcontextprotocol/sdk).
|
| allowed-tools | ["Read","Write","Edit","Glob","Grep","Bash"] |
| compatibility | Claude Code |
| staleness_sensitive_sections | ["Before You Build: Do You Need MCP?","Transports","Bundles (.mcpb) -- Packaging for Distribution","Code Execution with MCP (Emerging)","Resources","SDK Landscape","SDK v2 Alpha Note"] |
| staleness_threshold_days | 60 |
MCP Server Development
Build Model Context Protocol servers that expose tools, resources, and prompts to LLM applications.
Satellite files (loaded on-demand):
For MCP connector API features (calling MCP servers from the Messages API), consult the claude-ecosystem skill.
Table of Contents
Before You Build: Do You Need MCP?
MCP is not free. Each connected server injects its tool schemas into context at session start — commonly thousands of tokens before the user says anything — and a larger tool surface measurably degrades tool-selection accuracy (the model picks wrong among look-alikes). A single broad query has been measured at ~30× more tokens through an MCP server than through the equivalent CLI.
So, in order:
- Can a CLI tool do it? LLMs already know how to call
some-tool --help. A well-documented CLI (or a Praxion command/skill that wraps one) is often cheaper and simpler than an MCP server. Reach for MCP when you need a typed, discoverable contract a model invokes directly, OAuth-mediated remote access, or resources/prompts — not merely to wrap an API.
- If you do build MCP, install few servers and scope narrowly. Three focused servers beat thirteen; fewer, sharper tools choose better.
- At large tool counts, prefer code-execution mode (see Code Execution with MCP).
Tool-design quality (naming, fat-vs-thin, error grammar) is its own discipline — see agentic-interface-design and Anthropic's Writing effective tools for AI agents. To document an existing MCP server's tool catalog (render schemas + annotations + error modes from live tools/list), see api-documentation (mcp-docs.md).
Language Contexts
When working in a specific language, load the corresponding context for SDK setup, code examples, testing, and deployment patterns. The contexts carry version-pinned SDK guidance (SDK versions, package ranges) — the most drift-prone content in this skill; re-verify with /refresh-skill mcp-crafting against current SDK releases before relying on a pin.
Core Primitives
Tools -- Executable Functions
Tools perform computation and side effects. The LLM invokes them. Define parameters with types, defaults, and descriptions so the LLM understands how to call the tool.
Tool "search_database":
Parameters:
query: string (required) -- search query
limit: integer (default: 10) -- max results
Returns: array of objects
Tool "long_task":
Parameters:
name: string (required) -- task identifier
steps: integer (default: 5) -- number of steps
Returns: string (completion message)
Behavior: reports progress after each step
Use tools for: computation, side effects, actions on external systems, anything that changes state.
Tool design quality — naming a tool well, writing its description so a model comprehends it on every call, deciding fat-vs-thin decomposition, applying progressive disclosure when the surface exceeds ~20 tools, and designing errors the model can self-recover from — is a design discipline distinct from the implementation mechanics on this page. For that craft, see the agentic-interface-design skill (the tool name and description ARE the interface; the description is the primary lever for correcting model behavior). This page covers how to build an MCP server; agentic-interface-design covers how good the tool design is.
Resources -- Data Exposure
Resources provide data to LLMs (like GET endpoints). No significant side effects. Identified by URI templates.
Resource "config://settings":
Returns: string (JSON)
Resource "file://docs/{path}":
Parameters:
path: string (URI template variable)
Returns: string (file content)
Use resources for: read-only data, configuration, file access, database lookups without mutations.
Prompts -- Reusable Templates
Prompts define structured interaction patterns for LLMs. They accept parameters and return formatted text.
Prompt "analyze_data":
Parameters:
dataset: string (required)
focus: string (default: "trends")
Returns: string (prompt text)
Use prompts for: standardized analysis requests, review templates, multi-step workflows.
For prompt-body authoring patterns (few-shot examples, chain-of-thought, structured-output instructions, injection hardening) used inside MCP prompt templates, see the llm-prompt-engineering skill.
Do not mix primitives. Tools execute logic (side effects OK). Resources expose data (no side effects). Prompts template interactions. If a function reads data and mutates state, make it a tool.
See language context for SDK-specific decorator syntax and code examples.
Transports
| Transport | Use Case |
|---|
| stdio | Local development, Claude Desktop |
| Streamable HTTP | Production, remote clients |
SSE is deprecated — use streamable HTTP for all new HTTP-based servers. Remote HTTP servers standardize on OAuth 2.1 for auth (handled in-browser on first use for hosted servers); always use HTTPS, never hardcode tokens. Tools lazy-load — the connection opens on first use, not at registration.
See language context for transport configuration code.
Logging
Universal rule: never print to stdout in stdio servers -- it corrupts JSON-RPC messages. Direct all logging output to stderr.
For HTTP servers, standard output logging is acceptable.
See language context for logging setup code.
Client Integration
Claude Desktop
Configure servers in the Claude Desktop config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"my-server": {
"command": "RUNTIME_COMMAND",
"args": ["RUNTIME_ARGS"]
}
}
}
See your language context for the command and args values appropriate to your runtime.
Claude Code
claude mcp add --transport http my-server http://localhost:8000/mcp
claude mcp add my-server --scope project -- RUNTIME_COMMAND RUNTIME_ARGS
See your language context for the stdio launch command.
Error Handling
- Validate inputs early -- check types, ranges, required fields before processing
- Catch specific exceptions with targeted responses, fall back to generic handlers
- Return
isError: true in CallToolResult for tool-level failures
- Log full error details to stderr; sanitize responses to avoid leaking internals
- Provide context-aware messages that help the LLM recover ("column 'xyz' not found -- did you mean 'xy'?")
Token-Efficient Tool Responses
A tool's return value is context the model pays for on every call. Build for token efficiency (design rationale: agentic-interface-design; source: Writing effective tools for AI agents):
- Default to filtered, paginated responses. Provide sensible default limits, range selection, and filtering — don't return everything. Claude Code caps tool responses at 25,000 tokens by default; on truncation, return guidance steering the model toward narrower queries.
- Offer a
response_format (concise | detailed) so the agent tunes verbosity — concise returns only actionable content; detailed adds IDs/metadata for chained calls.
- Return natural-language identifiers, not opaque UUIDs. Models reason far better over
name/title than over a3f9-…; surface high-signal fields, drop low-signal ones (mime_type, 256px_url).
- Write errors that steer. "Found 847 results — too many to return; narrow by date or category" beats an opaque code or traceback.
Testing
MCP Inspector
The MCP Inspector provides interactive testing for any MCP server, regardless of language:
npx -y @modelcontextprotocol/inspector
Connect to a running server or launch one directly. The Inspector lets you invoke tools, read resources, and test prompts through a web UI at localhost:6274.
See language context for in-memory / programmatic testing patterns.
Bundles (.mcpb) -- Packaging for Distribution
MCP Bundles are ZIP archives (.mcpb extension) containing a server and a manifest.json. They enable one-click installation in Claude Desktop (double-click, drag-and-drop, or Developer menu). Formerly called DXT (Desktop Extensions).
Repository: modelcontextprotocol/mcpb
Manifest Overview
Every bundle requires a manifest.json with at minimum:
Manifest fields (required):
manifest_version: string -- currently "0.4"
name: string -- unique identifier (lowercase, hyphens)
version: string -- semver
description: string -- what the server does
server:
type: string -- one of: node, uv, python, binary
entry_point: string -- path to server entry file
Manifest fields (optional):
author: { name, url, email }
user_config: object -- declares user-configurable fields
mcp_config: object -- environment variables for the server
Server Types
| Type | When to Use |
|---|
node | Recommended -- ships with Claude Desktop, zero install friction |
uv | Python servers -- host manages Python/deps via uv (experimental) |
python | Python with pre-bundled deps -- limited portability for compiled pkgs |
binary | Pre-compiled executables |
User Configuration
Declare config fields and Claude Desktop auto-generates a settings UI:
{
"user_config": {
"api_key": {
"type": "string",
"title": "API Key",
"required": true,
"sensitive": true
}
}
}
Reference via ${user_config.api_key} in mcp_config.env.
CLI
npm install -g @anthropic-ai/mcpb
mcpb init
mcpb pack
mcpb pack examples/hello-world-uv
See references/resources.md for the full manifest specification, bundle directory structures, and advanced examples. See language context for language-specific bundle patterns.
Code Execution with MCP (Emerging)
A 2026 pattern (Anthropic, Code execution with MCP): instead of loading every tool's schema and orchestrating call-by-call, the agent writes code that imports and calls tools in a sandbox, handling intermediate results at the edge. Reported up to ~98% token reduction (150k → 2k on a Drive→Salesforce workflow); the win scales with tool count. Four complementary levers: schema compression, search-first tool discovery (an optional search_tools endpoint loads defs on demand), response filtering, and code-based execution.
For Praxion this is forward-looking, not a hard requirement — it needs a sandboxed code-execution environment. When authoring an MCP server today, design tools so they compose cleanly in code (clear types, deterministic returns, idempotency via a request_id), so the server is ready if/when code-execution mode is available in the target harness.
Common Pitfalls
- Printing to stdout in stdio servers -- corrupts JSON-RPC. Log to stderr
- Using SSE transport -- deprecated. Use streamable HTTP
- Missing type annotations -- LLMs cannot understand tool parameters without annotations
- Mixing primitives -- tools execute logic (side effects OK), resources expose data (no side effects)
- Overly broad permissions -- start read-only, whitelist operations, restrict filesystem paths
See language context for language-specific pitfalls.
Resources