
Herramientas MCP para Flujos de Trabajo de Clientes de Agencias de IA: Entrega Modelos como Herramientas, No como Archivos
Las agencias de IA típicamente entregan un archivo de modelo. Con MCP, puedes entregar una herramienta de Claude Desktop o Cursor que tu cliente usa diariamente — valor recurrente que justifica un retainer recurrente.
La mayoría de las agencias de IA entregan un modelo. Entregan un archivo GGUF, una guía de despliegue, un comando de Ollama. El cliente ejecuta el modelo, obtiene valor durante unas semanas, y luego el modelo queda sin usar porque integrarlo en el flujo de trabajo diario requiere un esfuerzo que el cliente no presupuestó.
MCP cambia el modelo de entrega. En lugar de entregar un archivo de modelo, entregas una herramienta de Claude Desktop o Cursor — un servidor MCP configurado que tu cliente instala en 5 minutos y usa todos los días como una extensión natural de su flujo de trabajo de IA existente.
El modelo corre en tu infraestructura. Cobras por el acceso. El valor se entrega diariamente. El retainer se justifica solo.
El Cambio en la Entrega de Agencias
Entrega antigua: Entrenar modelo → exportar GGUF → escribir guía de despliegue → el cliente averigua cómo ejecutarlo
Entrega nueva: Entrenar modelo → desplegar en tu VPS → construir servidor MCP → dar al cliente un fragmento de configuración → el cliente lo agrega a Claude Desktop → listo
La configuración del cliente son 4 líneas de JSON y un reinicio de Claude Desktop. El resto es tu infraestructura para mantener.
Construir Herramientas MCP Listas para Clientes
Arquitectura:
Client's Claude Desktop / Cursor
↓ MCP protocol
Your MCP server (hosted on your VPS)
↓ HTTP
Your Ollama instance (hosting client's fine-tuned model)
El servidor MCP maneja la autenticación (la clave API del cliente), el enrutamiento (qué modelo llamar según la identidad del cliente), y las definiciones de herramientas específicas para los casos de uso de este cliente.
Plantilla de servidor MCP multi-cliente:
// agency-mcp-server.mjs
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
// Client registry — maps API keys to model names and tool configs
const CLIENT_CONFIG = {
'client-a-key-xxxx': {
modelName: 'real-estate-client-a-v3',
tools: ['generate_listing', 'draft_followup', 'score_lead'],
clientName: 'Sunrise Realty'
},
'client-b-key-yyyy': {
modelName: 'ecommerce-client-b-v2',
tools: ['product_description', 'support_response', 'classify_ticket'],
clientName: 'BlueLine Commerce'
}
};
const TOOL_DEFINITIONS = {
generate_listing: {
name: 'generate_listing',
description: 'Generate a property listing description in our brokerage voice for Sunrise Realty.',
inputSchema: {
type: 'object',
properties: {
property_details: { type: 'string', description: 'Bedrooms, bathrooms, sqft, features, neighborhood' }
},
required: ['property_details']
}
},
draft_followup: {
name: 'draft_followup',
description: 'Draft a personalized follow-up message to a real estate contact.',
inputSchema: {
type: 'object',
properties: {
contact_context: { type: 'string', description: 'Who this is, relationship, last interaction, any news' },
goal: { type: 'string', description: 'What you want to accomplish with this message' }
},
required: ['contact_context']
}
},
// ... other tools
};
// API key is passed via environment variable in Claude Desktop config
const API_KEY = process.env.AGENCY_API_KEY;
const client = CLIENT_CONFIG[API_KEY];
if (!client) {
process.stderr.write('Invalid API key\n');
process.exit(1);
}
const server = new Server(
{ name: `agency-tools-${client.clientName}`, version: '1.0.0' },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: client.tools.map(toolName => TOOL_DEFINITIONS[toolName])
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (!client.tools.includes(name)) {
throw new Error(`Tool ${name} not available for your account`);
}
const prompt = buildPrompt(name, args);
const response = await fetch('http://localhost:11434/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: client.modelName,
messages: [{ role: 'user', content: prompt }],
stream: false
})
});
const data = await response.json();
return { content: [{ type: 'text', text: data.message.content }] };
});
function buildPrompt(toolName, args) {
const prompts = {
generate_listing: `Write a listing description for:\n${args.property_details}`,
draft_followup: `Draft a follow-up message.\nContext: ${args.contact_context}\nGoal: ${args.goal || 'Maintain relationship'}`,
// ... other prompt builders
};
return prompts[toolName] || JSON.stringify(args);
}
const transport = new StdioServerTransport();
await server.connect(transport);
Configuración del Lado del Cliente (Lo que Envías al Cliente)
// claude_desktop_config.json snippet — you provide this to client
{
"mcpServers": {
"agency-tools": {
"command": "node",
"args": ["/path/to/agency-mcp-client.mjs"],
"env": {
"AGENCY_API_KEY": "client-a-key-xxxx",
"AGENCY_SERVER_URL": "https://mcp.youragency.com"
}
}
}
}
O si empaquetas esto como un binario npm para una configuración aún más simple:
{
"mcpServers": {
"your-agency-name": {
"command": "npx",
"args": ["@youragency/mcp-client"],
"env": {
"API_KEY": "client-a-key-xxxx"
}
}
}
}
El cliente ejecuta npx @youragency/mcp-client una vez (o se auto-instala vía npx), agrega la configuración, reinicia Claude Desktop. Listo.
La Justificación del Retainer
Sin MCP: El cliente tiene un archivo GGUF. Lo ejecuta ocasionalmente. El valor es ocasional. El retainer se siente como pagar por algo que no usan diariamente.
Con MCP: El cliente usa tu herramienta cada vez que abre Claude Desktop. Cada listado que genera, cada seguimiento que redacta, cada ticket que clasifica — la herramienta de tu agencia está en el flujo de trabajo. El valor es diario y visible.
Niveles de retainer por acceso a herramientas:
- Básico ($400/mes): 2 herramientas, reentrenamiento trimestral, soporte por email
- Estándar ($700/mes): 5 herramientas, reentrenamiento mensual, soporte por Slack
- Premium ($1,200/mes): Herramientas ilimitadas, actualizaciones semanales del modelo, soporte prioritario
El marco de "herramientas" es más intuitivo para los clientes que el marco de "mantenimiento de modelo". Están pagando por acceso a herramientas que usan todos los días.
Ship AI that runs on your users' devices.
Ertas early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.
Lectura Adicional
- MCP + Modelo Local Fine-Tuned — La descripción general de la arquitectura
- Configuración de Claude Desktop con Modelo Local — Tutorial de configuración para el cliente
- Modelo de Retainer para Agencias de IA — Construir ingresos recurrentes
- Gestionar Múltiples Modelos Fine-Tuned — Gestión de modelos multi-cliente
Ship AI that runs on your users' devices.
Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.
Keep reading

How to QA a Fine-Tuned Model Before Client Delivery
A complete QA process for testing fine-tuned models before delivering them to clients — covering functional testing, edge cases, regression checks, and client acceptance criteria.

Running 10+ Fine-Tuned Models for Different Clients: Operations Guide
An operations guide for AI agencies managing 10+ fine-tuned models across multiple clients — covering model organization, resource allocation, monitoring, updates, and scaling without chaos.

AI Agency Proposal Template: How to Win Custom Model Projects
Most AI agency proposals lose because they lead with technology. Here's the structure, the writing formula, and the common mistakes that cost agencies deals.