├── requirements.txt ├── .env.example ├── claude_desktop_config.json ├── package.json ├── tsconfig.json ├── .gitignore ├── config └── claude_desktop_config.json ├── src ├── index.ts └── claude_api_server.py └── README.md /requirements.txt: -------------------------------------------------------------------------------- 1 | mcp>=1.2.0 2 | anthropic>=0.10.0 3 | python-dotenv>=1.0.0 4 | json5>=0.9.14 -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Copy this file to .env and fill in your values 2 | ANTHROPIC_API_KEY=your_api_key_here -------------------------------------------------------------------------------- /claude_desktop_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "claude-api": { 4 | "command": "node", 5 | "args": ["build/index.js"], 6 | "env": { 7 | "ANTHROPIC_API_KEY": "your-api-key-here" 8 | } 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "claude-api-mcp", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "build": "tsc", 7 | "start": "node build/index.js", 8 | "dev": "mcp dev src/index.ts" 9 | }, 10 | "dependencies": { 11 | "@modelcontextprotocol/sdk": "latest", 12 | "@anthropic-ai/sdk": "latest", 13 | "typescript": "latest" 14 | } 15 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules", "test"] 15 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Environment variables 2 | .env 3 | 4 | # Python 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | *.so 9 | .Python 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | downloads/ 14 | eggs/ 15 | .eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | wheels/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # Virtual Environment 27 | venv/ 28 | env/ 29 | ENV/ 30 | 31 | # IDE 32 | .idea/ 33 | .vscode/ 34 | *.swp 35 | *.swo 36 | 37 | # OS 38 | .DS_Store 39 | Thumbs.db -------------------------------------------------------------------------------- /config/claude_desktop_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "github": { 4 | "command": "npx", 5 | "args": ["-y", "@modelcontextprotocol/server-github"], 6 | "env": { 7 | "GITHUB_PERSONAL_ACCESS_TOKEN": "" 8 | } 9 | }, 10 | "claude-api": { 11 | "command": "python", 12 | "args": ["./src/claude_api_server.py"], 13 | "env": { 14 | "ANTHROPIC_API_KEY": "" 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import Anthropic from "@anthropic-ai/sdk"; 2 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 3 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 4 | import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; 5 | 6 | const log = (message: string) => { 7 | console.error(`[DEBUG] ${message}`); 8 | }; 9 | 10 | const client = new Anthropic({ 11 | apiKey: process.env.ANTHROPIC_API_KEY 12 | }); 13 | 14 | const server = new Server( 15 | { 16 | name: "claude-api", 17 | version: "1.0.0", 18 | }, 19 | { 20 | capabilities: { 21 | tools: {} 22 | } 23 | } 24 | ); 25 | 26 | server.setRequestHandler(ListToolsRequestSchema, async () => { 27 | log("Listing tools..."); 28 | return { 29 | tools: [ 30 | { 31 | name: "send-message", 32 | description: "Send a message to Claude", 33 | inputSchema: { 34 | type: "object", 35 | properties: { 36 | message: { 37 | type: "string", 38 | description: "Message to send to Claude" 39 | } 40 | }, 41 | required: ["message"] 42 | } 43 | } 44 | ] 45 | }; 46 | }); 47 | 48 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 49 | log(`Executing tool: ${request.params.name}`); 50 | 51 | if (request.params.name === "send-message" && request.params.arguments?.message) { 52 | try { 53 | const msg = await client.messages.create({ 54 | model: "claude-3-opus-20240229", 55 | max_tokens: 1024, 56 | messages: [ 57 | { 58 | role: "user", 59 | content: String(request.params.arguments.message) 60 | } 61 | ] 62 | }); 63 | 64 | const responseText = msg.content[0].type === 'text' ? msg.content[0].text : 'No text response available'; 65 | 66 | return { 67 | content: [ 68 | { 69 | type: "text", 70 | text: responseText 71 | } 72 | ] 73 | }; 74 | } catch (error) { 75 | log(`Error calling Claude API: ${error}`); 76 | throw error; 77 | } 78 | } 79 | throw new Error(`Unknown tool: ${request.params.name}`); 80 | }); 81 | 82 | async function main() { 83 | try { 84 | log("Starting server..."); 85 | const transport = new StdioServerTransport(); 86 | await server.connect(transport); 87 | log("Server running"); 88 | } catch (error) { 89 | log(`Server error: ${error}`); 90 | process.exit(1); 91 | } 92 | } 93 | 94 | main(); -------------------------------------------------------------------------------- /src/claude_api_server.py: -------------------------------------------------------------------------------- 1 | from mcp.server.fastmcp import FastMCP 2 | import anthropic 3 | import os 4 | from dotenv import load_dotenv 5 | from typing import Dict, List, Optional 6 | import json 7 | 8 | # Load environment variables 9 | load_dotenv() 10 | 11 | # Initialize FastMCP server 12 | mcp = FastMCP("ClaudeAPI") 13 | 14 | # Initialize Anthropic client 15 | client = anthropic.Client(api_key=os.getenv("ANTHROPIC_API_KEY")) 16 | 17 | class KnowledgeBase: 18 | def __init__(self): 19 | self.conversations: Dict[str, List[Dict]] = {} 20 | 21 | def add_message(self, conversation_id: str, message: Dict): 22 | if conversation_id not in self.conversations: 23 | self.conversations[conversation_id] = [] 24 | self.conversations[conversation_id].append(message) 25 | 26 | def get_conversation(self, conversation_id: str) -> List[Dict]: 27 | return self.conversations.get(conversation_id, []) 28 | 29 | # Initialize knowledge base 30 | kb = KnowledgeBase() 31 | 32 | @mcp.tool() 33 | async def query_claude(prompt: str, conversation_id: str = "default", system_prompt: Optional[str] = None) -> str: 34 | """ 35 | Query Claude API with a prompt and optional system prompt 36 | 37 | Args: 38 | prompt: The user's query 39 | conversation_id: Unique identifier for the conversation 40 | system_prompt: Optional system prompt to guide Claude's behavior 41 | """ 42 | try: 43 | # Get conversation history 44 | messages = kb.get_conversation(conversation_id) 45 | 46 | # Construct the new message 47 | message = { 48 | "role": "user", 49 | "content": prompt 50 | } 51 | 52 | # Add message to history 53 | kb.add_message(conversation_id, message) 54 | 55 | # Make API call to Claude 56 | response = client.messages.create( 57 | model="claude-3-sonnet-20240229", 58 | max_tokens=4096, 59 | temperature=0.7, 60 | system=system_prompt if system_prompt else None, 61 | messages=messages + [message] 62 | ) 63 | 64 | # Store Claude's response 65 | assistant_message = { 66 | "role": "assistant", 67 | "content": response.content[0].text 68 | } 69 | kb.add_message(conversation_id, assistant_message) 70 | 71 | return response.content[0].text 72 | 73 | except Exception as e: 74 | return f"Error querying Claude API: {str(e)}" 75 | 76 | @mcp.tool() 77 | async def clear_conversation(conversation_id: str = "default") -> str: 78 | """Clear a specific conversation history""" 79 | try: 80 | if conversation_id in kb.conversations: 81 | kb.conversations[conversation_id] = [] 82 | return f"Conversation {conversation_id} cleared successfully" 83 | return f"Conversation {conversation_id} not found" 84 | except Exception as e: 85 | return f"Error clearing conversation: {str(e)}" 86 | 87 | @mcp.tool() 88 | async def get_conversation_history(conversation_id: str = "default") -> str: 89 | """Get the conversation history for a specific ID""" 90 | try: 91 | history = kb.get_conversation(conversation_id) 92 | return json.dumps(history, indent=2) 93 | except Exception as e: 94 | return f"Error retrieving conversation history: {str(e)}" 95 | 96 | if __name__ == "__main__": 97 | mcp.run() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Claude Desktop API Integration via MCP 2 | 3 | This project provides an MCP server implementation that enables seamless integration between Claude Desktop and the Claude API. It allows you to bypass Professional Plan limitations and access advanced features like custom system prompts and conversation management. 4 | 5 | ## Features 6 | 7 | - Direct Claude API integration via MCP 8 | - Conversation history tracking and management 9 | - System prompt support 10 | - Seamless switching between Professional Plan and API usage 11 | - Easy configuration with Claude Desktop 12 | 13 | ## When to Use 14 | 15 | - **Professional Plan** (default): 16 | - Regular conversations in Claude Desktop 17 | - Basic usage within plan limits 18 | - No special configuration needed 19 | 20 | - **API Token** (via this MCP server): 21 | - When you need longer context windows 22 | - To use custom system prompts 23 | - To bypass rate limits 24 | - For advanced conversation management 25 | 26 | ## Setup Instructions 27 | 28 | 1. **Clone the Repository** 29 | ```bash 30 | # Using VS Code: 31 | # 1. Press Cmd + Shift + P 32 | # 2. Type "Git: Clone" 33 | # 3. Paste: https://github.com/mlobo2012/Claude_Desktop_API_USE_VIA_MCP.git 34 | 35 | # Or using terminal: 36 | git clone https://github.com/mlobo2012/Claude_Desktop_API_USE_VIA_MCP.git 37 | cd Claude_Desktop_API_USE_VIA_MCP 38 | ``` 39 | 40 | 2. **Install Dependencies** 41 | ```bash 42 | pip install -r requirements.txt 43 | ``` 44 | 45 | 3. **Configure Environment** 46 | ```bash 47 | # Copy environment template 48 | cp .env.example .env 49 | 50 | # Edit .env and add your API key 51 | ANTHROPIC_API_KEY=your_api_key_here 52 | ``` 53 | 54 | 4. **Configure Claude Desktop** 55 | - macOS: Navigate to `~/Library/Application Support/Claude/` 56 | ```bash 57 | # Using Finder: 58 | # 1. Press Cmd + Shift + G 59 | # 2. Enter: ~/Library/Application Support/Claude/ 60 | ``` 61 | - Windows: Navigate to `%APPDATA%\Claude\` 62 | - Create or edit `claude_desktop_config.json` 63 | - Copy contents from `config/claude_desktop_config.json` 64 | - Update paths and API keys 65 | 66 | ## Usage Guide 67 | 68 | ### Basic Usage 69 | 70 | 1. **Regular Claude Desktop Usage** 71 | - Just chat normally with Claude 72 | - Uses your Professional Plan 73 | - No special commands needed 74 | 75 | 2. **API Usage** 76 | ``` 77 | @claude-api Please answer using the API: What is the capital of France? 78 | ``` 79 | 80 | ### Advanced Features 81 | 82 | 1. **Using System Prompts** 83 | ``` 84 | @claude-api {"system_prompt": "You are an expert fitness coach"} Create a workout plan 85 | ``` 86 | 87 | 2. **Managing Conversations** 88 | ``` 89 | # Start a new conversation 90 | @claude-api {"conversation_id": "project1"} Let's discuss Python 91 | 92 | # Continue same conversation 93 | @claude-api {"conversation_id": "project1"} Tell me more 94 | 95 | # View conversation history 96 | @claude-api get_conversation_history project1 97 | 98 | # Clear conversation 99 | @claude-api clear_conversation project1 100 | ``` 101 | 102 | ### Cost Management 103 | 104 | - API calls use your Anthropic API credits and may incur charges 105 | - Use the Professional Plan for regular queries 106 | - Only use @claude-api when you specifically need: 107 | - Longer context windows 108 | - Custom system prompts 109 | - To bypass rate limits 110 | 111 | ## MCP Tools Available 112 | 113 | 1. `query_claude` 114 | - Make direct API calls to Claude 115 | - Support for system prompts 116 | - Conversation tracking 117 | 118 | 2. `clear_conversation` 119 | - Reset conversation history 120 | - Manage multiple conversation threads 121 | 122 | 3. `get_conversation_history` 123 | - Retrieve conversation records 124 | - Debug conversation flow 125 | 126 | ## Development 127 | 128 | The main server implementation is in `src/claude_api_server.py`. To extend functionality, you can add new tools using the `@mcp.tool()` decorator. 129 | 130 | Example of adding a new tool: 131 | 132 | ```python 133 | @mcp.tool() 134 | async def custom_tool(param: str) -> str: 135 | """ 136 | Custom tool description 137 | 138 | Args: 139 | param: Parameter description 140 | """ 141 | try: 142 | # Tool implementation 143 | return result 144 | except Exception as e: 145 | return f"Error: {str(e)}" 146 | ``` 147 | 148 | ## Troubleshooting 149 | 150 | 1. **API Key Issues** 151 | - Verify your API key in .env 152 | - Check Claude Desktop config paths 153 | - Ensure API key has correct permissions 154 | 155 | 2. **Connection Issues** 156 | - Check if MCP server is running 157 | - Verify Python environment 158 | - Check Claude Desktop logs 159 | 160 | 3. **Usage Issues** 161 | - Ensure correct @claude-api syntax 162 | - Check conversation IDs 163 | - Verify system prompt format 164 | 165 | ## Contributing 166 | 167 | 1. Fork the repository 168 | 2. Create a feature branch 169 | 3. Make your changes 170 | 4. Submit a pull request 171 | 172 | ## License 173 | 174 | MIT 175 | 176 | ## Support 177 | 178 | For issues and questions: 179 | 1. Open an issue in the repository 180 | 2. Check existing discussions 181 | 3. Review the troubleshooting guide --------------------------------------------------------------------------------