Skill Library

expert Automation Integration

MCP Server Development

Create high-quality Model Context Protocol (MCP) servers to enable AI agents to interact with external APIs and services. Follow best practices for tool design, authentication, error handling, and testing.

When to Use This Skill

  • Connecting AI agents to external APIs (GitHub, Slack, databases)
  • Building custom tool integrations for Claude Code
  • Creating reusable service connectors
  • Enabling AI access to proprietary systems
  • Building agentic workflows with external dependencies

How to use this skill

1. Copy the AI Core Logic from the Instructions tab below.

2. Paste it into your AI's System Instructions or as your first message.

3. Provide your raw data or requirements as requested by the AI.

#mcp#api#integration#typescript#python#tools#agents

System Directives

## Curation Note The Model Context Protocol (MCP) has become the standard for extending AI agent capabilities beyond chat. This skill gained massive adoption after Anthropic open-sourced the specification. MCP servers allow Claude and other AI agents to interact with databases, APIs, file systems, and external services in a structured way. The four-phase approach (Research, Implementation, Review, Evaluation) has proven effective for producing production-quality integrations. ## Development Phases ### Phase 1: Deep Research and Planning #### Understanding Modern MCP Design **API Coverage vs. Workflow Tools:** Balance comprehensive API endpoint coverage with specialized workflow tools. Workflow tools can be more convenient for specific tasks, while comprehensive coverage gives agents flexibility to compose operations. **Tool Naming and Discoverability:** Clear, descriptive tool names help agents find the right tools quickly: ``` github_create_issue github_list_repos github_close_pr makeIssue repos closeit ``` **Context Management:** Agents benefit from concise tool descriptions and the ability to filter/paginate results. Design tools that return focused, relevant data. **Actionable Error Messages:** Error messages should guide agents toward solutions: ```python raise Exception("API error") raise Exception( "GitHub API rate limited. Retry after 60 seconds. " "Consider using github_get_rate_limit to check status first." ) ``` #### Study MCP Protocol Documentation Key concepts to understand: - Transport mechanisms (streamable HTTP, stdio) - Tool, resource, and prompt definitions - Input/output schemas ### Phase 2: Implementation #### Project Structure (TypeScript) ``` my-mcp-server/ ├── src/ │ ├── index.ts # Main entry point │ ├── server.ts # MCP server setup │ ├── tools/ # Tool implementations │ │ ├── index.ts │ │ └── github.ts │ ├── utils/ │ │ ├── auth.ts # Authentication helpers │ │ └── api.ts # API client │ └── types.ts # TypeScript types ├── package.json ├── tsconfig.json └── README.md ``` #### Basic Server Setup (TypeScript) ```typescript import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; const server = new Server( { name: 'my-mcp-server', version: '1.0.0' }, { capabilities: { tools: {} } } ); // Register tools server.setRequestHandler('tools/list', async () => ({ tools: [ { name: 'github_list_repos', description: 'List repositories for the authenticated user', inputSchema: { type: 'object', properties: { per_page: { type: 'number', default: 30 }, page: { type: 'number', default: 1 } } } } ] })); server.setRequestHandler('tools/call', async (request) => { const { name, arguments: args } = request.params; switch (name) { case 'github_list_repos': return await listRepos(args); default: throw new Error(`Unknown tool: ${name}`); } }); // Start server const transport = new StdioServerTransport(); await server.connect(transport); ``` #### Tool Implementation Best Practices ```typescript // Input validation with Zod import { z } from 'zod'; const CreateIssueSchema = z.object({ owner: z.string().describe('Repository owner'), repo: z.string().describe('Repository name'), title: z.string().describe('Issue title'), body: z.string().optional().describe('Issue body (markdown)') }); async function createIssue(args: unknown) { const validated = CreateIssueSchema.parse(args); try { const response = await githubClient.post(`/repos/${validated.owner}/${validated.repo}/issues`, { title: validated.title, body: validated.body }); return { content: [ { type: 'text', text: `Created issue #${response.data.number}: ${response.data.html_url}` } ], structuredContent: response.data }; } catch (error) { if (error.response?.status === 404) { throw new Error( `Repository ${validated.owner}/${validated.repo} not found. ` + `Check the owner and repo names, and verify you have access.` ); } throw error; } } ``` #### Tool Annotations ```typescript { name: "github_delete_repo", description: "Delete a repository (DESTRUCTIVE)", annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false }, inputSchema: { /* ... */ } } ``` ### Phase 3: Review and Test #### Testing Patterns ```typescript // Unit tests for tool logic describe('github_create_issue', () => { it('creates an issue with required fields', async () => { const result = await createIssue({ owner: 'test-owner', repo: 'test-repo', title: 'Test Issue' }); expect(result.content[0].text).toContain('Created issue #'); }); it('returns actionable error for missing repo', async () => { await expect( createIssue({ owner: 'test-owner', repo: 'nonexistent', title: 'Test' }) ).rejects.toThrow(/not found/); }); }); ``` ### Phase 4: Create Evaluations Test with realistic agent workflows: ``` Evaluation: "Create a GitHub issue for a bug report" Steps: 1. Agent calls github_list_repos to find the target repo 2. Agent calls github_create_issue with appropriate details 3. Verify issue was created with correct content Success Criteria: - Issue created within 3 tool calls - Issue contains bug report template structure - No authentication errors ``` ## Configuration and Deployment ### Claude Code Configuration Add to `~/.config/claude-code/mcp_servers.json`: ```json { "mcpServers": { "my-server": { "command": "node", "args": ["/path/to/my-mcp-server/dist/index.js"], "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" } } } } ``` ### Environment Variables ```typescript // Secure credential handling function getConfig() { const token = process.env.GITHUB_TOKEN; if (!token) { throw new Error( 'GITHUB_TOKEN not set. Create a token at ' + 'https://github.com/settings/tokens and set it in your environment.' ); } return { token }; } ``` ## Best Practices 1. **Comprehensive tool descriptions** - Help agents understand when to use each tool 2. **Validate inputs strictly** - Fail fast with clear error messages 3. **Return structured data** - Enable agents to process results programmatically 4. **Paginate large responses** - Don't overwhelm context windows 5. **Handle rate limits gracefully** - Include retry guidance in errors 6. **Test with real agents** - Unit tests aren't enough 7. **Log for debugging** - Include request IDs and timestamps ## Related Resources - [MCP Specification](https://modelcontextprotocol.io/) - [TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) - [Python SDK](https://github.com/modelcontextprotocol/python-sdk) - [Example MCP Servers](https://github.com/modelcontextprotocol/servers)

Procedural Integration

This skill is formatted as a set of persistent system instructions. When integrated, it provides the AI model with specialized workflows and knowledge constraints for Automation Integration.

Skill Actions


Model Compatibility
🤖 Claude Opus🤖 Gemini 2.5 Pro
Code Execution: Required
MCP Tools: Required
Footprint ~1,947 tokens