Claude Cursor GitHub Copilot Skill

MCP Integration

This skill should be used when the user asks to "add MCP server", "integrate MCP", "configure MCP in plugin", "use .mcp.json", "set up Model Context Protocol", "connect external service", mentions "${CLAUDE_PLUGIN_ROOT} with MCP", or discusses MCP server types (SSE, stdio, HTTP,

LLM Mart · 0 points · 14 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download tzachbon-smart-ralph-.agents_skills_MCP Integration-4890dd3.zip · 17 KB
Part of tzachbon/smart-ralph — 44 skills

Install

skills CLI npx skills add https://github.com/tzachbon/smart-ralph/tree/main/.agents/skills/MCP Integration
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install tzachbon-smart-ralph@llmmart
Git git clone https://github.com/tzachbon/smart-ralph.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole tzachbon/smart-ralph collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

MCP Integration for Claude Code Plugins

Overview

Model Context Protocol (MCP) enables Claude Code plugins to integrate with external services and APIs by providing structured tool access. Use MCP integration to expose external service capabilities as tools within Claude Code.

Key capabilities:

  • Connect to external services (databases, APIs, file systems)
  • Provide 10+ related tools from a single service
  • Handle OAuth and complex authentication flows
  • Bundle MCP servers with plugins for automatic setup

MCP Server Configuration Methods

Plugins can bundle MCP servers in two ways:

Method 1: Dedicated .mcp.json (Recommended)

Create .mcp.json at plugin root:

{
  "database-tools": {
    "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
    "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
    "env": {
      "DB_URL": "${DB_URL}"
    }
  }
}

Benefits:

  • Clear separation of concerns
  • Easier to maintain
  • Better for multiple servers

Method 2: Inline in plugin.json

Add mcpServers field to plugin.json:

{
  "name": "my-plugin",
  "version": "1.0.0",
  "mcpServers": {
    "plugin-api": {
      "command": "${CLAUDE_PLUGIN_ROOT}/servers/api-server",
      "args": ["--port", "8080"]
    }
  }
}

Benefits:

  • Single configuration file
  • Good for simple single-server plugins

MCP Server Types

stdio (Local Process)

Execute local MCP servers as child processes. Best for local tools and custom servers.

Configuration:

{
  "filesystem": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
    "env": {
      "LOG_LEVEL": "debug"
    }
  }
}

Use cases:

  • File system access
  • Local database connections
  • Custom MCP servers
  • NPM-packaged MCP servers

Process management:

  • Claude Code spawns and manages the process
  • Communicates via stdin/stdout
  • Terminates when Claude Code exits

SSE (Server-Sent Events)

Connect to hosted MCP servers with OAuth support. Best for cloud services.

Configuration:

{
  "asana": {
    "type": "sse",
    "url": "https://mcp.asana.com/sse"
  }
}

Use cases:

  • Official hosted MCP servers (Asana, GitHub, etc.)
  • Cloud services with MCP endpoints
  • OAuth-based authentication
  • No local installation needed

Authentication:

  • OAuth flows handled automatically
  • User prompted on first use
  • Tokens managed by Claude Code

HTTP (REST API)

Connect to RESTful MCP servers with token authentication.

Configuration:

{
  "api-service": {
    "type": "http",
    "url": "https://api.example.com/mcp",
    "headers": {
      "Authorization": "Bearer ${API_TOKEN}",
      "X-Custom-Header": "value"
    }
  }
}

Use cases:

  • REST API-based MCP servers
  • Token-based authentication
  • Custom API backends
  • Stateless interactions

WebSocket (Real-time)

Connect to WebSocket MCP servers for real-time bidirectional communication.

Configuration:

{
  "realtime-service": {
    "type": "ws",
    "url": "wss://mcp.example.com/ws",
    "headers": {
      "Authorization": "Bearer ${TOKEN}"
    }
  }
}

Use cases:

  • Real-time data streaming
  • Persistent connections
  • Push notifications from server
  • Low-latency requirements

Environment Variable Expansion

All MCP configurations support environment variable substitution:

$ - Plugin directory (always use for portability):

{
  "command": "${CLAUDE_PLUGIN_ROOT}/servers/my-server"
}

User environment variables - From user's shell:

{
  "env": {
    "API_KEY": "${MY_API_KEY}",
    "DATABASE_URL": "${DB_URL}"
  }
}

Best practice: Document all required environment variables in plugin README.

MCP Tool Naming

When MCP servers provide tools, they're automatically prefixed:

Format: mcp__plugin_<plugin-name>_<server-name>__<tool-name>

Example:

  • Plugin: asana
  • Server: asana
  • Tool: create_task
  • Full name: mcp__plugin_asana_asana__asana_create_task

Using MCP Tools in Commands

Pre-allow specific MCP tools in command frontmatter:

---
allowed-tools: [
  "mcp__plugin_asana_asana__asana_create_task",
  "mcp__plugin_asana_asana__asana_search_tasks"
]
---

Wildcard (use sparingly):

---
allowed-tools: ["mcp__plugin_asana_asana__*"]
---

Best practice: Pre-allow specific tools, not wildcards, for security.

Lifecycle Management

Automatic startup:

  • MCP servers start when plugin enables
  • Connection established before first tool use
  • Restart required for configuration changes

Lifecycle:

  1. Plugin loads
  2. MCP configuration parsed
  3. Server process started (stdio) or connection established (SSE/HTTP/WS)
  4. Tools discovered and registered
  5. Tools available as mcp__plugin_...__...

Viewing servers: Use /mcp command to see all servers including plugin-provided ones.

Authentication Patterns

OAuth (SSE/HTTP)

OAuth handled automatically by Claude Code:

{
  "type": "sse",
  "url": "https://mcp.example.com/sse"
}

User authenticates in browser on first use. No additional configuration needed.

Token-Based (Headers)

Static or environment variable tokens:

{
  "type": "http",
  "url": "https://api.example.com",
  "headers": {
    "Authorization": "Bearer ${API_TOKEN}"
  }
}

Document required environment variables in README.

Environment Variables (stdio)

Pass configuration to MCP server:

{
  "command": "python",
  "args": ["-m", "my_mcp_server"],
  "env": {
    "DATABASE_URL": "${DB_URL}",
    "API_KEY": "${API_KEY}",
    "LOG_LEVEL": "info"
  }
}

Integration Patterns

Pattern 1: Simple Tool Wrapper

Commands use MCP tools with user interaction:

# Command: create-item.md
---
allowed-tools: ["mcp__plugin_name_server__create_item"]
---

Steps:
1. Gather item details from user
2. Use mcp__plugin_name_server__create_item
3. Confirm creation

Use for: Adding validation or preprocessing before MCP calls.

Pattern 2: Autonomous Agent

Agents use MCP tools autonomously:

# Agent: data-analyzer.md

Analysis Process:
1. Query data via mcp__plugin_db_server__query
2. Process and analyze results
3. Generate insights report

Use for: Multi-step MCP workflows without user interaction.

Pattern 3: Multi-Server Plugin

Integrate multiple MCP servers:

{
  "github": {
    "type": "sse",
    "url": "https://mcp.github.com/sse"
  },
  "jira": {
    "type": "sse",
    "url": "https://mcp.jira.com/sse"
  }
}

Use for: Workflows spanning multiple services.

Security Best Practices

Use HTTPS/WSS

Always use secure connections:

✅ "url": "https://mcp.example.com/sse"
❌ "url": "http://mcp.example.com/sse"

Token Management

DO:

  • ✅ Use environment variables for tokens
  • ✅ Document required env vars in README
  • ✅ Let OAuth flow handle authentication

DON'T:

  • ❌ Hardcode tokens in configuration
  • ❌ Commit tokens to git
  • ❌ Share tokens in documentation

Permission Scoping

Pre-allow only necessary MCP tools:

✅ allowed-tools: [
  "mcp__plugin_api_server__read_data",
  "mcp__plugin_api_server__create_item"
]

❌ allowed-tools: ["mcp__plugin_api_server__*"]

Error Handling

Connection Failures

Handle MCP server unavailability:

  • Provide fallback behavior in commands
  • Inform user of connection issues
  • Check server URL and configuration

Tool Call Errors

