Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:55:59 +08:00
commit 7449ea6e8b
60 changed files with 21848 additions and 0 deletions

View File

@@ -0,0 +1,554 @@
---
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.

View File

@@ -0,0 +1,20 @@
{
"_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"
}
}
}

View File

@@ -0,0 +1,19 @@
{
"_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}"
}
}
}

View File

@@ -0,0 +1,26 @@
{
"_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"
}
}
}

View File

@@ -0,0 +1,549 @@
# 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.

View File

@@ -0,0 +1,536 @@
# 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.

View File

@@ -0,0 +1,538 @@
# 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"
model: inherit
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.