Las descripciones de las herramientas MCP son costos ocultos. Cada herramienta a la que su agente puede llamar agrega una descripción al mensaje del sistema, consumiendo tokens de contexto antes de que el usuario diga algo. Con varios servidores MCP, las descripciones de las herramientas pueden ocupar entre el 10% y el 20% de su ventana de contexto. Este tutorial crea una herramienta de auditoría de tokens que mide exactamente cuántos tokens consume cada servidor MCP, identifica a los peores infractores y muestra cómo cambiar a Scavio (mcp.scavio.dev/mcp) consolida 6 plataformas en un servidor.
Requisitos previos
- Python 3.9+ instalado
- biblioteca tiktoken instalada (pip install tiktoken)
- Acceso a sus archivos de configuración de MCP
- Una clave API de Scavio de scavio.dev para comparar
Guia paso a paso
Paso 1: Cargue y analice su configuración de MCP
Lea sus archivos de configuración de MCP y enumere todos los servidores configurados y sus recuentos de herramientas.
import json, os
def load_mcp_configs() -> dict:
"""Load MCP configs from all standard locations."""
configs = {}
paths = {
'claude_desktop': os.path.expanduser('~/.config/claude/claude_desktop_config.json'),
'cursor': os.path.expanduser('~/.cursor/mcp.json'),
'project': '.mcp.json',
}
for name, path in paths.items():
if os.path.exists(path):
with open(path) as f:
data = json.load(f)
servers = data.get('mcpServers', {})
configs[name] = {
'path': path,
'servers': servers,
'server_count': len(servers),
}
return configs
configs = load_mcp_configs()
for name, cfg in configs.items():
print(f'{name} ({cfg["path"]}):')
print(f' Servers: {cfg["server_count"]}')
for server_name in cfg['servers']:
print(f' - {server_name}')Paso 2: Estimar los costos de los tokens por servidor
Cuente tokens en descripciones de herramientas usando tiktoken. Cada herramienta tiene un nombre, una descripción y un esquema de parámetros que consumen tokens.
import tiktoken
def count_tokens(text: str, model: str = 'gpt-4o') -> int:
enc = tiktoken.encoding_for_model(model)
return len(enc.encode(text))
# Typical tool description sizes (measured from real MCP servers)
SERVER_ESTIMATES = {
'filesystem': {'tools': 11, 'avg_desc_tokens': 180},
'github': {'tools': 25, 'avg_desc_tokens': 250},
'slack': {'tools': 12, 'avg_desc_tokens': 200},
'postgres': {'tools': 8, 'avg_desc_tokens': 220},
'memory': {'tools': 5, 'avg_desc_tokens': 150},
'brave-search': {'tools': 2, 'avg_desc_tokens': 300},
'scavio': {'tools': 3, 'avg_desc_tokens': 250},
'tavily': {'tools': 2, 'avg_desc_tokens': 280},
'puppeteer': {'tools': 8, 'avg_desc_tokens': 200},
'sequential-thinking': {'tools': 1, 'avg_desc_tokens': 400},
}
def estimate_server_tokens(server_name: str) -> int:
"""Estimate token cost for a known MCP server."""
if server_name in SERVER_ESTIMATES:
est = SERVER_ESTIMATES[server_name]
return est['tools'] * est['avg_desc_tokens']
return 5 * 200 # Default: 5 tools x 200 tokens
# Audit all servers
print('MCP Server Token Audit')
print('=' * 50)
total = 0
for name, est in sorted(SERVER_ESTIMATES.items(), key=lambda x: x[1]['tools'] * x[1]['avg_desc_tokens'], reverse=True):
tokens = est['tools'] * est['avg_desc_tokens']
total += tokens
print(f'{name:25s} {est["tools"]:3d} tools x {est["avg_desc_tokens"]:3d} tok = {tokens:5,} tokens')
print(f'{"TOTAL":25s} {"":>18s} {total:5,} tokens')Paso 3: Calcular el coste de los tokens de descripción de herramientas
Traduzca el recuento de tokens a costos reales en dólares. Con los precios actuales de LLM, los tokens de descripción de herramientas se acumulan rápidamente cuando realiza cientos de solicitudes diariamente.
def cost_analysis(servers: list[str], requests_per_day: int = 100) -> dict:
"""Calculate the real cost of MCP tool description tokens."""
total_tokens = sum(estimate_server_tokens(s) for s in servers)
# LLM input token pricing (2026 rates)
pricing = {
'gpt-4o': 2.50 / 1_000_000,
'gpt-4o-mini': 0.15 / 1_000_000,
'claude-sonnet-4': 3.00 / 1_000_000,
'claude-opus-4': 15.00 / 1_000_000,
}
results = {'total_tokens_per_request': total_tokens, 'servers': servers}
print(f'Servers: {", ".join(servers)}')
print(f'Token overhead per request: {total_tokens:,}')
print(f'\nMonthly cost at {requests_per_day} requests/day:')
for model, rate in pricing.items():
daily = total_tokens * requests_per_day * rate
monthly = daily * 30
print(f' {model:25s} ${monthly:6.2f}/month')
results[model] = monthly
return results
# Full global config: all servers
print('GLOBAL CONFIG (all servers):')
full = cost_analysis(list(SERVER_ESTIMATES.keys()), requests_per_day=200)
print()
# Scoped config: just Scavio
print('SCOPED CONFIG (Scavio only):')
scoped = cost_analysis(['scavio'], requests_per_day=200)
print()
print(f'Monthly savings with Claude Sonnet: '
f'${full.get("claude-sonnet-4",0) - scoped.get("claude-sonnet-4",0):.2f}')Paso 4: Generar recomendaciones de optimización
Analice su configuración actual y recomiende qué servidores incluir en cada proyecto. Identifique servidores que podrían ser reemplazados por Scavio para su consolidación.
def optimize_mcp(current_servers: list[str]) -> dict:
"""Generate MCP optimization recommendations."""
# Servers that Scavio can replace
replaceable = {
'brave-search': 'Scavio covers web search + 5 more platforms',
'tavily': 'Scavio provides similar web search at $0.005/credit',
'google-search': 'Scavio includes Google search',
}
recommendations = []
tokens_before = sum(estimate_server_tokens(s) for s in current_servers)
new_servers = []
scavio_added = False
for s in current_servers:
if s in replaceable:
recommendations.append({
'action': 'REPLACE',
'server': s,
'reason': replaceable[s],
'token_savings': estimate_server_tokens(s),
})
if not scavio_added:
new_servers.append('scavio')
scavio_added = True
else:
new_servers.append(s)
tokens_after = sum(estimate_server_tokens(s) for s in new_servers)
print('MCP Optimization Recommendations')
print('=' * 50)
for rec in recommendations:
print(f'REPLACE {rec["server"]} -> Scavio')
print(f' Reason: {rec["reason"]}')
print(f' Token savings: {rec["token_savings"]:,}')
print(f'\nBefore: {tokens_before:,} tokens ({len(current_servers)} servers)')
print(f'After: {tokens_after:,} tokens ({len(new_servers)} servers)')
print(f'Saved: {tokens_before - tokens_after:,} tokens/request')
return {'before': tokens_before, 'after': tokens_after, 'recommendations': recommendations}
optimize_mcp(['filesystem', 'github', 'brave-search', 'tavily', 'slack', 'memory'])Ejemplo en Python
import json, os
SERVER_TOKEN_EST = {
'filesystem': 1980, 'github': 6250, 'slack': 2400,
'brave-search': 600, 'scavio': 750, 'tavily': 560,
'memory': 750, 'postgres': 1760,
}
def audit_mcp(config_path='.mcp.json'):
if not os.path.exists(config_path):
print(f'{config_path} not found')
return
with open(config_path) as f:
servers = json.load(f).get('mcpServers', {})
total = 0
for name in servers:
tokens = SERVER_TOKEN_EST.get(name, 1000)
total += tokens
print(f' {name}: ~{tokens:,} tokens')
print(f'Total: ~{total:,} tokens per request')
print(f'Monthly cost (Sonnet, 100 req/day): ${total * 100 * 30 * 3 / 1e6:.2f}')
audit_mcp()Ejemplo en JavaScript
const fs = require('fs');
const TOKEN_EST = {
filesystem: 1980, github: 6250, slack: 2400,
'brave-search': 600, scavio: 750, tavily: 560,
memory: 750, postgres: 1760,
};
function auditMcp(configPath = '.mcp.json') {
if (!fs.existsSync(configPath)) return console.log('Config not found');
const servers = JSON.parse(fs.readFileSync(configPath, 'utf8')).mcpServers || {};
let total = 0;
for (const name of Object.keys(servers)) {
const tokens = TOKEN_EST[name] || 1000;
total += tokens;
console.log(` ${name}: ~${tokens.toLocaleString()} tokens`);
}
console.log(`Total: ~${total.toLocaleString()} tokens per request`);
console.log(`Monthly cost (Sonnet, 100 req/day): $${(total * 100 * 30 * 3 / 1e6).toFixed(2)}`);
}
auditMcp();Salida esperada
MCP Server Token Audit
==================================================
github 25 tools x 250 tok = 6,250 tokens
filesystem 11 tools x 180 tok = 1,980 tokens
slack 12 tools x 200 tok = 2,400 tokens
postgres 8 tools x 220 tok = 1,760 tokens
scavio 3 tools x 250 tok = 750 tokens
TOTAL 19,310 tokens
MCP Optimization Recommendations
==================================================
REPLACE brave-search -> Scavio
Reason: Scavio covers web search + 5 more platforms
REPLACE tavily -> Scavio
Reason: Scavio provides similar web search at $0.005/credit
Before: 15,540 tokens (6 servers)
After: 13,130 tokens (5 servers)
Saved: 2,410 tokens/requestTutoriales relacionados
- Cómo determinar el alcance de los servidores MCP por proyecto para reducir la sobrecarga de tokens
- Cómo agregar búsqueda en tiempo real a Claude a través de MCP
- Cómo determinar el alcance del acceso a los datos de los agentes para obtener mejores resultados
- Cómo agregar datos en vivo multiplataforma a cualquier agente de IA