Model Context Protocol (MCP) Servers Cheat Sheet¶
Overview¶
Model Context Protocol (MCP) es un estándar universal y abierto diseñado para conectar sistemas AI con fuentes e instrumentos de datos externos. Los servidores de MCP actúan como el puente entre los modelos AI (clientes) y el mundo externo, permitiendo a los asistentes de IA acceder e invocar funciones, recuperar información e interactuar con diversos servicios de manera estandarizada.
Lo que distingue a MCP es su capacidad de reemplazar las integraciones fragmentadas con un protocolo único y unificado. Antes de MCP, cada proveedor de modelos AI tenía sus propios métodos patentados para el uso de herramientas y el uso de funciones, creando un ecosistema complejo que requería que los desarrolladores implementaran diferentes enfoques de integración para cada modelo. MCP resuelve esto proporcionando una interfaz estandarizada que funciona en diferentes modelos y servicios de IA, simplificando significativamente el desarrollo y el despliegue de aplicaciones de IA.
Los servidores de MCP han surgido como un componente crítico en la pila de infraestructura de IA, permitiendo a las organizaciones construir conexiones seguras, escalables y estandarizadas entre sus modelos de IA y las herramientas, fuentes de datos y servicios que necesitan para acceder. Ya sea desplegado en plataformas de nube o en locales, los servidores MCP permiten que los sistemas AI interactúen de manera segura y eficiente con el mundo externo manteniendo el control sobre estas interacciones.
Core Concepts¶
Model Context Protocol (MCP)¶
MCP es el protocolo estandarizado que define cómo los modelos AI interactúan con herramientas y servicios externos. Proporciona una interfaz universal para conectar sistemas AI con fuentes de datos y funciones.
MCP Server¶
Un servidor MCP implementa el Protocolo Modelo de Contexto y actúa como puente entre los modelos AI (clientes) y herramientas o servicios externos. Maneja solicitudes de modelos AI, ejecuta las funciones apropiadas y devuelve los resultados.
MCP Client¶
Un cliente MCP es cualquier modelo o aplicación AI que se comunica con un servidor MCP para acceder a herramientas y servicios externos. Los clientes envían solicitudes al servidor y reciben respuestas según la especificación MCP.
Herramientas Las herramientas son funciones o servicios que un servidor MCP pone a disposición de los modelos AI. Estos pueden incluir funciones de recuperación de datos, herramientas computacionales, integraciones de API o cualquier otra capacidad que extienda la funcionalidad del modelo AI.
Contexto Context se refiere a la información y las capacidades disponibles para un modelo AI a través del servidor MCP. Esto incluye las herramientas que el modelo puede acceder, los datos que puede recuperar, y las operaciones que puede realizar.
Instalación y configuración¶
AWS Serverless¶
# Clone the AWS Serverless MCP Server repository
git clone https://github.com/aws-samples/aws-serverless-mcp-server.git
cd aws-serverless-mcp-server
# Install dependencies
npm install
# Deploy using AWS CDK
npm run cdk bootstrap
npm run cdk deploy
Basic Node.js MCP Server¶
// Install dependencies
// npm install express cors body-parser
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
app.use(cors());
app.use(bodyParser.json());
// Define available tools
const tools = \\\\{
get_weather: async (params) => \\\\{
const \\\\{ location \\\\} = params;
// Implement weather retrieval logic
return \\\\{ temperature: 25, conditions: "Sunny", location \\\\};
\\\\},
search_database: async (params) => \\\\{
const \\\\{ query \\\\} = params;
// Implement database search logic
return \\\\{ results: [`Result for: $\\{query\\}`] \\\\};
\\\\}
\\\\};
// MCP server endpoint
app.post('/mcp', async (req, res) => \\\\{
try \\\\{
const \\\\{ tool, parameters \\\\} = req.body;
if (!tools[tool]) \\\\{
return res.status(400).json(\\\\{ error: `Tool '$\\{tool\\}' not found` \\\\});
\\\\}
const result = await tools[tool](parameters);
res.json(\\\\{ result \\\\});
\\\\} catch (error) \\\\{
res.status(500).json(\\\\{ error: error.message \\\\});
\\\\}
\\\\});
// Start server
const PORT = process.env.PORT||3000;
app.listen(PORT, () => \\\\{
console.log(`MCP Server running on port $\\{PORT\\}`);
\\\\});
Python MCP Servidor¶
# Install dependencies
# pip install fastapi uvicorn pydantic
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Dict, Any, Optional
import uvicorn
app = FastAPI()
# Define request model
class MCPRequest(BaseModel):
tool: str
parameters: Dict[str, Any]
# Define available tools
async def get_weather(location: str) -> Dict[str, Any]:
# Implement weather retrieval logic
return \\\\{"temperature": 25, "conditions": "Sunny", "location": location\\\\}
async def search_database(query: str) -> Dict[str, Any]:
# Implement database search logic
return \\\\{"results": [f"Result for: \\\\{query\\\\}"]\\\\}
# Tool registry
tools = \\\\{
"get_weather": get_weather,
"search_database": search_database
\\\\}
@app.post("/mcp")
async def mcp_endpoint(request: MCPRequest):
if request.tool not in tools:
raise HTTPException(status_code=400, detail=f"Tool '\\\\{request.tool\\\\}' not found")
try:
result = await tools[request.tool](**request.parameters)
return \\\\{"result": result\\\\}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=3000)
Docker Deployment¶
# Dockerfile for Python MCP Server
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 3000
CMD ["uvicorn", "mcp_server:app", "--host", "0.0.0.0", "--port", "3000"]
# docker-compose.yml
version: '3'
services:
mcp-server:
build: .
ports:
- "3000:3000"
environment:
- LOG_LEVEL=info
- AUTH_ENABLED=true
- AUTH_API_KEY=your-secret-api-key
volumes:
- ./config:/app/config
Tool Implementation¶
Basic Tool Structure¶
// JavaScript tool implementation
const tools = \\\\{
// Simple tool with direct implementation
get_current_time: async (params) => \\\\{
const \\\\{ timezone = 'UTC' \\\\} = params;
return \\\\{
time: new Date().toLocaleString('en-US', \\\\{ timeZone: timezone \\\\}),
timezone
\\\\};
\\\\},
// Tool that calls an external API
fetch_stock_price: async (params) => \\\\{
const \\\\{ symbol \\\\} = params;
try \\\\{
const response = await fetch(`https://api.example.com/stocks/$\\{symbol\\}`);
const data = await response.json();
return \\\\{
symbol,
price: data.price,
currency: data.currency,
timestamp: data.timestamp
\\\\};
\\\\} catch (error) \\\\{
throw new Error(`Failed to fetch stock price: $\\{error.message\\}`);
\\\\}
\\\\}
\\\\};
# Python tool implementation
async def get_current_time(timezone: str = 'UTC') -> Dict[str, Any]:
from datetime import datetime
import pytz
tz = pytz.timezone(timezone)
current_time = datetime.now(tz)
return \\\\{
"time": current_time.strftime("%Y-%m-%d %H:%M:%S"),
"timezone": timezone
\\\\}
async def fetch_stock_price(symbol: str) -> Dict[str, Any]:
import aiohttp
async with aiohttp.ClientSession() as session:
async with session.get(f"https://api.example.com/stocks/\\\\{symbol\\\\}") as response:
if response.status != 200:
raise Exception(f"API returned status code \\\\{response.status\\\\}")
data = await response.json()
return \\\\{
"symbol": symbol,
"price": data["price"],
"currency": data["currency"],
"timestamp": data["timestamp"]
\\\\}
Tool Manifest¶
\\\\{
"tools": [
\\\\{
"name": "get_current_time",
"description": "Get the current time in a specified timezone",
"parameters": \\\\{
"type": "object",
"properties": \\\\{
"timezone": \\\\{
"type": "string",
"description": "Timezone identifier (e.g., 'UTC', 'America/New_York')"
\\\\}
\\\\},
"required": []
\\\\}
\\\\},
\\\\{
"name": "fetch_stock_price",
"description": "Get the current stock price for a given symbol",
"parameters": \\\\{
"type": "object",
"properties": \\\\{
"symbol": \\\\{
"type": "string",
"description": "Stock symbol (e.g., 'AAPL', 'MSFT')"
\\\\}
\\\\},
"required": ["symbol"]
\\\\}
\\\\}
]
\\\\}
Herramienta avanzada con autenticación¶
// Tool that requires authentication
const authenticatedTools = \\\\{
get_user_data: async (params, context) => \\\\{
const \\\\{ userId \\\\} = params;
const \\\\{ authToken \\\\} = context;
if (!authToken) \\\\{
throw new Error('Authentication required');
\\\\}
try \\\\{
const response = await fetch(`https://api.example.com/users/$\\{userId\\}`, \\\\{
headers: \\\\{
'Authorization': `Bearer $\\{authToken\\}`
\\\\}
\\\\});
if (!response.ok) \\\\{
throw new Error(`API returned status $\\{response.status\\}`);
\\\\}
return await response.json();
\\\\} catch (error) \\\\{
throw new Error(`Failed to fetch user data: $\\{error.message\\}`);
\\\\}
\\\\}
\\\\};
Autenticación y seguridad
API Autenticación clave¶
// Express middleware for API key authentication
function apiKeyAuth(req, res, next) \\\\{
const apiKey = req.headers['x-api-key'];
if (!apiKey||apiKey !== process.env.MCP_API_KEY) \\\\{
return res.status(401).json(\\\\{ error: 'Unauthorized' \\\\});
\\\\}
next();
\\\\}
// Apply middleware to MCP endpoint
app.post('/mcp', apiKeyAuth, async (req, res) => \\\\{
// MCP request handling
\\\\});
# FastAPI API key authentication
from fastapi import Depends, HTTPException, Security
from fastapi.security.api_key import APIKeyHeader
import os
API_KEY = os.getenv("MCP_API_KEY")
api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
async def get_api_key(api_key: str = Security(api_key_header)):
if not api_key or api_key != API_KEY:
raise HTTPException(status_code=401, detail="Invalid API Key")
return api_key
@app.post("/mcp")
async def mcp_endpoint(request: MCPRequest, api_key: str = Depends(get_api_key)):
# MCP request handling
JWT Autenticación¶
// JWT authentication middleware
const jwt = require('jsonwebtoken');
function jwtAuth(req, res, next) \\\\{
const authHeader = req.headers.authorization;
if (!authHeader||!authHeader.startsWith('Bearer ')) \\\\{
return res.status(401).json(\\\\{ error: 'Unauthorized' \\\\});
\\\\}
const token = authHeader.split(' ')[1];
try \\\\{
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
\\\\} catch (error) \\\\{
return res.status(401).json(\\\\{ error: 'Invalid token' \\\\});
\\\\}
\\\\}
// Apply middleware to MCP endpoint
app.post('/mcp', jwtAuth, async (req, res) => \\\\{
// MCP request handling with access to req.user
\\\\});
# FastAPI JWT authentication
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
import jwt
from jwt.exceptions import PyJWTError
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
JWT_SECRET = os.getenv("JWT_SECRET")
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, JWT_SECRET, algorithms=["HS256"])
username = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
except PyJWTError:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
# Get user from database or return user info from token
return \\\\{"username": username\\\\}
@app.post("/mcp")
async def mcp_endpoint(request: MCPRequest, current_user: dict = Depends(get_current_user)):
# MCP request handling with access to current_user
Rate Limiting¶
// Rate limiting middleware
const rateLimit = require('express-rate-limit');
const mcpLimiter = rateLimit(\\\\{
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again later'
\\\\});
// Apply rate limiting to MCP endpoint
app.post('/mcp', mcpLimiter, async (req, res) => \\\\{
// MCP request handling
\\\\});
# FastAPI rate limiting with slowapi
from fastapi import Depends
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
app = FastAPI()
app.state.limiter = limiter
@app.post("/mcp")
@limiter.limit("100/minute")
async def mcp_endpoint(request: MCPRequest, remote_addr: str = Depends(get_remote_address)):
# MCP request handling
Características avanzadas del servidor MCP¶
Tool Discovery¶
// Endpoint for tool discovery
app.get('/mcp/tools', apiKeyAuth, (req, res) => \\\\{
const toolManifest = \\\\{
tools: Object.keys(tools).map(toolName => \\\\{
return \\\\{
name: toolName,
description: toolDescriptions[toolName]||'',
parameters: toolParameters[toolName]||\\\\{ type: 'object', properties: \\\\{\\\\} \\\\}
\\\\};
\\\\})
\\\\};
res.json(toolManifest);
\\\\});
# FastAPI tool discovery endpoint
@app.get("/mcp/tools")
async def get_tools(api_key: str = Depends(get_api_key)):
tool_manifest = \\\\{
"tools": [
\\\\{
"name": name,
"description": tool_descriptions.get(name, ""),
"parameters": tool_parameters.get(name, \\\\{"type": "object", "properties": \\\\{\\\\}\\\\})
\\\\}
for name in tools.keys()
]
\\\\}
return tool_manifest
Streaming Responses¶
// Express streaming response
app.post('/mcp/stream', apiKeyAuth, (req, res) => \\\\{
const \\\\{ tool, parameters \\\\} = req.body;
if (!streamingTools[tool]) \\\\{
return res.status(400).json(\\\\{ error: `Streaming tool '$\\{tool\\}' not found` \\\\});
\\\\}
// Set headers for streaming
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Create streaming tool instance
const stream = streamingTools[tool](parameters);
// Handle data events
stream.on('data', (data) => \\\\{
res.write(`data: $\\{JSON.stringify(data)\\}\n\n`);
\\\\});
// Handle end event
stream.on('end', () => \\\\{
res.write('data: [DONE]\n\n');
res.end();
\\\\});
// Handle errors
stream.on('error', (error) => \\\\{
res.write(`data: $\\{JSON.stringify(\\{ error: error.message \\})\\}\n\n`);
res.end();
\\\\});
// Handle client disconnect
req.on('close', () => \\\\{
stream.destroy();
\\\\});
\\\\});
# FastAPI streaming response
from fastapi import Response
from fastapi.responses import StreamingResponse
import json
import asyncio
@app.post("/mcp/stream")
async def stream_mcp(request: MCPRequest, api_key: str = Depends(get_api_key)):
if request.tool not in streaming_tools:
raise HTTPException(status_code=400, detail=f"Streaming tool '\\\\{request.tool\\\\}' not found")
async def event_generator():
try:
async for data in streaming_tools[request.tool](**request.parameters):
yield f"data: \\\\{json.dumps(data)\\\\}\n\n"
await asyncio.sleep(0.01) # Small delay to prevent CPU hogging
yield "data: [DONE]\n\n"
except Exception as e:
yield f"data: \\\\{json.dumps(\\\\{'error': str(e)\\\\})\\\\}\n\n"
return StreamingResponse(
event_generator(),
media_type="text/event-stream"
)
Logging and Monitoring¶
// Winston logger setup
const winston = require('winston');
const logger = winston.createLogger(\\\\{
level: process.env.LOG_LEVEL||'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console(),
new winston.transports.File(\\\\{ filename: 'mcp-server.log' \\\\})
]
\\\\});
// Logging middleware
function loggingMiddleware(req, res, next) \\\\{
const start = Date.now();
// Log request
logger.info(\\\\{
type: 'request',
method: req.method,
path: req.path,
tool: req.body.tool,
requestId: req.headers['x-request-id']||uuidv4()
\\\\});
// Capture response
const originalSend = res.send;
res.send = function(body) \\\\{
const duration = Date.now() - start;
// Log response
logger.info(\\\\{
type: 'response',
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration,
requestId: req.headers['x-request-id']||uuidv4()
\\\\});
return originalSend.call(this, body);
\\\\};
next();
\\\\}
// Apply logging middleware
app.use(loggingMiddleware);
# FastAPI logging middleware
import logging
import time
import uuid
from fastapi import Request
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("mcp-server.log"),
logging.StreamHandler()
]
)
logger = logging.getLogger("mcp-server")
@app.middleware("http")
async def logging_middleware(request: Request, call_next):
request_id = request.headers.get("X-Request-ID", str(uuid.uuid4()))
start_time = time.time()
# Log request
logger.info(\\\\{
"type": "request",
"method": request.method,
"path": request.url.path,
"request_id": request_id
\\\\})
# Process request
response = await call_next(request)
# Log response
duration = time.time() - start_time
logger.info(\\\\{
"type": "response",
"method": request.method,
"path": request.url.path,
"status_code": response.status_code,
"duration": duration,
"request_id": request_id
\\\\})
return response
Error de manipulación¶
// Error handling middleware
function errorHandler(err, req, res, next) \\\\{
logger.error(\\\\{
type: 'error',
error: err.message,
stack: err.stack,
path: req.path,
requestId: req.headers['x-request-id']||uuidv4()
\\\\});
res.status(500).json(\\\\{
error: 'Internal server error',
requestId: req.headers['x-request-id']||uuidv4()
\\\\});
\\\\}
// Apply error handling middleware
app.use(errorHandler);
# FastAPI exception handlers
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
logger.error(\\\\{
"type": "validation_error",
"path": request.url.path,
"errors": exc.errors(),
"request_id": request.headers.get("X-Request-ID", str(uuid.uuid4()))
\\\\})
return JSONResponse(
status_code=422,
content=\\\\{"detail": exc.errors(), "type": "validation_error"\\\\}
)
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
logger.error(\\\\{
"type": "http_error",
"path": request.url.path,
"status_code": exc.status_code,
"detail": exc.detail,
"request_id": request.headers.get("X-Request-ID", str(uuid.uuid4()))
\\\\})
return JSONResponse(
status_code=exc.status_code,
content=\\\\{"detail": exc.detail, "type": "http_error"\\\\}
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
logger.error(\\\\{
"type": "server_error",
"path": request.url.path,
"error": str(exc),
"request_id": request.headers.get("X-Request-ID", str(uuid.uuid4()))
\\\\})
return JSONResponse(
status_code=500,
content=\\\\{"detail": "Internal server error", "type": "server_error"\\\\}
)
Cloud Deployment¶
AWS Lambda Deployment¶
// serverless.yml for AWS Lambda deployment
service: mcp-server
provider:
name: aws
runtime: nodejs14.x
region: us-east-1
environment:
MCP_API_KEY: $\\\\{env:MCP_API_KEY\\\\}
LOG_LEVEL: info
functions:
mcp:
handler: handler.mcp
events:
- http:
path: mcp
method: post
cors: true
toolDiscovery:
handler: handler.toolDiscovery
events:
- http:
path: mcp/tools
method: get
cors: true
// handler.js for AWS Lambda
const serverless = require('serverless-http');
const express = require('express');
const app = express();
// ... MCP server implementation ...
// Export Lambda handlers
module.exports.mcp = serverless(app);
module.exports.toolDiscovery = serverless(app);
Azure Functions Deployment¶
// function.json for Azure Functions
\\\\{
"bindings": [
\\\\{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["post"],
"route": "mcp"
\\\\},
\\\\{
"type": "http",
"direction": "out",
"name": "res"
\\\\}
]
\\\\}
// index.js for Azure Functions
module.exports = async function (context, req) \\\\{
// Validate request
if (!req.body||!req.body.tool) \\\\{
context.res = \\\\{
status: 400,
body: \\\\{ error: "Missing required fields" \\\\}
\\\\};
return;
\\\\}
const \\\\{ tool, parameters \\\\} = req.body;
// Validate API key
const apiKey = req.headers['x-api-key'];
if (!apiKey||apiKey !== process.env.MCP_API_KEY) \\\\{
context.res = \\\\{
status: 401,
body: \\\\{ error: "Unauthorized" \\\\}
\\\\};
return;
\\\\}
try \\\\{
// Execute tool
if (!tools[tool]) \\\\{
context.res = \\\\{
status: 400,
body: \\\\{ error: `Tool '$\\{tool\\}' not found` \\\\}
\\\\};
return;
\\\\}
const result = await tools[tool](parameters);
context.res = \\\\{
status: 200,
body: \\\\{ result \\\\}
\\\\};
\\\\} catch (error) \\\\{
context.log.error(`Error executing tool $\\{tool\\}: $\\{error.message\\}`);
context.res = \\\\{
status: 500,
body: \\\\{ error: error.message \\\\}
\\\\};
\\\\}
\\\\};
Kubernetes Deployment¶
# kubernetes-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server
labels:
app: mcp-server
spec:
replicas: 3
selector:
matchLabels:
app: mcp-server
template:
metadata:
labels:
app: mcp-server
spec:
containers:
- name: mcp-server
image: your-registry/mcp-server:latest
ports:
- containerPort: 3000
env:
- name: MCP_API_KEY
valueFrom:
secretKeyRef:
name: mcp-secrets
key: api-key
- name: LOG_LEVEL
value: "info"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: mcp-server-service
spec:
selector:
app: mcp-server
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
---
apiVersion: v1
kind: Secret
metadata:
name: mcp-secrets
type: Opaque
data:
api-key: <base64-encoded-api-key>
Integración con modelos AI¶
OpenAI Integration¶
// Client-side integration with OpenAI
const \\\\{ OpenAI \\\\} = require('openai');
const openai = new OpenAI(\\\\{
apiKey: process.env.OPENAI_API_KEY
\\\\});
async function callOpenAIWithMCP(prompt, mcpServerUrl, mcpApiKey) \\\\{
const response = await openai.chat.completions.create(\\\\{
model: 'gpt-4',
messages: [\\\\{ role: 'user', content: prompt \\\\}],
tools: [
\\\\{
type: 'function',
function: \\\\{
name: 'mcp_server',
description: 'Call the MCP server to access external tools and data',
parameters: \\\\{
type: 'object',
properties: \\\\{
tool: \\\\{
type: 'string',
description: 'The name of the tool to call'
\\\\},
parameters: \\\\{
type: 'object',
description: 'Parameters for the tool'
\\\\}
\\\\},
required: ['tool']
\\\\}
\\\\}
\\\\}
],
tool_choice: 'auto'
\\\\});
// Check if the model wants to call a tool
const message = response.choices[0].message;
if (message.tool_calls && message.tool_calls.length > 0) \\\\{
const toolCall = message.tool_calls[0];
if (toolCall.function.name === 'mcp_server') \\\\{
const \\\\{ tool, parameters \\\\} = JSON.parse(toolCall.function.arguments);
// Call MCP server
const mcpResponse = await fetch(mcpServerUrl, \\\\{
method: 'POST',
headers: \\\\{
'Content-Type': 'application/json',
'X-API-Key': mcpApiKey
\\\\},
body: JSON.stringify(\\\\{ tool, parameters \\\\})
\\\\});
const mcpResult = await mcpResponse.json();
// Continue the conversation with the tool result
const finalResponse = await openai.chat.completions.create(\\\\{
model: 'gpt-4',
messages: [
\\\\{ role: 'user', content: prompt \\\\},
message,
\\\\{
role: 'tool',
tool_call_id: toolCall.id,
content: JSON.stringify(mcpResult)
\\\\}
]
\\\\});
return finalResponse.choices[0].message.content;
\\\\}
\\\\}
return message.content;
\\\\}
Anthropic Integration¶
// Client-side integration with Anthropic
const \\\\{ Anthropic \\\\} = require('@anthropic-ai/sdk');
const anthropic = new Anthropic(\\\\{
apiKey: process.env.ANTHROPIC_API_KEY
\\\\});
async function callAnthropicWithMCP(prompt, mcpServerUrl, mcpApiKey) \\\\{
const response = await anthropic.messages.create(\\\\{
model: 'claude-3-opus-20240229',
messages: [\\\\{ role: 'user', content: prompt \\\\}],
tools: [
\\\\{
name: 'mcp_server',
description: 'Call the MCP server to access external tools and data',
input_schema: \\\\{
type: 'object',
properties: \\\\{
tool: \\\\{
type: 'string',
description: 'The name of the tool to call'
\\\\},
parameters: \\\\{
type: 'object',
description: 'Parameters for the tool'
\\\\}
\\\\},
required: ['tool']
\\\\}
\\\\}
]
\\\\});
// Check if the model wants to call a tool
const message = response.content[0];
if (message.type === 'tool_use' && message.name === 'mcp_server') \\\\{
const \\\\{ tool, parameters \\\\} = message.input;
// Call MCP server
const mcpResponse = await fetch(mcpServerUrl, \\\\{
method: 'POST',
headers: \\\\{
'Content-Type': 'application/json',
'X-API-Key': mcpApiKey
\\\\},
body: JSON.stringify(\\\\{ tool, parameters \\\\})
\\\\});
const mcpResult = await mcpResponse.json();
// Continue the conversation with the tool result
const finalResponse = await anthropic.messages.create(\\\\{
model: 'claude-3-opus-20240229',
messages: [
\\\\{ role: 'user', content: prompt \\\\},
\\\\{
role: 'assistant',
content: [message]
\\\\},
\\\\{
role: 'tool',
name: 'mcp_server',
content: JSON.stringify(mcpResult)
\\\\}
]
\\\\});
return finalResponse.content[0].text;
\\\\}
return message.text;
\\\\}
Buenas prácticas¶
Seguridad Buenas Prácticas¶
- Authentication: Siempre implemente la autenticación adecuada para servidores MCP Autorización: Implementar un control de acceso fino para herramientas
- ** Validación de entrada**: Validar todos los parámetros de entrada para prevenir ataques de inyección ** Limitación de destino**: Implementar la tasa límite para prevenir los abusos
- ** Gestión de Secretos**: Utilice métodos seguros para almacenar y acceder a las claves y secretos de API
- HTTPS: Utilice siempre HTTPS para despliegues de producción Permisos mínimos**: Seguir el principio de mínimo privilegio para la aplicación de los instrumentos
Performance Optimization¶
Caching: Implementar caching para los resultados de herramientas utilizados con frecuencia - Connection Pooling: Uso de la conexión para las conexiones de bases de datos y API - Procesamiento Sincrónico**: Use async/await for I/O-bound operations - ** Escalada horizontal**: Diseño para escalado horizontal para manejar carga aumentada - Manejo de tiempo: Implementar el manejo de tiempo adecuado para llamadas de API externas - Resource Limits: Establecer límites adecuados de la CPU y la memoria para contenedores
Reliability¶
Manejo del espejo: Implementar un manejo integral de errores e informar - Retries: Agregue la lógica de reingreso para fallos transitorios Circuit Breakers: Implementar interruptores para dependencias externas - Comprobaciones de salud**: Agregue puntos finales de control de salud para monitorizar Logging: Implementar un registro estructurado para la solución de problemas Monitoreo Establecer monitorización y alerta para métricas clave
Development Workflow¶
- Control de Versión**: Control de la versión para el código del servidor MCP CI/CD: Implementación de tuberías de integración y despliegue continuos
- Testing: Escribir pruebas de unidad e integración para herramientas
- Documentación: documentar todas las herramientas y sus parámetros
- Code Reviews: Realizar exámenes de código completo para la seguridad y la calidad
- Traducción semántica**: Utilice la versión semántica para los cambios de API
Troubleshooting¶
Common Issues¶
Authentication Failures¶
- Causa: Claves incorrectas de API, fichas vencidas o autenticación errónea
- Solución: Claves de API, verificación de la caducidad token, y asegurar la configuración de autenticación adecuada
Errores de ejecución de herramientas¶
- Causa: Parámetros inválidos, fallas externas de API o errores en la implementación de herramientas
- Solución: Validar los parámetros, añadir el manejo de errores para API externas y herramientas de prueba a fondo
Performance Issues¶
Causa: Ineficientes implementaciones de herramientas, falta de caché o limitaciones de recursos Solución: Optimize tool code, implemente caching y asigne los recursos apropiados
Problemas de integración¶
- Causa: esquemas incorrectos de herramientas, tipos de parámetros desajustados o malentendidos de protocolo
- Solución: Verificar esquemas de herramientas, asegurar que los tipos de parámetro coincidan, y seguir la especificación MCP
-...
*Esta hoja de trampolín completa de MCP Servers proporciona todo lo necesario para construir, desplegar e integrar los servidores de Modelo Context Protocol. Desde la configuración básica hasta las pautas avanzadas de despliegue, utilice estos ejemplos y mejores prácticas para crear conexiones potentes y estandarizadas entre los modelos AI y las herramientas y servicios externos. *