Handle failed MCP operations:

  • Validate inputs before calling MCP tools
  • Provide clear error messages
  • Check rate limiting and quotas

Configuration Errors

Validate MCP configuration:

  • Test server connectivity during development
  • Validate JSON syntax
  • Check required environment variables

Performance Considerations

Lazy Loading

MCP servers connect on-demand:

  • Not all servers connect at startup
  • First tool use triggers connection
  • Connection pooling managed automatically

Batching

Batch similar requests when possible:

# Good: Single query with filters
tasks = search_tasks(project="X", assignee="me", limit=50)

# Avoid: Many individual queries
for id in task_ids:
    task = get_task(id)

Testing MCP Integration

Local Testing

  1. Configure MCP server in .mcp.json
  2. Install plugin locally (.claude-plugin/)
  3. Run /mcp to verify server appears
  4. Test tool calls in commands
  5. Check claude --debug logs for connection issues

Validation Checklist

  • MCP configuration is valid JSON
  • Server URL is correct and accessible
  • Required environment variables documented
  • Tools appear in /mcp output
  • Authentication works (OAuth or tokens)
  • Tool calls succeed from commands
  • Error cases handled gracefully

Debugging

Enable Debug Logging

claude --debug

Look for:

  • MCP server connection attempts
  • Tool discovery logs
  • Authentication flows
  • Tool call errors

Common Issues

Server not connecting:

  • Check URL is correct
  • Verify server is running (stdio)
  • Check network connectivity
  • Review authentication configuration

Tools not available:

  • Verify server connected successfully
  • Check tool names match exactly
  • Run /mcp to see available tools
  • Restart Claude Code after config changes

Authentication failing:

  • Clear cached auth tokens
  • Re-authenticate
  • Check token scopes and permissions
  • Verify environment variables set

Quick Reference

MCP Server Types

Type Transport Best For Auth
stdio Process Local tools, custom servers Env vars
SSE HTTP Hosted services, cloud APIs OAuth
HTTP REST API backends, token auth Tokens
ws WebSocket Real-time, streaming Tokens

Configuration Checklist

  • Server type specified (stdio/SSE/HTTP/ws)
  • Type-specific fields complete (command or url)
  • Authentication configured
  • Environment variables documented
  • HTTPS/WSS used (not HTTP/WS)
  • $ used for paths

Best Practices

DO:

  • ✅ Use $ for portable paths
  • ✅ Document required environment variables
  • ✅ Use secure connections (HTTPS/WSS)
  • ✅ Pre-allow specific MCP tools in commands
  • ✅ Test MCP integration before publishing
  • ✅ Handle connection and tool errors gracefully

DON'T:

  • ❌ Hardcode absolute paths
  • ❌ Commit credentials to git
  • ❌ Use HTTP instead of HTTPS
  • ❌ Pre-allow all tools with wildcards
  • ❌ Skip error handling
  • ❌ Forget to document setup

Additional Resources

Reference Files

For detailed information, consult:

  • references/server-types.md - Deep dive on each server type
  • references/authentication.md - Authentication patterns and OAuth
  • references/tool-usage.md - Using MCP tools in commands and agents

Example Configurations

Working examples in examples/:

  • stdio-server.json - Local stdio MCP server
  • sse-server.json - Hosted SSE server with OAuth
  • http-server.json - REST API with token auth

External Resources

Implementation Workflow

To add MCP integration to a plugin:

  1. Choose MCP server type (stdio, SSE, HTTP, ws)
  2. Create .mcp.json at plugin root with configuration
  3. Use $ for all file references
  4. Document required environment variables in README
  5. Test locally with /mcp command
  6. Pre-allow MCP tools in relevant commands
  7. Handle authentication (OAuth or tokens)
  8. Test error cases (connection failures, auth errors)
  9. Document MCP integration in plugin README

Focus on stdio for custom/local servers, SSE for hosted services with OAuth.

