Created
March 19, 2025 04:53
-
-
Save korrio/77c12ba1fa8bdada8d5b496f31bf1190 to your computer and use it in GitHub Desktop.
MCP Server/Client integration with Claude Sonnet 3.7 model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MCP Server with Claude Integration | |
const express = require('express'); | |
const http = require('http'); | |
const WebSocket = require('ws'); | |
const { Anthropic } = require('@anthropic/sdk'); | |
const dotenv = require('dotenv'); | |
// Load environment variables from .env file | |
dotenv.config(); | |
// Initialize Claude client | |
const anthropic = new Anthropic({ | |
apiKey: process.env.ANTHROPIC_API_KEY, | |
}); | |
// Initialize Express app | |
const app = express(); | |
const server = http.createServer(app); | |
const wss = new WebSocket.Server({ server }); | |
// Store client connections | |
const clients = new Map(); | |
// MCP message types | |
const MESSAGE_TYPES = { | |
CONNECT: 'connect', | |
DISCONNECT: 'disconnect', | |
CHAT_MESSAGE: 'chat_message', | |
AI_RESPONSE: 'ai_response', | |
STATUS_UPDATE: 'status_update', | |
ERROR: 'error' | |
}; | |
// Handle new WebSocket connections | |
wss.on('connection', (ws) => { | |
const clientId = generateClientId(); | |
// Store client connection | |
clients.set(clientId, { | |
connection: ws, | |
history: [] | |
}); | |
// Send welcome message | |
sendMessage(ws, { | |
type: MESSAGE_TYPES.CONNECT, | |
clientId: clientId, | |
message: 'Connected to MCP server with Claude integration' | |
}); | |
// Handle incoming messages | |
ws.on('message', async (data) => { | |
try { | |
const message = JSON.parse(data); | |
// Store message in client history | |
clients.get(clientId).history.push({ | |
role: 'user', | |
content: message.content | |
}); | |
// Broadcast message to all clients | |
broadcastMessage({ | |
type: MESSAGE_TYPES.CHAT_MESSAGE, | |
clientId: clientId, | |
message: message.content, | |
timestamp: new Date().toISOString() | |
}); | |
// Process message with Claude | |
try { | |
sendMessage(ws, { | |
type: MESSAGE_TYPES.STATUS_UPDATE, | |
message: 'Processing your message with Claude...' | |
}); | |
const response = await getClaudeResponse(clientId, message.content); | |
// Store Claude's response in client history | |
clients.get(clientId).history.push({ | |
role: 'assistant', | |
content: response | |
}); | |
// Send Claude's response | |
sendMessage(ws, { | |
type: MESSAGE_TYPES.AI_RESPONSE, | |
message: response, | |
timestamp: new Date().toISOString() | |
}); | |
} catch (error) { | |
console.error('Claude API error:', error); | |
sendMessage(ws, { | |
type: MESSAGE_TYPES.ERROR, | |
message: 'Error processing your message with Claude. Please try again later.' | |
}); | |
} | |
} catch (error) { | |
console.error('Error processing message:', error); | |
sendMessage(ws, { | |
type: MESSAGE_TYPES.ERROR, | |
message: 'Invalid message format' | |
}); | |
} | |
}); | |
// Handle client disconnection | |
ws.on('close', () => { | |
clients.delete(clientId); | |
broadcastMessage({ | |
type: MESSAGE_TYPES.DISCONNECT, | |
clientId: clientId, | |
message: 'Client disconnected', | |
timestamp: new Date().toISOString() | |
}); | |
}); | |
}); | |
// Generate a unique client ID | |
function generateClientId() { | |
return 'client_' + Math.random().toString(36).substring(2, 15); | |
} | |
// Send message to a specific client | |
function sendMessage(client, message) { | |
client.send(JSON.stringify(message)); | |
} | |
// Broadcast message to all clients | |
function broadcastMessage(message) { | |
clients.forEach((client) => { | |
sendMessage(client.connection, message); | |
}); | |
} | |
// Get response from Claude | |
async function getClaudeResponse(clientId, message) { | |
const client = clients.get(clientId); | |
// Prepare message history for Claude | |
const messages = client.history.map(msg => ({ | |
role: msg.role, | |
content: msg.content | |
})); | |
// Call Claude API | |
const response = await anthropic.messages.create({ | |
model: 'claude-3-7-sonnet-20250219', | |
max_tokens: 1000, | |
messages: messages, | |
system: "You are Claude, an AI assistant integrated into an MCP server. Be helpful, accurate, and concise in your responses." | |
}); | |
return response.content[0].text; | |
} | |
// Serve static files | |
app.use(express.static('public')); | |
// Define API routes | |
app.get('/api/clients', (req, res) => { | |
const clientList = Array.from(clients.keys()); | |
res.json({ clients: clientList }); | |
}); | |
// Start the server | |
const PORT = process.env.PORT || 3000; | |
server.listen(PORT, () => { | |
console.log(`MCP Server with Claude integration running on port ${PORT}`); | |
}); | |
// Example .env file configuration: | |
/* | |
PORT=3000 | |
ANTHROPIC_API_KEY=your_anthropic_api_key | |
*/ | |
// Example client-side implementation for connecting to this MCP server: | |
// client.js | |
const socket = new WebSocket('ws://localhost:3000'); | |
socket.onopen = () => { | |
console.log('Connected to MCP server'); | |
}; | |
socket.onmessage = (event) => { | |
const message = JSON.parse(event.data); | |
console.log('Received message:', message); | |
// Handle different message types | |
switch (message.type) { | |
case 'connect': | |
console.log('Connected with client ID:', message.clientId); | |
break; | |
case 'chat_message': | |
// Display chat message from another user | |
break; | |
case 'ai_response': | |
// Display Claude's response | |
break; | |
case 'status_update': | |
// Display status update | |
break; | |
case 'error': | |
// Display error message | |
break; | |
default: | |
console.log('Unknown message type:', message.type); | |
} | |
}; | |
function sendMessage(content) { | |
socket.send(JSON.stringify({ | |
content: content | |
})); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment