Initial commit
This commit is contained in:
553
skills/mcp-integration/SKILL.md
Normal file
553
skills/mcp-integration/SKILL.md
Normal file
@@ -0,0 +1,553 @@
|
||||
---
|
||||
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.
|
||||
---
|
||||
|
||||
# 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.
|
||||
20
skills/mcp-integration/examples/http-server.json
Normal file
20
skills/mcp-integration/examples/http-server.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
19
skills/mcp-integration/examples/sse-server.json
Normal file
19
skills/mcp-integration/examples/sse-server.json
Normal 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}"
|
||||
}
|
||||
}
|
||||
}
|
||||
26
skills/mcp-integration/examples/stdio-server.json
Normal file
26
skills/mcp-integration/examples/stdio-server.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
549
skills/mcp-integration/references/authentication.md
Normal file
549
skills/mcp-integration/references/authentication.md
Normal 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.
|
||||
536
skills/mcp-integration/references/server-types.md
Normal file
536
skills/mcp-integration/references/server-types.md
Normal 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.
|
||||
538
skills/mcp-integration/references/tool-usage.md
Normal file
538
skills/mcp-integration/references/tool-usage.md
Normal 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.
|
||||
Reference in New Issue
Block a user