Files (smart-ralph)
  • examples
    • http-server.json 502 B
      {
        "_comment": "Example HTTP MCP server configuration for REST APIs",
        "rest-api": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}",
            "Content-Type": "application/json",
            "X-API-Version": "2024-01-01"
          }
        },
        "internal-service": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}",
            "X-Service-Name": "claude-plugin"
          }
        }
      }
      
    • sse-server.json 413 B
      {
        "_comment": "Example SSE MCP server configuration for hosted cloud services",
        "asana": {
          "type": "sse",
          "url": "https://mcp.asana.com/sse"
        },
        "github": {
          "type": "sse",
          "url": "https://mcp.github.com/sse"
        },
        "custom-service": {
          "type": "sse",
          "url": "https://mcp.example.com/sse",
          "headers": {
            "X-API-Version": "v1",
            "X-Client-ID": "${CLIENT_ID}"
          }
        }
      }
      
    • stdio-server.json 686 B
      {
        "_comment": "Example stdio MCP server configuration for local file system access",
        "filesystem": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-filesystem", "${CLAUDE_PROJECT_DIR}"],
          "env": {
            "LOG_LEVEL": "info"
          }
        },
        "database": {
          "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server.js",
          "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config/db.json"],
          "env": {
            "DATABASE_URL": "${DATABASE_URL}",
            "DB_POOL_SIZE": "10"
          }
        },
        "custom-tools": {
          "command": "python",
          "args": ["-m", "my_mcp_server", "--port", "8080"],
          "env": {
            "API_KEY": "${CUSTOM_API_KEY}",
            "DEBUG": "false"
          }
        }
      }
      
  • references
    • authentication.md 10 KB
      # MCP Authentication Patterns
      
      Complete guide to authentication methods for MCP servers in Claude Code plugins.
      
      ## Overview
      
      MCP servers support multiple authentication methods depending on the server type and service requirements. Choose the method that best matches your use case and security requirements.
      
      ## OAuth (Automatic)
      
      ### How It Works
      
      Claude Code automatically handles the complete OAuth 2.0 flow for SSE and HTTP servers:
      
      1. User attempts to use MCP tool
      2. Claude Code detects authentication needed
      3. Opens browser for OAuth consent
      4. User authorizes in browser
      5. Tokens stored securely by Claude Code
      6. Automatic token refresh
      
      ### Configuration
      
      ```json
      {
        "service": {
          "type": "sse",
          "url": "https://mcp.example.com/sse"
        }
      }
      ```
      
      No additional auth configuration needed! Claude Code handles everything.
      
      ### Supported Services
      
      **Known OAuth-enabled MCP servers:**
      - Asana: `https://mcp.asana.com/sse`
      - GitHub (when available)
      - Google services (when available)
      - Custom OAuth servers
      
      ### OAuth Scopes
      
      OAuth scopes are determined by the MCP server. Users see required scopes during the consent flow.
      
      **Document required scopes in your README:**
      ```markdown
      ## Authentication
      
      This plugin requires the following Asana permissions:
      - Read tasks and projects
      - Create and update tasks
      - Access workspace data
      ```
      
      ### Token Storage
      
      Tokens are stored securely by Claude Code:
      - Not accessible to plugins
      - Encrypted at rest
      - Automatic refresh
      - Cleared on sign-out
      
      ### Troubleshooting OAuth
      
      **Authentication loop:**
      - Clear cached tokens (sign out and sign in)
      - Check OAuth redirect URLs
      - Verify server OAuth configuration
      
      **Scope issues:**
      - User may need to re-authorize for new scopes
      - Check server documentation for required scopes
      
      **Token expiration:**
      - Claude Code auto-refreshes
      - If refresh fails, prompts re-authentication
      
      ## Token-Based Authentication
      
      ### Bearer Tokens
      
      Most common for HTTP and WebSocket servers.
      
      **Configuration:**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}"
          }
        }
      }
      ```
      
      **Environment variable:**
      ```bash
      export API_TOKEN="your-secret-token-here"
      ```
      
      ### API Keys
      
      Alternative to Bearer tokens, often in custom headers.
      
      **Configuration:**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "X-API-Key": "${API_KEY}",
            "X-API-Secret": "${API_SECRET}"
          }
        }
      }
      ```
      
      ### Custom Headers
      
      Services may use custom authentication headers.
      
      **Configuration:**
      ```json
      {
        "service": {
          "type": "sse",
          "url": "https://mcp.example.com/sse",
          "headers": {
            "X-Auth-Token": "${AUTH_TOKEN}",
            "X-User-ID": "${USER_ID}",
            "X-Tenant-ID": "${TENANT_ID}"
          }
        }
      }
      ```
      
      ### Documenting Token Requirements
      
      Always document in your README:
      
      ```markdown
      ## Setup
      
      ### Required Environment Variables
      
      Set these environment variables before using the plugin:
      
      \`\`\`bash
      export API_TOKEN="your-token-here"
      export API_SECRET="your-secret-here"
      \`\`\`
      
      ### Obtaining Tokens
      
      1. Visit https://api.example.com/tokens
      2. Create a new API token
      3. Copy the token and secret
      4. Set environment variables as shown above
      
      ### Token Permissions
      
      The API token needs the following permissions:
      - Read access to resources
      - Write access for creating items
      - Delete access (optional, for cleanup operations)
      \`\`\`
      ```
      
      ## Environment Variable Authentication (stdio)
      
      ### Passing Credentials to Server
      
      For stdio servers, pass credentials via environment variables:
      
      ```json
      {
        "database": {
          "command": "python",
          "args": ["-m", "mcp_server_db"],
          "env": {
            "DATABASE_URL": "${DATABASE_URL}",
            "DB_USER": "${DB_USER}",
            "DB_PASSWORD": "${DB_PASSWORD}"
          }
        }
      }
      ```
      
      ### User Environment Variables
      
      ```bash
      # User sets these in their shell
      export DATABASE_URL="postgresql://localhost/mydb"
      export DB_USER="myuser"
      export DB_PASSWORD="mypassword"
      ```
      
      ### Documentation Template
      
      ```markdown
      ## Database Configuration
      
      Set these environment variables:
      
      \`\`\`bash
      export DATABASE_URL="postgresql://host:port/database"
      export DB_USER="username"
      export DB_PASSWORD="password"
      \`\`\`
      
      Or create a `.env` file (add to `.gitignore`):
      
      \`\`\`
      DATABASE_URL=postgresql://localhost:5432/mydb
      DB_USER=myuser
      DB_PASSWORD=mypassword
      \`\`\`
      
      Load with: \`source .env\` or \`export $(cat .env | xargs)\`
      \`\`\`
      ```
      
      ## Dynamic Headers
      
      ### Headers Helper Script
      
      For tokens that change or expire, use a helper script:
      
      ```json
      {
        "api": {
          "type": "sse",
          "url": "https://api.example.com",
          "headersHelper": "${CLAUDE_PLUGIN_ROOT}/scripts/get-headers.sh"
        }
      }
      ```
      
      **Script (get-headers.sh):**
      ```bash
      #!/bin/bash
      # Generate dynamic authentication headers
      
      # Fetch fresh token
      TOKEN=$(get-fresh-token-from-somewhere)
      
      # Output JSON headers
      cat <<EOF
      {
        "Authorization": "Bearer $TOKEN",
        "X-Timestamp": "$(date -Iseconds)"
      }
      EOF
      ```
      
      ### Use Cases for Dynamic Headers
      
      - Short-lived tokens that need refresh
      - Tokens with HMAC signatures
      - Time-based authentication
      - Dynamic tenant/workspace selection
      
      ## Security Best Practices
      
      ### DO
      
      ✅ **Use environment variables:**
      ```json
      {
        "headers": {
          "Authorization": "Bearer ${API_TOKEN}"
        }
      }
      ```
      
      ✅ **Document required variables in README**
      
      ✅ **Use HTTPS/WSS always**
      
      ✅ **Implement token rotation**
      
      ✅ **Store tokens securely (env vars, not files)**
      
      ✅ **Let OAuth handle authentication when available**
      
      ### DON'T
      
      ❌ **Hardcode tokens:**
      ```json
      {
        "headers": {
          "Authorization": "Bearer sk-abc123..."  // NEVER!
        }
      }
      ```
      
      ❌ **Commit tokens to git**
      
      ❌ **Share tokens in documentation**
      
      ❌ **Use HTTP instead of HTTPS**
      
      ❌ **Store tokens in plugin files**
      
      ❌ **Log tokens or sensitive headers**
      
      ## Multi-Tenancy Patterns
      
      ### Workspace/Tenant Selection
      
      **Via environment variable:**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}",
            "X-Workspace-ID": "${WORKSPACE_ID}"
          }
        }
      }
      ```
      
      **Via URL:**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://${TENANT_ID}.api.example.com/mcp"
        }
      }
      ```
      
      ### Per-User Configuration
      
      Users set their own workspace:
      
      ```bash
      export WORKSPACE_ID="my-workspace-123"
      export TENANT_ID="my-company"
      ```
      
      ## Authentication Troubleshooting
      
      ### Common Issues
      
      **401 Unauthorized:**
      - Check token is set correctly
      - Verify token hasn't expired
      - Check token has required permissions
      - Ensure header format is correct
      
      **403 Forbidden:**
      - Token valid but lacks permissions
      - Check scope/permissions
      - Verify workspace/tenant ID
      - May need admin approval
      
      **Token not found:**
      ```bash
      # Check environment variable is set
      echo $API_TOKEN
      
      # If empty, set it
      export API_TOKEN="your-token"
      ```
      
      **Token in wrong format:**
      ```json
      // Correct
      "Authorization": "Bearer sk-abc123"
      
      // Wrong
      "Authorization": "sk-abc123"
      ```
      
      ### Debugging Authentication
      
      **Enable debug mode:**
      ```bash
      claude --debug
      ```
      
      Look for:
      - Authentication header values (sanitized)
      - OAuth flow progress
      - Token refresh attempts
      - Authentication errors
      
      **Test authentication separately:**
      ```bash
      # Test HTTP endpoint
      curl -H "Authorization: Bearer $API_TOKEN" \
           https://api.example.com/mcp/health
      
      # Should return 200 OK
      ```
      
      ## Migration Patterns
      
      ### From Hardcoded to Environment Variables
      
      **Before:**
      ```json
      {
        "headers": {
          "Authorization": "Bearer sk-hardcoded-token"
        }
      }
      ```
      
      **After:**
      ```json
      {
        "headers": {
          "Authorization": "Bearer ${API_TOKEN}"
        }
      }
      ```
      
      **Migration steps:**
      1. Add environment variable to plugin README
      2. Update configuration to use ${VAR}
      3. Test with variable set
      4. Remove hardcoded value
      5. Commit changes
      
      ### From Basic Auth to OAuth
      
      **Before:**
      ```json
      {
        "headers": {
          "Authorization": "Basic ${BASE64_CREDENTIALS}"
        }
      }
      ```
      
      **After:**
      ```json
      {
        "type": "sse",
        "url": "https://mcp.example.com/sse"
      }
      ```
      
      **Benefits:**
      - Better security
      - No credential management
      - Automatic token refresh
      - Scoped permissions
      
      ## Advanced Authentication
      
      ### Mutual TLS (mTLS)
      
      Some enterprise services require client certificates.
      
      **Not directly supported in MCP configuration.**
      
      **Workaround:** Wrap in stdio server that handles mTLS:
      
      ```json
      {
        "secure-api": {
          "command": "${CLAUDE_PLUGIN_ROOT}/servers/mtls-wrapper",
          "args": ["--cert", "${CLIENT_CERT}", "--key", "${CLIENT_KEY}"],
          "env": {
            "API_URL": "https://secure.example.com"
          }
        }
      }
      ```
      
      ### JWT Tokens
      
      Generate JWT tokens dynamically with headers helper:
      
      ```bash
      #!/bin/bash
      # generate-jwt.sh
      
      # Generate JWT (using library or API call)
      JWT=$(generate-jwt-token)
      
      echo "{\"Authorization\": \"Bearer $JWT\"}"
      ```
      
      ```json
      {
        "headersHelper": "${CLAUDE_PLUGIN_ROOT}/scripts/generate-jwt.sh"
      }
      ```
      
      ### HMAC Signatures
      
      For APIs requiring request signing:
      
      ```bash
      #!/bin/bash
      # generate-hmac.sh
      
      TIMESTAMP=$(date -Iseconds)
      SIGNATURE=$(echo -n "$TIMESTAMP" | openssl dgst -sha256 -hmac "$SECRET_KEY" | cut -d' ' -f2)
      
      cat <<EOF
      {
        "X-Timestamp": "$TIMESTAMP",
        "X-Signature": "$SIGNATURE",
        "X-API-Key": "$API_KEY"
      }
      EOF
      ```
      
      ## Best Practices Summary
      
      ### For Plugin Developers
      
      1. **Prefer OAuth** when service supports it
      2. **Use environment variables** for tokens
      3. **Document all required variables** in README
      4. **Provide setup instructions** with examples
      5. **Never commit credentials**
      6. **Use HTTPS/WSS only**
      7. **Test authentication thoroughly**
      
      ### For Plugin Users
      
      1. **Set environment variables** before using plugin
      2. **Keep tokens secure** and private
      3. **Rotate tokens regularly**
      4. **Use different tokens** for dev/prod
      5. **Don't commit .env files** to git
      6. **Review OAuth scopes** before authorizing
      
      ## Conclusion
      
      Choose the authentication method that matches your MCP server's requirements:
      - **OAuth** for cloud services (easiest for users)
      - **Bearer tokens** for API services
      - **Environment variables** for stdio servers
      - **Dynamic headers** for complex auth flows
      
      Always prioritize security and provide clear setup documentation for users.
      
    • server-types.md 10.4 KB
      # MCP Server Types: Deep Dive
      
      Complete reference for all MCP server types supported in Claude Code plugins.
      
      ## stdio (Standard Input/Output)
      
      ### Overview
      
      Execute local MCP servers as child processes with communication via stdin/stdout. Best choice for local tools, custom servers, and NPM packages.
      
      ### Configuration
      
      **Basic:**
      ```json
      {
        "my-server": {
          "command": "npx",
          "args": ["-y", "my-mcp-server"]
        }
      }
      ```
      
      **With environment:**
      ```json
      {
        "my-server": {
          "command": "${CLAUDE_PLUGIN_ROOT}/servers/custom-server",
          "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
          "env": {
            "API_KEY": "${MY_API_KEY}",
            "LOG_LEVEL": "debug",
            "DATABASE_URL": "${DB_URL}"
          }
        }
      }
      ```
      
      ### Process Lifecycle
      
      1. **Startup**: Claude Code spawns process with `command` and `args`
      2. **Communication**: JSON-RPC messages via stdin/stdout
      3. **Lifecycle**: Process runs for entire Claude Code session
      4. **Shutdown**: Process terminated when Claude Code exits
      
      ### Use Cases
      
      **NPM Packages:**
      ```json
      {
        "filesystem": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"]
        }
      }
      ```
      
      **Custom Scripts:**
      ```json
      {
        "custom": {
          "command": "${CLAUDE_PLUGIN_ROOT}/servers/my-server.js",
          "args": ["--verbose"]
        }
      }
      ```
      
      **Python Servers:**
      ```json
      {
        "python-server": {
          "command": "python",
          "args": ["-m", "my_mcp_server"],
          "env": {
            "PYTHONUNBUFFERED": "1"
          }
        }
      }
      ```
      
      ### Best Practices
      
      1. **Use absolute paths or ${CLAUDE_PLUGIN_ROOT}**
      2. **Set PYTHONUNBUFFERED for Python servers**
      3. **Pass configuration via args or env, not stdin**
      4. **Handle server crashes gracefully**
      5. **Log to stderr, not stdout (stdout is for MCP protocol)**
      
      ### Troubleshooting
      
      **Server won't start:**
      - Check command exists and is executable
      - Verify file paths are correct
      - Check permissions
      - Review `claude --debug` logs
      
      **Communication fails:**
      - Ensure server uses stdin/stdout correctly
      - Check for stray print/console.log statements
      - Verify JSON-RPC format
      
      ## SSE (Server-Sent Events)
      
      ### Overview
      
      Connect to hosted MCP servers via HTTP with server-sent events for streaming. Best for cloud services and OAuth authentication.
      
      ### Configuration
      
      **Basic:**
      ```json
      {
        "hosted-service": {
          "type": "sse",
          "url": "https://mcp.example.com/sse"
        }
      }
      ```
      
      **With headers:**
      ```json
      {
        "service": {
          "type": "sse",
          "url": "https://mcp.example.com/sse",
          "headers": {
            "X-API-Version": "v1",
            "X-Client-ID": "${CLIENT_ID}"
          }
        }
      }
      ```
      
      ### Connection Lifecycle
      
      1. **Initialization**: HTTP connection established to URL
      2. **Handshake**: MCP protocol negotiation
      3. **Streaming**: Server sends events via SSE
      4. **Requests**: Client sends HTTP POST for tool calls
      5. **Reconnection**: Automatic reconnection on disconnect
      
      ### Authentication
      
      **OAuth (Automatic):**
      ```json
      {
        "asana": {
          "type": "sse",
          "url": "https://mcp.asana.com/sse"
        }
      }
      ```
      
      Claude Code handles OAuth flow:
      1. User prompted to authenticate on first use
      2. Opens browser for OAuth flow
      3. Tokens stored securely
      4. Automatic token refresh
      
      **Custom Headers:**
      ```json
      {
        "service": {
          "type": "sse",
          "url": "https://mcp.example.com/sse",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}"
          }
        }
      }
      ```
      
      ### Use Cases
      
      **Official Services:**
      - Asana: `https://mcp.asana.com/sse`
      - GitHub: `https://mcp.github.com/sse`
      - Other hosted MCP servers
      
      **Custom Hosted Servers:**
      Deploy your own MCP server and expose via HTTPS + SSE.
      
      ### Best Practices
      
      1. **Always use HTTPS, never HTTP**
      2. **Let OAuth handle authentication when available**
      3. **Use environment variables for tokens**
      4. **Handle connection failures gracefully**
      5. **Document OAuth scopes required**
      
      ### Troubleshooting
      
      **Connection refused:**
      - Check URL is correct and accessible
      - Verify HTTPS certificate is valid
      - Check network connectivity
      - Review firewall settings
      
      **OAuth fails:**
      - Clear cached tokens
      - Check OAuth scopes
      - Verify redirect URLs
      - Re-authenticate
      
      ## HTTP (REST API)
      
      ### Overview
      
      Connect to RESTful MCP servers via standard HTTP requests. Best for token-based auth and stateless interactions.
      
      ### Configuration
      
      **Basic:**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://api.example.com/mcp"
        }
      }
      ```
      
      **With authentication:**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}",
            "Content-Type": "application/json",
            "X-API-Version": "2024-01-01"
          }
        }
      }
      ```
      
      ### Request/Response Flow
      
      1. **Tool Discovery**: GET to discover available tools
      2. **Tool Invocation**: POST with tool name and parameters
      3. **Response**: JSON response with results or errors
      4. **Stateless**: Each request independent
      
      ### Authentication
      
      **Token-Based:**
      ```json
      {
        "headers": {
          "Authorization": "Bearer ${API_TOKEN}"
        }
      }
      ```
      
      **API Key:**
      ```json
      {
        "headers": {
          "X-API-Key": "${API_KEY}"
        }
      }
      ```
      
      **Custom Auth:**
      ```json
      {
        "headers": {
          "X-Auth-Token": "${AUTH_TOKEN}",
          "X-User-ID": "${USER_ID}"
        }
      }
      ```
      
      ### Use Cases
      
      - REST API backends
      - Internal services
      - Microservices
      - Serverless functions
      
      ### Best Practices
      
      1. **Use HTTPS for all connections**
      2. **Store tokens in environment variables**
      3. **Implement retry logic for transient failures**
      4. **Handle rate limiting**
      5. **Set appropriate timeouts**
      
      ### Troubleshooting
      
      **HTTP errors:**
      - 401: Check authentication headers
      - 403: Verify permissions
      - 429: Implement rate limiting
      - 500: Check server logs
      
      **Timeout issues:**
      - Increase timeout if needed
      - Check server performance
      - Optimize tool implementations
      
      ## WebSocket (Real-time)
      
      ### Overview
      
      Connect to MCP servers via WebSocket for real-time bidirectional communication. Best for streaming and low-latency applications.
      
      ### Configuration
      
      **Basic:**
      ```json
      {
        "realtime": {
          "type": "ws",
          "url": "wss://mcp.example.com/ws"
        }
      }
      ```
      
      **With authentication:**
      ```json
      {
        "realtime": {
          "type": "ws",
          "url": "wss://mcp.example.com/ws",
          "headers": {
            "Authorization": "Bearer ${TOKEN}",
            "X-Client-ID": "${CLIENT_ID}"
          }
        }
      }
      ```
      
      ### Connection Lifecycle
      
      1. **Handshake**: WebSocket upgrade request
      2. **Connection**: Persistent bidirectional channel
      3. **Messages**: JSON-RPC over WebSocket
      4. **Heartbeat**: Keep-alive messages
      5. **Reconnection**: Automatic on disconnect
      
      ### Use Cases
      
      - Real-time data streaming
      - Live updates and notifications
      - Collaborative editing
      - Low-latency tool calls
      - Push notifications from server
      
      ### Best Practices
      
      1. **Use WSS (secure WebSocket), never WS**
      2. **Implement heartbeat/ping-pong**
      3. **Handle reconnection logic**
      4. **Buffer messages during disconnection**
      5. **Set connection timeouts**
      
      ### Troubleshooting
      
      **Connection drops:**
      - Implement reconnection logic
      - Check network stability
      - Verify server supports WebSocket
      - Review firewall settings
      
      **Message delivery:**
      - Implement message acknowledgment
      - Handle out-of-order messages
      - Buffer during disconnection
      
      ## Comparison Matrix
      
      | Feature | stdio | SSE | HTTP | WebSocket |
      |---------|-------|-----|------|-----------|
      | **Transport** | Process | HTTP/SSE | HTTP | WebSocket |
      | **Direction** | Bidirectional | Server→Client | Request/Response | Bidirectional |
      | **State** | Stateful | Stateful | Stateless | Stateful |
      | **Auth** | Env vars | OAuth/Headers | Headers | Headers |
      | **Use Case** | Local tools | Cloud services | REST APIs | Real-time |
      | **Latency** | Lowest | Medium | Medium | Low |
      | **Setup** | Easy | Medium | Easy | Medium |
      | **Reconnect** | Process respawn | Automatic | N/A | Automatic |
      
      ## Choosing the Right Type
      
      **Use stdio when:**
      - Running local tools or custom servers
      - Need lowest latency
      - Working with file systems or local databases
      - Distributing server with plugin
      
      **Use SSE when:**
      - Connecting to hosted services
      - Need OAuth authentication
      - Using official MCP servers (Asana, GitHub)
      - Want automatic reconnection
      
      **Use HTTP when:**
      - Integrating with REST APIs
      - Need stateless interactions
      - Using token-based auth
      - Simple request/response pattern
      
      **Use WebSocket when:**
      - Need real-time updates
      - Building collaborative features
      - Low-latency critical
      - Bi-directional streaming required
      
      ## Migration Between Types
      
      ### From stdio to SSE
      
      **Before (stdio):**
      ```json
      {
        "local-server": {
          "command": "node",
          "args": ["server.js"]
        }
      }
      ```
      
      **After (SSE - deploy server):**
      ```json
      {
        "hosted-server": {
          "type": "sse",
          "url": "https://mcp.example.com/sse"
        }
      }
      ```
      
      ### From HTTP to WebSocket
      
      **Before (HTTP):**
      ```json
      {
        "api": {
          "type": "http",
          "url": "https://api.example.com/mcp"
        }
      }
      ```
      
      **After (WebSocket):**
      ```json
      {
        "realtime": {
          "type": "ws",
          "url": "wss://api.example.com/ws"
        }
      }
      ```
      
      Benefits: Real-time updates, lower latency, bi-directional communication.
      
      ## Advanced Configuration
      
      ### Multiple Servers
      
      Combine different types:
      
      ```json
      {
        "local-db": {
          "command": "npx",
          "args": ["-y", "mcp-server-sqlite", "./data.db"]
        },
        "cloud-api": {
          "type": "sse",
          "url": "https://mcp.example.com/sse"
        },
        "internal-service": {
          "type": "http",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}"
          }
        }
      }
      ```
      
      ### Conditional Configuration
      
      Use environment variables to switch servers:
      
      ```json
      {
        "api": {
          "type": "http",
          "url": "${API_URL}",
          "headers": {
            "Authorization": "Bearer ${API_TOKEN}"
          }
        }
      }
      ```
      
      Set different values for dev/prod:
      - Dev: `API_URL=http://localhost:8080/mcp`
      - Prod: `API_URL=https://api.production.com/mcp`
      
      ## Security Considerations
      
      ### Stdio Security
      
      - Validate command paths
      - Don't execute user-provided commands
      - Limit environment variable access
      - Restrict file system access
      
      ### Network Security
      
      - Always use HTTPS/WSS
      - Validate SSL certificates
      - Don't skip certificate verification
      - Use secure token storage
      
      ### Token Management
      
      - Never hardcode tokens
      - Use environment variables
      - Rotate tokens regularly
      - Implement token refresh
      - Document scopes required
      
      ## Conclusion
      
      Choose the MCP server type based on your use case:
      - **stdio** for local, custom, or NPM-packaged servers
      - **SSE** for hosted services with OAuth
      - **HTTP** for REST APIs with token auth
      - **WebSocket** for real-time bidirectional communication
      
      Test thoroughly and handle errors gracefully for robust MCP integration.
      
    • tool-usage.md 11.4 KB
      # Using MCP Tools in Commands and Agents
      
      Complete guide to using MCP tools effectively in Claude Code plugin commands and agents.
      
      ## Overview
      
      Once an MCP server is configured, its tools become available with the prefix `mcp__plugin_<plugin-name>_<server-name>__<tool-name>`. Use these tools in commands and agents just like built-in Claude Code tools.
      
      ## Tool Naming Convention
      
      ### Format
      
      ```
      mcp__plugin_<plugin-name>_<server-name>__<tool-name>
      ```
      
      ### Examples
      
      **Asana plugin with asana server:**
      - `mcp__plugin_asana_asana__asana_create_task`
      - `mcp__plugin_asana_asana__asana_search_tasks`
      - `mcp__plugin_asana_asana__asana_get_project`
      
      **Custom plugin with database server:**
      - `mcp__plugin_myplug_database__query`
      - `mcp__plugin_myplug_database__execute`
      - `mcp__plugin_myplug_database__list_tables`
      
      ### Discovering Tool Names
      
      **Use `/mcp` command:**
      ```bash
      /mcp
      ```
      
      This shows:
      - All available MCP servers
      - Tools provided by each server
      - Tool schemas and descriptions
      - Full tool names for use in configuration
      
      ## Using Tools in Commands
      
      ### Pre-Allowing Tools
      
      Specify MCP tools in command frontmatter:
      
      ```markdown
      ---
      description: Create a new Asana task
      allowed-tools: [
        "mcp__plugin_asana_asana__asana_create_task"
      ]
      ---
      
      # Create Task Command
      
      To create a task:
      1. Gather task details from user
      2. Use mcp__plugin_asana_asana__asana_create_task with the details
      3. Confirm creation to user
      ```
      
      ### Multiple Tools
      
      ```markdown
      ---
      allowed-tools: [
        "mcp__plugin_asana_asana__asana_create_task",
        "mcp__plugin_asana_asana__asana_search_tasks",
        "mcp__plugin_asana_asana__asana_get_project"
      ]
      ---
      ```
      
      ### Wildcard (Use Sparingly)
      
      ```markdown
      ---
      allowed-tools: ["mcp__plugin_asana_asana__*"]
      ---
      ```
      
      **Caution:** Only use wildcards if the command truly needs access to all tools from a server.
      
      ### Tool Usage in Command Instructions
      
      **Example command:**
      ```markdown
      ---
      description: Search and create Asana tasks
      allowed-tools: [
        "mcp__plugin_asana_asana__asana_search_tasks",
        "mcp__plugin_asana_asana__asana_create_task"
      ]
      ---
      
      # Asana Task Management
      
      ## Searching Tasks
      
      To search for tasks:
      1. Use mcp__plugin_asana_asana__asana_search_tasks
      2. Provide search filters (assignee, project, etc.)
      3. Display results to user
      
      ## Creating Tasks
      
      To create a task:
      1. Gather task details:
         - Title (required)
         - Description
         - Project
         - Assignee
         - Due date
      2. Use mcp__plugin_asana_asana__asana_create_task
      3. Show confirmation with task link
      ```
      
      ## Using Tools in Agents
      
      ### Agent Configuration
      
      Agents can use MCP tools autonomously without pre-allowing them:
      
      ```markdown
      ---
      name: asana-status-updater
      description: This agent should be used when the user asks to "update Asana status", "generate project report", or "sync Asana tasks"
      color: blue
      ---
      
      ## Role
      
      Autonomous agent for generating Asana project status reports.
      
      ## Process
      
      1. **Query tasks**: Use mcp__plugin_asana_asana__asana_search_tasks to get all tasks
      2. **Analyze progress**: Calculate completion rates and identify blockers
      3. **Generate report**: Create formatted status update
      4. **Update Asana**: Use mcp__plugin_asana_asana__asana_create_comment to post report
      
      ## Available Tools
      
      The agent has access to all Asana MCP tools without pre-approval.
      ```
      
      ### Agent Tool Access
      
      Agents have broader tool access than commands:
      - Can use any tool Claude determines is necessary
      - Don't need pre-allowed lists
      - Should document which tools they typically use
      
      ## Tool Call Patterns
      
      ### Pattern 1: Simple Tool Call
      
      Single tool call with validation:
      
      ```markdown
      Steps:
      1. Validate user provided required fields
      2. Call mcp__plugin_api_server__create_item with validated data
      3. Check for errors
      4. Display confirmation
      ```
      
      ### Pattern 2: Sequential Tools
      
      Chain multiple tool calls:
      
      ```markdown
      Steps:
      1. Search for existing items: mcp__plugin_api_server__search
      2. If not found, create new: mcp__plugin_api_server__create
      3. Add metadata: mcp__plugin_api_server__update_metadata
      4. Return final item ID
      ```
      
      ### Pattern 3: Batch Operations
      
      Multiple calls with same tool:
      
      ```markdown
      Steps:
      1. Get list of items to process
      2. For each item:
         - Call mcp__plugin_api_server__update_item
         - Track success/failure
      3. Report results summary
      ```
      
      ### Pattern 4: Error Handling
      
      Graceful error handling:
      
      ```markdown
      Steps:
      1. Try to call mcp__plugin_api_server__get_data
      2. If error (rate limit, network, etc.):
         - Wait and retry (max 3 attempts)
         - If still failing, inform user
         - Suggest checking configuration
      3. On success, process data
      ```
      
      ## Tool Parameters
      
      ### Understanding Tool Schemas
      
      Each MCP tool has a schema defining its parameters. View with `/mcp`.
      
      **Example schema:**
      ```json
      {
        "name": "asana_create_task",
        "description": "Create a new Asana task",
        "inputSchema": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "Task title"
            },
            "notes": {
              "type": "string",
              "description": "Task description"
            },
            "workspace": {
              "type": "string",
              "description": "Workspace GID"
            }
          },
          "required": ["name", "workspace"]
        }
      }
      ```
      
      ### Calling Tools with Parameters
      
      Claude automatically structures tool calls based on schema:
      
      ```typescript
      // Claude generates this internally
      {
        toolName: "mcp__plugin_asana_asana__asana_create_task",
        input: {
          name: "Review PR #123",
          notes: "Code review for new feature",
          workspace: "12345",
          assignee: "67890",
          due_on: "2025-01-15"
        }
      }
      ```
      
      ### Parameter Validation
      
      **In commands, validate before calling:**
      
      ```markdown
      Steps:
      1. Check required parameters:
         - Title is not empty
         - Workspace ID is provided
         - Due date is valid format (YYYY-MM-DD)
      2. If validation fails, ask user to provide missing data
      3. If validation passes, call MCP tool
      4. Handle tool errors gracefully
      ```
      
      ## Response Handling
      
      ### Success Responses
      
      ```markdown
      Steps:
      1. Call MCP tool
      2. On success:
         - Extract relevant data from response
         - Format for user display
         - Provide confirmation message
         - Include relevant links or IDs
      ```
      
      ### Error Responses
      
      ```markdown
      Steps:
      1. Call MCP tool
      2. On error:
         - Check error type (auth, rate limit, validation, etc.)
         - Provide helpful error message
         - Suggest remediation steps
         - Don't expose internal error details to user
      ```
      
      ### Partial Success
      
      ```markdown
      Steps:
      1. Batch operation with multiple MCP calls
      2. Track successes and failures separately
      3. Report summary:
         - "Successfully processed 8 of 10 items"
         - "Failed items: [item1, item2] due to [reason]"
         - Suggest retry or manual intervention
      ```
      
      ## Performance Optimization
      
      ### Batching Requests
      
      **Good: Single query with filters**
      ```markdown
      Steps:
      1. Call mcp__plugin_api_server__search with filters:
         - project_id: "123"
         - status: "active"
         - limit: 100
      2. Process all results
      ```
      
      **Avoid: Many individual queries**
      ```markdown
      Steps:
      1. For each item ID:
         - Call mcp__plugin_api_server__get_item
         - Process item
      ```
      
      ### Caching Results
      
      ```markdown
      Steps:
      1. Call expensive MCP operation: mcp__plugin_api_server__analyze
      2. Store results in variable for reuse
      3. Use cached results for subsequent operations
      4. Only re-fetch if data changes
      ```
      
      ### Parallel Tool Calls
      
      When tools don't depend on each other, call in parallel:
      
      ```markdown
      Steps:
      1. Make parallel calls (Claude handles this automatically):
         - mcp__plugin_api_server__get_project
         - mcp__plugin_api_server__get_users
         - mcp__plugin_api_server__get_tags
      2. Wait for all to complete
      3. Combine results
      ```
      
      ## Integration Best Practices
      
      ### User Experience
      
      **Provide feedback:**
      ```markdown
      Steps:
      1. Inform user: "Searching Asana tasks..."
      2. Call mcp__plugin_asana_asana__asana_search_tasks
      3. Show progress: "Found 15 tasks, analyzing..."
      4. Present results
      ```
      
      **Handle long operations:**
      ```markdown
      Steps:
      1. Warn user: "This may take a minute..."
      2. Break into smaller steps with updates
      3. Show incremental progress
      4. Final summary when complete
      ```
      
      ### Error Messages
      
      **Good error messages:**
      ```
      ❌ "Could not create task. Please check:
         1. You're logged into Asana
         2. You have access to workspace 'Engineering'
         3. The project 'Q1 Goals' exists"
      ```
      
      **Poor error messages:**
      ```
      ❌ "Error: MCP tool returned 403"
      ```
      
      ### Documentation
      
      **Document MCP tool usage in command:**
      ```markdown
      ## MCP Tools Used
      
      This command uses the following Asana MCP tools:
      - **asana_search_tasks**: Search for tasks matching criteria
      - **asana_create_task**: Create new task with details
      - **asana_update_task**: Update existing task properties
      
      Ensure you're authenticated to Asana before running this command.
      ```
      
      ## Testing Tool Usage
      
      ### Local Testing
      
      1. **Configure MCP server** in `.mcp.json`
      2. **Install plugin locally** in `.claude-plugin/`
      3. **Verify tools available** with `/mcp`
      4. **Test command** that uses tools
      5. **Check debug output**: `claude --debug`
      
      ### Test Scenarios
      
      **Test successful calls:**
      ```markdown
      Steps:
      1. Create test data in external service
      2. Run command that queries this data
      3. Verify correct results returned
      ```
      
      **Test error cases:**
      ```markdown
      Steps:
      1. Test with missing authentication
      2. Test with invalid parameters
      3. Test with non-existent resources
      4. Verify graceful error handling
      ```
      
      **Test edge cases:**
      ```markdown
      Steps:
      1. Test with empty results
      2. Test with maximum results
      3. Test with special characters
      4. Test with concurrent access
      ```
      
      ## Common Patterns
      
      ### Pattern: CRUD Operations
      
      ```markdown
      ---
      allowed-tools: [
        "mcp__plugin_api_server__create_item",
        "mcp__plugin_api_server__read_item",
        "mcp__plugin_api_server__update_item",
        "mcp__plugin_api_server__delete_item"
      ]
      ---
      
      # Item Management
      
      ## Create
      Use create_item with required fields...
      
      ## Read
      Use read_item with item ID...
      
      ## Update
      Use update_item with item ID and changes...
      
      ## Delete
      Use delete_item with item ID (ask for confirmation first)...
      ```
      
      ### Pattern: Search and Process
      
      ```markdown
      Steps:
      1. **Search**: mcp__plugin_api_server__search with filters
      2. **Filter**: Apply additional local filtering if needed
      3. **Transform**: Process each result
      4. **Present**: Format and display to user
      ```
      
      ### Pattern: Multi-Step Workflow
      
      ```markdown
      Steps:
      1. **Setup**: Gather all required information
      2. **Validate**: Check data completeness
      3. **Execute**: Chain of MCP tool calls:
         - Create parent resource
         - Create child resources
         - Link resources together
         - Add metadata
      4. **Verify**: Confirm all steps succeeded
      5. **Report**: Provide summary to user
      ```
      
      ## Troubleshooting
      
      ### Tools Not Available
      
      **Check:**
      - MCP server configured correctly
      - Server connected (check `/mcp`)
      - Tool names match exactly (case-sensitive)
      - Restart Claude Code after config changes
      
      ### Tool Calls Failing
      
      **Check:**
      - Authentication is valid
      - Parameters match tool schema
      - Required parameters provided
      - Check `claude --debug` logs
      
      ### Performance Issues
      
      **Check:**
      - Batching queries instead of individual calls
      - Caching results when appropriate
      - Not making unnecessary tool calls
      - Parallel calls when possible
      
      ## Conclusion
      
      Effective MCP tool usage requires:
      1. **Understanding tool schemas** via `/mcp`
      2. **Pre-allowing tools** in commands appropriately
      3. **Handling errors gracefully**
      4. **Optimizing performance** with batching and caching
      5. **Providing good UX** with feedback and clear errors
      6. **Testing thoroughly** before deployment
      
      Follow these patterns for robust MCP tool integration in your plugin commands and agents.
      
  • SKILL.md 12.2 KB
    ---
    name: MCP Integration
    description: This skill should be used when the user asks to "add MCP server", "integrate MCP", "configure MCP in plugin", "use .mcp.json", "set up Model Context Protocol", "connect external service", mentions "${CLAUDE_PLUGIN_ROOT} with MCP", or discusses MCP server types (SSE, stdio, HTTP, WebSocket). Provides comprehensive guidance for integrating Model Context Protocol servers into Claude Code plugins for external tool and service integration.
    version: 0.1.0
    ---
    
    # MCP Integration for Claude Code Plugins
    
    ## Overview
    
    Model Context Protocol (MCP) enables Claude Code plugins to integrate with external services and APIs by providing structured tool access. Use MCP integration to expose external service capabilities as tools within Claude Code.
    
    **Key capabilities:**
    - Connect to external services (databases, APIs, file systems)
    - Provide 10+ related tools from a single service
    - Handle OAuth and complex authentication flows
    - Bundle MCP servers with plugins for automatic setup
    
    ## MCP Server Configuration Methods
    
    Plugins can bundle MCP servers in two ways:
    
    ### Method 1: Dedicated .mcp.json (Recommended)
    
    Create `.mcp.json` at plugin root:
    
    ```json
    {
      "database-tools": {
        "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
        "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
        "env": {
          "DB_URL": "${DB_URL}"
        }
      }
    }
    ```
    
    **Benefits:**
    - Clear separation of concerns
    - Easier to maintain
    - Better for multiple servers
    
    ### Method 2: Inline in plugin.json
    
    Add `mcpServers` field to plugin.json:
    
    ```json
    {
      "name": "my-plugin",
      "version": "1.0.0",
      "mcpServers": {
        "plugin-api": {
          "command": "${CLAUDE_PLUGIN_ROOT}/servers/api-server",
          "args": ["--port", "8080"]
        }
      }
    }
    ```
    
    **Benefits:**
    - Single configuration file
    - Good for simple single-server plugins
    
    ## MCP Server Types
    
    ### stdio (Local Process)
    
    Execute local MCP servers as child processes. Best for local tools and custom servers.
    
    **Configuration:**
    ```json
    {
      "filesystem": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
        "env": {
          "LOG_LEVEL": "debug"
        }
      }
    }
    ```
    
    **Use cases:**
    - File system access
    - Local database connections
    - Custom MCP servers
    - NPM-packaged MCP servers
    
    **Process management:**
    - Claude Code spawns and manages the process
    - Communicates via stdin/stdout
    - Terminates when Claude Code exits
    
    ### SSE (Server-Sent Events)
    
    Connect to hosted MCP servers with OAuth support. Best for cloud services.
    
    **Configuration:**
    ```json
    {
      "asana": {
        "type": "sse",
        "url": "https://mcp.asana.com/sse"
      }
    }
    ```
    
    **Use cases:**
    - Official hosted MCP servers (Asana, GitHub, etc.)
    - Cloud services with MCP endpoints
    - OAuth-based authentication
    - No local installation needed
    
    **Authentication:**
    - OAuth flows handled automatically
    - User prompted on first use
    - Tokens managed by Claude Code
    
    ### HTTP (REST API)
    
    Connect to RESTful MCP servers with token authentication.
    
    **Configuration:**
    ```json
    {
      "api-service": {
        "type": "http",
        "url": "https://api.example.com/mcp",
        "headers": {
          "Authorization": "Bearer ${API_TOKEN}",
          "X-Custom-Header": "value"
        }
      }
    }
    ```
    
    **Use cases:**
    - REST API-based MCP servers
    - Token-based authentication
    - Custom API backends
    - Stateless interactions
    
    ### WebSocket (Real-time)
    
    Connect to WebSocket MCP servers for real-time bidirectional communication.
    
    **Configuration:**
    ```json
    {
      "realtime-service": {
        "type": "ws",
        "url": "wss://mcp.example.com/ws",
        "headers": {
          "Authorization": "Bearer ${TOKEN}"
        }
      }
    }
    ```
    
    **Use cases:**
    - Real-time data streaming
    - Persistent connections
    - Push notifications from server
    - Low-latency requirements
    
    ## Environment Variable Expansion
    
    All MCP configurations support environment variable substitution:
    
    **${CLAUDE_PLUGIN_ROOT}** - Plugin directory (always use for portability):
    ```json
    {
      "command": "${CLAUDE_PLUGIN_ROOT}/servers/my-server"
    }
    ```
    
    **User environment variables** - From user's shell:
    ```json
    {
      "env": {
        "API_KEY": "${MY_API_KEY}",
        "DATABASE_URL": "${DB_URL}"
      }
    }
    ```
    
    **Best practice:** Document all required environment variables in plugin README.
    
    ## MCP Tool Naming
    
    When MCP servers provide tools, they're automatically prefixed:
    
    **Format:** `mcp__plugin_<plugin-name>_<server-name>__<tool-name>`
    
    **Example:**
    - Plugin: `asana`
    - Server: `asana`
    - Tool: `create_task`
    - **Full name:** `mcp__plugin_asana_asana__asana_create_task`
    
    ### Using MCP Tools in Commands
    
    Pre-allow specific MCP tools in command frontmatter:
    
    ```markdown
    ---
    allowed-tools: [
      "mcp__plugin_asana_asana__asana_create_task",
      "mcp__plugin_asana_asana__asana_search_tasks"
    ]
    ---
    ```
    
    **Wildcard (use sparingly):**
    ```markdown
    ---
    allowed-tools: ["mcp__plugin_asana_asana__*"]
    ---
    ```
    
    **Best practice:** Pre-allow specific tools, not wildcards, for security.
    
    ## Lifecycle Management
    
    **Automatic startup:**
    - MCP servers start when plugin enables
    - Connection established before first tool use
    - Restart required for configuration changes
    
    **Lifecycle:**
    1. Plugin loads
    2. MCP configuration parsed
    3. Server process started (stdio) or connection established (SSE/HTTP/WS)
    4. Tools discovered and registered
    5. Tools available as `mcp__plugin_...__...`
    
    **Viewing servers:**
    Use `/mcp` command to see all servers including plugin-provided ones.
    
    ## Authentication Patterns
    
    ### OAuth (SSE/HTTP)
    
    OAuth handled automatically by Claude Code:
    
    ```json
    {
      "type": "sse",
      "url": "https://mcp.example.com/sse"
    }
    ```
    
    User authenticates in browser on first use. No additional configuration needed.
    
    ### Token-Based (Headers)
    
    Static or environment variable tokens:
    
    ```json
    {
      "type": "http",
      "url": "https://api.example.com",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}"
      }
    }
    ```
    
    Document required environment variables in README.
    
    ### Environment Variables (stdio)
    
    Pass configuration to MCP server:
    
    ```json
    {
      "command": "python",
      "args": ["-m", "my_mcp_server"],
      "env": {
        "DATABASE_URL": "${DB_URL}",
        "API_KEY": "${API_KEY}",
        "LOG_LEVEL": "info"
      }
    }
    ```
    
    ## Integration Patterns
    
    ### Pattern 1: Simple Tool Wrapper
    
    Commands use MCP tools with user interaction:
    
    ```markdown
    # Command: create-item.md
    ---
    allowed-tools: ["mcp__plugin_name_server__create_item"]
    ---
    
    Steps:
    1. Gather item details from user
    2. Use mcp__plugin_name_server__create_item
    3. Confirm creation
    ```
    
    **Use for:** Adding validation or preprocessing before MCP calls.
    
    ### Pattern 2: Autonomous Agent
    
    Agents use MCP tools autonomously:
    
    ```markdown
    # Agent: data-analyzer.md
    
    Analysis Process:
    1. Query data via mcp__plugin_db_server__query
    2. Process and analyze results
    3. Generate insights report
    ```
    
    **Use for:** Multi-step MCP workflows without user interaction.
    
    ### Pattern 3: Multi-Server Plugin
    
    Integrate multiple MCP servers:
    
    ```json
    {
      "github": {
        "type": "sse",
        "url": "https://mcp.github.com/sse"
      },
      "jira": {
        "type": "sse",
        "url": "https://mcp.jira.com/sse"
      }
    }
    ```
    
    **Use for:** Workflows spanning multiple services.
    
    ## Security Best Practices
    
    ### Use HTTPS/WSS
    
    Always use secure connections:
    
    ```json
    ✅ "url": "https://mcp.example.com/sse"
    ❌ "url": "http://mcp.example.com/sse"
    ```
    
    ### Token Management
    
    **DO:**
    - ✅ Use environment variables for tokens
    - ✅ Document required env vars in README
    - ✅ Let OAuth flow handle authentication
    
    **DON'T:**
    - ❌ Hardcode tokens in configuration
    - ❌ Commit tokens to git
    - ❌ Share tokens in documentation
    
    ### Permission Scoping
    
    Pre-allow only necessary MCP tools:
    
    ```markdown
    ✅ allowed-tools: [
      "mcp__plugin_api_server__read_data",
      "mcp__plugin_api_server__create_item"
    ]
    
    ❌ allowed-tools: ["mcp__plugin_api_server__*"]
    ```
    
    ## Error Handling
    
    ### Connection Failures
    
    Handle MCP server unavailability:
    - Provide fallback behavior in commands
    - Inform user of connection issues
    - Check server URL and configuration
    
    ### Tool Call Errors
    
    Handle failed MCP operations:
    - Validate inputs before calling MCP tools
    - Provide clear error messages
    - Check rate limiting and quotas
    
    ### Configuration Errors
    
    Validate MCP configuration:
    - Test server connectivity during development
    - Validate JSON syntax
    - Check required environment variables
    
    ## Performance Considerations
    
    ### Lazy Loading
    
    MCP servers connect on-demand:
    - Not all servers connect at startup
    - First tool use triggers connection
    - Connection pooling managed automatically
    
    ### Batching
    
    Batch similar requests when possible:
    
    ```
    # Good: Single query with filters
    tasks = search_tasks(project="X", assignee="me", limit=50)
    
    # Avoid: Many individual queries
    for id in task_ids:
        task = get_task(id)
    ```
    
    ## Testing MCP Integration
    
    ### Local Testing
    
    1. Configure MCP server in `.mcp.json`
    2. Install plugin locally (`.claude-plugin/`)
    3. Run `/mcp` to verify server appears
    4. Test tool calls in commands
    5. Check `claude --debug` logs for connection issues
    
    ### Validation Checklist
    
    - [ ] MCP configuration is valid JSON
    - [ ] Server URL is correct and accessible
    - [ ] Required environment variables documented
    - [ ] Tools appear in `/mcp` output
    - [ ] Authentication works (OAuth or tokens)
    - [ ] Tool calls succeed from commands
    - [ ] Error cases handled gracefully
    
    ## Debugging
    
    ### Enable Debug Logging
    
    ```bash
    claude --debug
    ```
    
    Look for:
    - MCP server connection attempts
    - Tool discovery logs
    - Authentication flows
    - Tool call errors
    
    ### Common Issues
    
    **Server not connecting:**
    - Check URL is correct
    - Verify server is running (stdio)
    - Check network connectivity
    - Review authentication configuration
    
    **Tools not available:**
    - Verify server connected successfully
    - Check tool names match exactly
    - Run `/mcp` to see available tools
    - Restart Claude Code after config changes
    
    **Authentication failing:**
    - Clear cached auth tokens
    - Re-authenticate
    - Check token scopes and permissions
    - Verify environment variables set
    
    ## Quick Reference
    
    ### MCP Server Types
    
    | Type | Transport | Best For | Auth |
    |------|-----------|----------|------|
    | stdio | Process | Local tools, custom servers | Env vars |
    | SSE | HTTP | Hosted services, cloud APIs | OAuth |
    | HTTP | REST | API backends, token auth | Tokens |
    | ws | WebSocket | Real-time, streaming | Tokens |
    
    ### Configuration Checklist
    
    - [ ] Server type specified (stdio/SSE/HTTP/ws)
    - [ ] Type-specific fields complete (command or url)
    - [ ] Authentication configured
    - [ ] Environment variables documented
    - [ ] HTTPS/WSS used (not HTTP/WS)
    - [ ] ${CLAUDE_PLUGIN_ROOT} used for paths
    
    ### Best Practices
    
    **DO:**
    - ✅ Use ${CLAUDE_PLUGIN_ROOT} for portable paths
    - ✅ Document required environment variables
    - ✅ Use secure connections (HTTPS/WSS)
    - ✅ Pre-allow specific MCP tools in commands
    - ✅ Test MCP integration before publishing
    - ✅ Handle connection and tool errors gracefully
    
    **DON'T:**
    - ❌ Hardcode absolute paths
    - ❌ Commit credentials to git
    - ❌ Use HTTP instead of HTTPS
    - ❌ Pre-allow all tools with wildcards
    - ❌ Skip error handling
    - ❌ Forget to document setup
    
    ## Additional Resources
    
    ### Reference Files
    
    For detailed information, consult:
    
    - **`references/server-types.md`** - Deep dive on each server type
    - **`references/authentication.md`** - Authentication patterns and OAuth
    - **`references/tool-usage.md`** - Using MCP tools in commands and agents
    
    ### Example Configurations
    
    Working examples in `examples/`:
    
    - **`stdio-server.json`** - Local stdio MCP server
    - **`sse-server.json`** - Hosted SSE server with OAuth
    - **`http-server.json`** - REST API with token auth
    
    ### External Resources
    
    - **Official MCP Docs**: https://modelcontextprotocol.io/
    - **Claude Code MCP Docs**: https://docs.claude.com/en/docs/claude-code/mcp
    - **MCP SDK**: @modelcontextprotocol/sdk
    - **Testing**: Use `claude --debug` and `/mcp` command
    
    ## Implementation Workflow
    
    To add MCP integration to a plugin:
    
    1. Choose MCP server type (stdio, SSE, HTTP, ws)
    2. Create `.mcp.json` at plugin root with configuration
    3. Use ${CLAUDE_PLUGIN_ROOT} for all file references
    4. Document required environment variables in README
    5. Test locally with `/mcp` command
    6. Pre-allow MCP tools in relevant commands
    7. Handle authentication (OAuth or tokens)
    8. Test error cases (connection failures, auth errors)
    9. Document MCP integration in plugin README
    
    Focus on stdio for custom/local servers, SSE for hosted services with OAuth.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related