MCP Development
Skill Location: This file
Quick Start
Create MCP server: /toolkit:build:package → Full structure with SDK setup
Define tools: Follow <tool_schema> template with JSON Schema validation
Choose transport: stdio (local) or http (remote) based on use case
Validate server: scripts/test_mcp.sh → Quick integration testing
Why: MCP provides structured tool definitions with type safety—prevents runtime errors from malformed inputs.
Navigation
| If you need... | Read... |
|---|---|
| Create MCP server | ## Quick Start → /toolkit:build:package |
| Define tool schema | ## Implementation Patterns |
| Choose transport | ## Implementation Patterns |
| Context engineering | context-engineering skill |
| Authentication patterns | references/pattern_auth_patterns.md |
| Validate server | See validation section in this file |
| 2026 syntax features | references/pattern_2026_syntax.md |
| Plugin integration | references/pattern_plugin_integration.md |
Critical Reference Loading
Key Reference: Authentication patterns in pattern_auth_patterns.md contain JSON Schema validation rules critical for runtime stability. Read these patterns in full when implementing authentication—summarization causes validation failures.
System Requirements
- •MCP SDK:
@modelcontextprotocol/sdk(latest via npm/pnpm) - •TypeScript: >= 5.0
- •Node.js: >= 18
- •Validation:
scripts/test_mcp.sh(bundled CLI abstraction) - •Transport: stdio (local) or http (remote)
- •Schema: Valid JSON Schema for tool input/output
Operational Patterns
This skill follows these behavioral patterns:
- •Planning: Switch to planning mode for architectural decisions
- •Discovery: Locate files matching patterns and search file contents for MCP integration
- •Delegation: Delegate planning and exploration to specialized workers
- •Tracking: Maintain a visible task list for MCP development
<critical_constraint> Use native tools to fulfill these patterns. The System Prompt selects the correct implementation for semantic directives. </critical_constraint>
Implementation Patterns
Pattern: Tool Definition Template
{
"name": "tool_name",
"description": "Tool to <verb> <resource>. Use when <condition>. Constraints: <limits>.",
"inputSchema": {
"type": "object",
"properties": {
"param_name": {
"type": "string",
"description": "Parameter description",
"enum": ["value1", "value2"],
"format": "email"
}
},
"required": ["param_name"],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {
"result": { "type": "string", "description": "Result description" }
}
}
}
Pattern: stdio Transport (Local)
{
"transport": {
"type": "stdio",
"command": "node",
"args": ["server.js"]
}
}
Pattern: http Transport (Remote)
{
"transport": {
"type": "http",
"url": "http://localhost:3000",
"authentication": {
"type": "bearer",
"token": "${API_TOKEN}"
}
}
}
Pattern: Error Message
"Invalid input: parameter must be a valid email address. Please provide a valid email like user@example.com."
Troubleshooting
| Issue | Symptom | Solution |
|---|---|---|
| Schema validation fails | Tool calls rejected | Ensure valid JSON Schema, add descriptions |
| Agent doesn't use tool | Poor description | Use formula: "Tool to X. Use when Y. Constraints: Z." |
| Missing required fields | Runtime errors | Add required array in inputSchema |
| Wrong parameter type | Type errors | Match type in schema (string/number/boolean/array/object) |
| Enum values not recognized | Unexpected behavior | Use enums for finite value sets |
| Transport connection fails | Server not reachable | Verify stdio command or http URL |
<mission_control> <objective>Create portable MCP servers with strict tool schema definitions, clear transport logic, and prompt-engineered descriptions that guide agent behavior</objective> <success_criteria>Generated MCP server has valid JSON Schema for tools, prompt-engineered descriptions, and proper transport configuration</success_criteria> <standards_gate> Before creating MCP servers, review:
- •Tool schema & transport → https://code.claude.com/docs/en/mcp.md
- •Authentication patterns →
Glob: lookup_auth_patterns.md</standards_gate> </mission_control>
<interaction_schema> design → tool_schema_definition → transport_logic → validation → output</interaction_schema>
MCP (Model Context Protocol) servers provide structured integration between Claude and external systems. They define tools, resources, and prompts that Claude can access through standardized protocols.
Core principle: Treat every MCP tool like a tiny, well-written prompt for the agent. The descriptions and schemas you write directly influence how well Claude understands and uses your tools.
<pattern name="prompt_engineering_principle"> <principle>Tool descriptions and schemas are prompts to the agent. Write them as if explaining to a new hire—make implicit context explicit.</principle> </pattern>
Prompt Engineering for Tool Descriptions
<description_pattern> <purpose>Structure tool descriptions to maximize agent understanding</purpose>
<template_formula>
Standard description format:
description: "Brief description, non spoiling of the content. Use when {trigger condition + keywords + key sentences user might say that should lead the tool to be invoked}. Not for {exclusions}."
Alternative formula (MCP-style):
Tool to <verb> <resource>. Use when <trigger condition>. Constraints: <key limits>.
{
"name": "create_channel",
"description": "Tool to create a new Slack channel. Use when the user asks to create a new channel, make a new channel, or set up a channel."
}
{
"name": "create_contact",
"description": "Tool to create a new Salesforce contact. Use when the user wants to create a contact, add a new contact, or input contact data. Required workflow: call discover_required_fields('Contact') first to identify mandatory fields and prevent creation errors. Not for bulk imports."
}
{
"name": "get_calls",
"description": "Tool to list all calls in a date range. Use when the user asks for calls across a workspace without user/workspace filtering. Constraint: this tool does not support user or workspace filters; for filtered calls, use search_calls_extensive instead. Not for real-time or live call data."
}
<structure_rules>
- •Start with action: Verb + resource (what the tool does)
- •Add trigger condition: Keywords and phrases that activate the tool
- •Front-load constraints: Required workflows, hard limits, alternatives
- •End with exclusions: "Not for" clause prevents misuse
</structure_rules>
<length_guidance>
- •Keep descriptions 1-2 sentences
- •Under 1024 characters in practice
- •Avoid marketing fluff
- •Focus on non-spoiling description
</length_guidance>
</description_pattern>
Schema-Level Prompt Engineering
<schema_pattern> <purpose>Use schemas not just for validation, but as prompts to the agent</purpose>
<parameter_level_guidance>
<property_pattern name="enum_preference">
Use enums instead of free text when:
- •Finite set of values (status: ["pending", "approved", "rejected"])
- •Predefined options (unit: ["celsius", "fahrenheit"])
- •Boolean-like choices (severity: ["low", "medium", "high", "critical"])
Why: Enums remove ambiguity and act as strong constraints at the schema level.
</property_pattern>
<property_pattern name="format_constraints">
Use format constraints:
"email": {
"type": "string",
"format": "email",
"description": "User's email address"
}
Common formats: email, date, date-time, uri, uuid
</property_pattern>
<property_pattern name="conditional_requirements">
State mutual exclusivity or requirements in descriptions:
"agent_id": {
"type": "string",
"description": "Unique identifier for agent. At least one of agent_id, user_id, app_id, or run_id must be provided."
}
</property_pattern>
</parameter_level_guidance>
<output_schema>
Define outputSchema for complex responses:
{
"name": "get_weather",
"description": "Get weather conditions for a city",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"enum": ["New York", "Chicago", "Los Angeles"],
"description": "Choose city"
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"temperature": {
"type": "number",
"description": "Temperature in Fahrenheit"
},
"conditions": { "type": "string", "description": "Weather conditions" },
"humidity": { "type": "number", "description": "Humidity percentage" }
}
}
}
Why: outputSchema guides the agent about what shape to expect, improving reasoning about downstream tools.
</output_schema>
</schema_pattern>
When and How to Use Strong Language
<strong_language> <purpose>Directive language (must, always, never, required) for agent guidance</purpose>
<where_to_use>
<location type="safety">Safety and guardrails:
"description": "Tool to delete a user record. Use only when the user has confirmed deletion and has appropriate permissions. Never allow deletion without explicit user consent."
Preconditions and ordering:
"description": "Tool to create a contact. Required workflow: call discover_required_fields('Contact') first to identify mandatory fields."
Format and cardinality constraints:
"title": {
"type": "string",
"description": "Title must be between 5 and 120 characters"
}
Error messages for agent recovery:
"Invalid date_range: date_from is after date_to. Please ensure date_from is earlier than date_to and try again."
</where_to_use>
<guidance>Use strong language for:
- •Safety requirements (never expose credentials)
- •Required workflows (must call X first)
- •Non-negotiable constraints (must be <= 100)
- •Error recovery instructions
Avoid overusing strong language for:
- •General behavior descriptions
- •Optional features
- •Documentation-level details (put these in schema)
Trade-off: Too much strong language causes token bloat and over-constraint. Use sparingly where it matters most.
</guidance></strong_language>
Guiding Agents with Errors
<error_guidance> <purpose>Error messages are micro-prompts that guide agents to self-correct</purpose>
<pattern>Error message formula:
<Problem>. <Why>. <Fix>.
"Invalid date_from: date_from must be earlier than date_to. Please adjust date_from to a value before date_to and retry."
"Missing required parameter: repo_path is required. Please provide the path to the Git repository and retry."
"Access denied: token lacks write scope. Ask the user to grant write permissions or use a read-only tool."
"Result truncated: returned first 500 of 3,000 rows. To reduce truncation, specify a narrower date range or use filters (user_id, event_type)."
- •Return structured errors with isError flag
- •Use natural language, not stack traces
- •Include concrete examples of correct parameters
- •Suggest recovery actions explicitly
</error_guidance>
Balancing Power vs Complexity
<complexity_management> <purpose>Achieve maximum capability with minimum cognitive load</purpose>
<per_tool_targets>
- •One clear, atomic action per tool
- •1-3 required parameters, small number of optional (total < 6-7)
- •Short descriptions (1-2 sentences, < 1024 chars)
- •Narrow scope: Don't create "manage" tools; prefer "create", "delete", "list", "search"
</per_tool_targets>
<per_server_targets>
- •Coherent domain: Group related tools by service (git**, slack*_, jira__)
- •Small surface: Each server should do one thing well
- •Consolidate chains: Merge tools that are almost always called together
</per_server_targets>
<annotations>Use MCP annotations for client guidance:
- •
readOnlyHint: tool doesn't modify state - •
destructiveHint: may cause destructive changes (triggers confirmations) - •
idempotentHint: repeating the call is safe
</complexity_management>
Community Patterns and Examples
<community_examples> <purpose>Reference patterns from official MCP servers and community implementations</purpose>
<pattern name="naming">Consistent snake_case with namespace prefixes:
{
"git_status": "Shows working tree status",
"git_diff_unstaged": "Shows unstaged changes",
"git_commit": "Records changes to the repository"
}
Concise descriptions following the formula:
{
"name": "get_structured_content",
"description": "Returns structured content along with an output schema for client data validation"
}
Strong typing with enums and descriptions:
{
"location": {
"type": "string",
"enum": ["New York", "Chicago", "Los Angeles"],
"description": "Choose city"
}
}
One dense description for server capability (not individual tools):
{
"description": "Integrates with Slack Lists to enable creation, retrieval, filtering, and management of list items with support for bulk operations, data export to JSON/CSV formats"
}
</community_examples>
<pattern name="tool_schema_enforcement"> <principle>Use `<tool_schema>` tags to ensure generated MCP servers have valid JSON Schema for tool parameters.</principle> </pattern>
<tool_schema> <purpose>Strict template for generating valid tool definitions</purpose>
<tool_definition_template>
{
"name": "{{TOOL_NAME}}",
"description": "{{PROMPT_ENGINEERED_DESCRIPTION}}",
"inputSchema": {
"type": "object",
"properties": {
{{PARAMETER_DEFINITIONS}}
},
"required": [{{REQUIRED_PARAMS}}],
"additionalProperties": false
},
"outputSchema": {{OUTPUT_SCHEMA}}
}
</tool_definition_template>
<parameter_template>
"{{PARAM_NAME}}": {
"type": "{{PARAM_TYPE}}",
"description": "{{PARAM_DESCRIPTION}}",
"enum": [{{ENUM_VALUES}}],
"format": "{{FORMAT}}",
"default": "{{DEFAULT_VALUE}}"
}
</parameter_template>
<validation_rules>
- •Tool names use snake_case with namespace prefix (e.g.,
service_action) - •Descriptions achieve clarity when following: "Tool to <verb> <resource>. Use when <condition>. Constraints: <limits>."
- •Valid JSON Schema ensures runtime reliability for inputSchema
- •Parameter descriptions prevent misuse by explaining meaning and constraints
- •The required field lists all non-optional parameters
- •Set additionalProperties to false for strict validation
- •Enums improve reliability for finite value sets
- •Format constraints (email, date, etc.) add automatic validation
</validation_rules>
<common_types>
- •string - Text values
- •number - Numeric values (int or float)
- •boolean - true/false
- •array - Lists of items
- •object - Nested structures
- •enum - Fixed set of values
</common_types>
<common_formats>
- •email - Valid email address
- •date - ISO date (YYYY-MM-DD)
- •date-time - ISO datetime
- •uri - Valid URI
- •uuid - Valid UUID
</common_formats>
</tool_schema>
Transport Logic
<transport_selection> <purpose>Define when to use stdio vs http transport</purpose>
<transports> <transport type="stdio"> <use_case>Local development, subprocess communication</use_case> <advantages> - Direct Claude integration - Simple setup - No network overhead - Ideal for CLI tools </advantages> <disadvantages> - Single client only - Local only </disadvantages> <example> ```json { "transport": { "type": "stdio", "command": "node", "args": ["server.js"] } } ``` </example> </transport> <transport type="http"> <use_case>Remote servers, multi-client scenarios</use_case> <advantages> - Multiple clients - Remote access - Network transport - Load balancing </advantages> <disadvantages> - Requires server setup - Network dependency - Authentication needed </disadvantages> <example> ```json { "transport": { "type": "http", "url": "http://localhost:3000", "authentication": { "type": "bearer", "token": "${API_TOKEN}" } } } ``` </example> </transport> </transports><selection_criteria>
- •Local tool → stdio
- •Remote service → http
- •Multi-user → http
- •Development → stdio
- •Production → http </selection_criteria> </transport_selection>
MCP servers provide:
- •Tool definitions: Structured capabilities Claude can invoke
- •Resource access: Shared data and context
- •Prompt templates: Reusable interaction patterns
- •Transport mechanisms: Communication protocols
- •Portability: Work across different environments
MCP Architecture
Server-Based: MCPs run as separate servers that Claude connects to
Three Component Types:
- •Tools: Invocable functions with parameters
- •Resources: Data sources and context providers
- •Prompts: Template-based interaction patterns
Core Structure
Server Configuration (McpServer)
<critical_constraint>
Use McpServer from @modelcontextprotocol/sdk/server/mcp.js (the legacy Server is deprecated)
</critical_constraint>
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "mcp-server-name",
version: "1.0.0",
});
// Tool registration with Zod
server.tool(
"tool-name",
"Tool description",
{
param: z.string().describe("Parameter description"),
},
async ({ param }) => {
// Implementation
return { content: [{ type: "text", text: result }] };
},
);
// Transport connection
const transport = new StdioServerTransport();
await server.connect(transport);
Validation Framework
<critical_constraint>
Use scripts/test_mcp.sh for MCP server validation—this script abstracts @modelcontextprotocol/inspector complexity into a simple CLI.
</critical_constraint>
Quick validation commands:
# Health check (verifies server starts and responds)
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js health
# List all tools (verify schema and descriptions)
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js tools
# List resources
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js resources
# List prompts
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js prompts
# Call a tool (happy path)
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js call myTool --arg key=value
# Call with JSON arguments
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js call myTool --json '{"key": "value"}'
# Run full test suite
scripts/test_mcp.sh Custom_MCP/{project}/dist/server.js all
CI/CD validation with exit codes:
#!/bin/bash
set -e
PROJECT="your-project-name"
SERVER_PATH="Custom_MCP/${PROJECT}/dist/server.js"
# Health check (exit 0 = server running)
scripts/test_mcp.sh "$SERVER_PATH" health || exit 1
# List tools (verify definitions)
TOOLS=$(scripts/test_mcp.sh "$SERVER_PATH" tools)
echo "$TOOLS" | jq -e '.tools | length > 0' || exit 1
# Test critical tool
scripts/test_mcp.sh "$SERVER_PATH" call myCriticalTool --arg input="test" || exit 1
echo "MCP server validation: PASS"
For deep spec compliance, combine with external validators like mcp-validator:
# STDIO compliance test
python -m mcp_testing.scripts.compliance_report \
--server-command "node Custom_MCP/${PROJECT}/dist/server.js" \
--protocol-version 2025-06-18
Relevance Heuristic
<freshness_gate> <purpose>Validate URL freshness before trusting documentation</purpose>
<rule>Freshness Gate: Before trusting any code snippets from a URL:
- •Fetch the URL and check for last-updated metadata (Last-Modified header, date in content, or commit history)
- •If content is > 6 months old, search for a more recent version before using the code
- •Prefer recent commits over branch files for SDK documentation
- •Document the freshness check result in the session
Skip freshness check when:
- •Checking npm/GitHub version info (timestamp is the version)
- •The URL is clearly versioned (e.g., /v1/, /2026/)
- •Official SDK changelog confirms stability
<freshness_check>
# Check GitHub file last commit date gh api repos/modelcontextprotocol/specification/commits?path=specification.md --jq '.[0].commit.author.date' # Or fetch and parse for dates curl -sI https://github.com/modelcontextprotocol/specification | grep -i last-modified
</freshness_check>
</freshness_gate>
Protocol: Check Principles → Freshness Gate → Fetch Instance → Extract Delta → Dispose
Before fetching MCP specification URLs:
- •
Check Principles - This skill covers tool schema design, transport selection, error guidance, and prompt engineering. The patterns here are stable.
- •
Freshness Gate - Verify URL is < 6 months old. If older, search for updated version or use npm package version instead.
- •
Fetch Instance Only When:
- •MCP SDK version has breaking changes
- •Transport mechanism differs from documented patterns
- •New primitive types not covered
- •Authentication flow has changed
- •
Extract Delta - Keep only what this skill doesn't cover:
- •SDK-specific initialization changes
- •New transport options
- •Updated security requirements
- •Protocol version differences
- •
Dispose Context - Remove fetched content after extracting delta
Delta Pattern: Fetch the URL, identify current tool-calling syntax, apply directly to the local file. Store patterns, not documentation. Documentation becomes stale; patterns remain actionable.
When NOT to fetch:
- •Tool description formula (covered in skill)
- •Schema patterns (covered with templates)
- •Transport selection criteria (covered in tables)
- •Error guidance (covered with examples)
- •Strong language usage (covered in patterns)
Official Documentation (fetch for current MCP syntax):
- •Tool schema & transport → https://code.claude.com/docs/en/mcp.md
- •Inspector CLI (testing) → https://github.com/modelcontextprotocol/inspector
- •MCP Validator (compliance) → https://github.com/Janix-ai/mcp-validator
- •Protocol spec → https://modelcontextprotocol.io/
- •Best practices → https://modelcontextprotocol.info/docs/best-practices
- •SDK docs → https://modelcontextprotocol.io/quickstart/server
- •Testing guide → https://www.stainless.com/mcp/how-to-test-mcp-servers
Workflow: Freshness check → Verify npm package version → Consult skill patterns → Fetch spec only if behavior differs → Extract delta → Dispose
Dynamic Sourcing Protocol
<fetch_protocol> Before creating MCP servers, fetch current syntax from:
- •https://code.claude.com/docs/en/mcp.md (tool schema and transport)
Note: For CLI testing, use scripts/test_mcp.sh instead of fetching inspector documentation.
</fetch_protocol>
Navigation
Official Documentation:
- •Tool schema & transport → https://code.claude.com/docs/en/mcp.md
- •Inspector CLI (testing) → https://github.com/modelcontextprotocol/inspector
- •MCP Validator (compliance) → https://github.com/Janix-ai/mcp-validator
- •Protocol spec → https://modelcontextprotocol.io/
- •Best practices → https://modelcontextprotocol.info/docs/best-practices
- •SDK docs → https://modelcontextprotocol.io/quickstart/server
- •Testing guide → https://www.stainless.com/mcp/how-to-test-mcp-servers
| If you need... | Reference |
|---|---|
| Testing MCP server | scripts/test_mcp.sh |
| Authentication | references/lookup_auth_patterns.md |
| Plugin integration | references/lookup_plugin_integration.md |
| 2026 features | references/lookup_2026_syntax.md |
Genetic Code
This component carries essential Seed System principles for context: fork isolation:
<critical_constraint>
All components work with zero CLAUDE.md, CLAUDE.local.md, or .claude/rules/ dependencies (portability invariant).
Achieve 80-95% autonomy (0-5 AskUserQuestion rounds per session).
Use What-When-Not-Includes format in descriptions (third person).
Progressive disclosure: SKILL.md contains core philosophy; references/ contains detailed content.
Use XML for control (mission_control, critical_constraint), Markdown for data.
When referencing other skills: use "invoke skill-name" or "invoke skill-name and read its file". Never cite absolute paths or reference .claude/rules/ from skills.
</critical_constraint>
Delta Standard: Good Component = Expert Knowledge − What Claude Already Knows
Recognition Questions
| Question | Recognition |
|---|---|
| Would Claude know this without being told? | Delete (zero delta) |
| Can this work standalone? | Fix if no (non-self-sufficient) |
| Did I read the actual file, or just see it in grep? | Verify before claiming |
Validation Checklist
Before claiming MCP development complete:
- • Prompt-engineered descriptions used
- • Schema-first design followed
- • Transport layer properly configured
- • Tool schemas validated
<guiding_principles>
The Path to MCP Server Quality
1. Prompt-Engineered Descriptions
Tool descriptions achieve optimal agent behavior when written as micro-prompts.
- •Description formula: "Tool to <verb> <resource>. Use when <condition>. Constraints: <limits>."
- •Front-load constraints: Place critical requirements and workflows first
- •Conciseness: 1-2 sentences, under 1024 characters
2. Schema-First Design
Valid JSON Schema prevents runtime errors and guides agent behavior.
- •Use
<tool_schema>template: Follow the tool definition structure exactly - •Kebab-case names: Service_action format improves discoverability
- •Property descriptions: Explain parameter meaning and constraints
- •Enums over free text: Finite value sets reduce ambiguity
- •Format constraints: Add automatic validation (email, date, uri, uuid)
3. Transport by Use Case
Choose stdio or http based on deployment requirements.
- •stdio for local: Single client, direct integration, simpler setup
- •http for remote: Multiple clients, network transport, load balancing
- •Define clearly: Transport configuration affects deployment architecture
4. Error Messages as Micro-Prompts
Errors guide agents to self-correct when structured properly.
- •Pattern: "<Problem>. <Why>. <Fix>."
- •Concrete suggestions: Include examples of correct parameters
- •Recovery actions: Explicit next steps instead of stack traces
5. Portability First
Servers work across environments when configured properly.
- •Environment variables: Externalize configuration
- •Project-relative paths: Use
${CLAUDE_PROJECT_DIR}instead of hardcoding - •Self-contained dependencies: Bundle required packages
- •Graceful degradation: Handle missing configuration safely
6. Security by Design
Input validation and sanitization prevent common vulnerabilities.
- •Validate all inputs: Against schema before processing
- •Sanitize user input: Prevent injection attacks
- •Parameterized queries: Use prepared statements for databases
- •Rate limiting: Prevent abuse and resource exhaustion
- •Mask sensitive data: Never log credentials or tokens
- •HTTPS only: Encrypt external communications
7. Performance Patterns
Servers remain responsive under load when optimized appropriately.
- •Cache repeated operations: Use
@lru_cacheor equivalent - •Paginate large results: Return data in manageable chunks
- •Batch operations: Group related calls when possible
- •Set timeouts: Prevent indefinite waits </guiding_principles>
<critical_constraint> System Physics:
- •Skill portability: The skill must function without CLAUDE.md, CLAUDE.local.md, or .claude/rules/ dependencies (core invariant)
- •Optional tooling: External validators (
mcp-validator,mcp_testing) are recommended for deep compliance but not required—the skill provides manual review patterns as fallback - •Use
McpServerfrom@modelcontextprotocol/sdk/server/mcp.js(legacyServerdeprecated) - •Completion claims require verification evidence
- •Prompt-engineered descriptions required for protocol correctness </critical_constraint>
Dynamic Knowledge Loading
This skill uses Blind Navigation for references. Load specialized knowledge ONLY when specific conditions are met:
| Context Condition | Resource | Action |
|---|---|---|
| Testing MCP server | Glob: test_mcp.sh | Execute for validation |
| Authentication patterns | Glob: lookup_auth_patterns.md | Grep for .env setup and header formats |
| Plugin integration | Glob: lookup_plugin_integration.md | Grep for MCP client patterns |
| 2026 syntax features | Glob: lookup_2026_syntax.md | Grep for new primitives |
| Tool schema templates | See tool_schema section | Grep for JSON Schema patterns |
| Enforcing tool invocation | Glob: lookup_anti_laziness_patterns.md | Grep for confidence rating, CoT patterns |
Dynamic Sourcing
Syntax Source: This skill focuses on patterns and philosophy. For raw MCP tool schema syntax:
- •Fetch:
https://code.claude.com/docs/en/mcp.md - •Extract: The specific tool schema fields you need
- •Discard: Do not retain the fetch in context
Common Mistakes to Avoid
Mistake 1: Missing additionalProperties
❌ Wrong:
"inputSchema": {
"type": "object",
"properties": { "param": { "type": "string" } }
}
✅ Correct:
"inputSchema": {
"type": "object",
"properties": { "param": { "type": "string" } },
"additionalProperties": false
}
Mistake 2: Weak Tool Descriptions
❌ Wrong:
"description": "Tool to get data"
✅ Correct:
"description": "Tool to retrieve user authentication status. Use when checking if a user is logged in or verifying session validity. Not for authentication operations (use auth-tool instead)."
Mistake 3: Missing Required Parameters
❌ Wrong:
"inputSchema": {
"type": "object",
"properties": { "user_id": { "type": "string" } }
}
✅ Correct:
"inputSchema": {
"type": "object",
"properties": { "user_id": { "type": "string", "description": "The user ID to look up" } },
"required": ["user_id"],
"additionalProperties": false
}
Mistake 4: Using Deprecated Server Class
❌ Wrong:
import { Server } from "@modelcontextprotocol/sdk/server/index.js"
✅ Correct:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
Mistake 5: Poor Error Messages
❌ Wrong:
"Invalid input"
✅ Correct:
"Invalid user_id: 'abc123' is not a valid UUID format. Please provide a valid UUID like '550e8400-e29b-41d4-a716-446655440000'."
Validation Checklist
Before claiming MCP development complete:
Tool Schema:
- • Valid JSON Schema for inputSchema
- • All required parameters listed in
requiredarray - • additionalProperties set to false
- • Parameter descriptions explain purpose and constraints
Tool Description:
- • Follows formula: "Tool to X. Use when Y. Constraints: Z."
- • Includes trigger conditions
- • Excludes use cases clearly (Not for...)
Transport:
- • stdio configured for local tools
- • http configured for remote tools
- • Authentication properly set up
Server:
- • Uses McpServer (not deprecated Server class)
- • Tools registered with valid schemas
- • Server properly initialized
Testing:
- • test_mcp.sh validation passes
- • Tool calls work correctly
- • Error messages are helpful
Best Practices Summary
✅ DO:
- •Use
additionalProperties: falsefor strict validation - •Write tool descriptions as micro-prompts
- •Include all required parameters in schema
- •Use enums for finite value sets
- •Set format constraints (email, date, etc.)
- •Use McpServer from correct import path
- •Test with test_mcp.sh before claiming complete
❌ DON'T:
- •Skip parameter descriptions
- •Use loose schemas without additionalProperties
- •Write vague tool descriptions
- •Forget required array for mandatory params
- •Use deprecated Server class
- •Skip error message improvement
- •Skip validation testing
<critical_constraint> System Physics:
- •Zero external dependencies (portability invariant)
- •Use
McpServerfrom@modelcontextprotocol/sdk/server/mcp.js(legacyServerdeprecated) - •Completion claims require verification evidence
- •Prompt-engineered descriptions required for protocol correctness
- •additionalProperties: false required for tool schemas </critical_constraint>