Skip to content

Instantly share code, notes, and snippets.

@korrio
Created March 19, 2025 04:53
Show Gist options
  • Save korrio/77c12ba1fa8bdada8d5b496f31bf1190 to your computer and use it in GitHub Desktop.
Save korrio/77c12ba1fa8bdada8d5b496f31bf1190 to your computer and use it in GitHub Desktop.
MCP Server/Client integration with Claude Sonnet 3.7 model
// 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