El Model Context Protocol (MCP) surgió a raíz del problema de la incompatibilidad. En nuestra vida cotidiana, la incompatibilidad nos incomoda de varias maneras.
¿Alguna vez llevó una herramienta para el cabello o un dispositivo electrónico cuando fue a otro país y se dio cuenta de que su enchufe no es compatible con la toma de corriente? Desde la perspectiva del desarrollador, este problema es tan frustrante como la creación de API y herramientas de desarrollo para su agente de IA a las que parece que no puede conectarse ni invocar correctamente. Ahí es exactamente donde el MCP alivia este problema de incompatibilidad.
El Model Context Protocol (MCP), introducido por Anthropic en 2024, sirve como una capa de estandarización para que las aplicaciones de IA se comuniquen eficazmente con servicios externos como herramientas, fuentes de datos/conjuntos de datos y plantillas predefinidas. El MCP sirve esencialmente como un estándar abierto y un conector para las interacciones entre la IA y las herramientas. La arquitectura del MCP se puede dividir en tres componentes arquitectónicos clave:
Primero, ¿qué es IBM Bob? IBM Bob es un entorno de desarrollo de integración (IDE) y modernización impulsado por IA generativa. Piense en Bob como su IDE que prioriza la IA y desarrollador de pares: una herramienta que comprende su intención, su base de código y los estándares de su organización.
Crear su propio servidor MCP desde cero puede llevar mucho tiempo, especialmente para los desarrolladores principiantes. En cambio, en este tutorial, exploraremos cómo iniciar rápidamente este flujo de trabajo con IBM Bob utilizando algunas instrucciones simples en lenguaje natural.
La integración MCP amplía la funcionalidad de Bob al conectarse a herramientas y servicios externos, configurables a nivel global (se aplica en todos los espacios de trabajo) o de proyecto (compartible en equipo a través de .Bob/mcp.json) . El MCP admite dos tipos de transporte: entrada/salida estándar (STDIO) para servidores locales de baja latencia y eventos enviados por el servidor (SSE) para servidores MCP remotos accesibles a través de HTTP/HTTPS. Los usuarios pueden configurar servidores con archivos JSON en el menú de configuración de Bob, definiendo comandos, variables de entorno y herramientas aprobadas automáticamente. Ambos tipos de transporte le permiten habilitar o deshabilitar servidores, aprobar automáticamente herramientas específicas y gestionar su operación a través del panel de configuración del MCP de Bob.
Comencemos. Si prefiere seguir este tutorial en GitHub, revise nuestro repositorio.
1. Continúe y abra el IDE de IBM Bob que instaló como requisito previo y familiarícese con el diseño de su nuevo asistente de programación de IA.
2. Para acceder al panel de configuración del MCP, haga clic en los 3 puntos junto al icono de ajustes en la esquina superior derecha de la ventana de chat. A continuación, seleccione Servidores del MCP en el menú desplegable.
Aquí, podemos habilitar o deshabilitar el MCP globalmente o por servidor y gestionar herramientas (por ejemplo, aprobación automática, eliminación o reinicio). También podemos explorar servidores comunitarios a través de Bob Marketplace o crear los propios con el SDK del MCP.
Si elige instalar un servidor de Bob Marketplace, notará que las configuraciones se pueden establecer en dos niveles: global (almacenado en
La configuración a nivel de proyecto anula los globales, lo que le brinda flexibilidad para adaptar el comportamiento del MCP a diferentes casos de uso. Para gestionar estas configuraciones, puede editar archivos JSON directamente a través del menú de configuración de Bob, donde define detalles del servidor como comandos, variables de entorno y herramientas aprobadas automáticamente. En este tutorial, usaremos el SDK.
3. Asegúrese de que la opción Habilitar creación de servidores MCP esté activa para crear servidores MCP personalizados con Bob.
4. Si tiene un directorio preferido para configurar su proyecto, puede abrirlo dentro del IDE o hacer que Bob lo haga por usted en la ventana de chat.
3. Es una práctica común crear entornos virtuales de Python para aislar las dependencias de un proyecto, de modo que los diferentes proyectos no entren en conflicto entre sí. Para ello, ingrese la instrucción: “En este directorio, activa un entorno virtual Python”.
4. Debería ver a Bob ejecutar una serie de comandos de terminal. Es probable que estos comandos sean similares a lo siguiente:
Le recomendamos que mantenga desactivado el conmutador de aprobación automática para que pueda aprobar o denegar cada comando antes de que Bob lo ejecute en tiempo real.
Excelente. Bob creó y activó correctamente un nuevo entorno virtual en el directorio
Con nuestro entorno virtual configurado, ahora podemos empezar con la creación del servidor MCP. Cuando se le pide a Bob que genere código, o cualquier modelo o asistente de IA, es útil incluir detalles importantes. Para ver a Bob en acción, enviemos la instrucción:
“Crea un servidor MCP que proporcione acceso de solo lectura a arXiv. El servidor debe:
Con esta sencilla instrucción, Bob tiene información suficiente para comprender la tarea y formular una lista de pasos de tareas para completarla. Tenga en cuenta que la lista incluye no solo la creación del servidor MCP, sino también su configuración y pruebas. Ordenado.
Tenga en cuenta que utilizamos la API de arXiv en este tutorial como un ejemplo simple que no requiere ninguna clave de API ni autenticación para comenzar. Sin embargo, este es un ejemplo y Bob también está bien equipado para manejar servidores más complejos con los permisos requeridos.
Antes de ejecutar cada comando, podemos aprobar o denegar la acción. Si observa que los comandos se ejecutan automáticamente, es posible que tenga habilitado el conmutador de aprobación automática.
2. A continuación, Bob crea un archivo
{
"name": "arxiv-server",
"version": "0.1.0",
"description": "MCP server for read-only access to arXiv papers",
"type": "module",
"bin": {
"arxiv-server": "./build/index.js"
},
"files": [
"build"
],
"scripts": {
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
"prepare": "npm run build",
"watch": "tsc --watch"
},
"keywords": [
"mcp",
"arxiv",
"research",
"papers"
],
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.4",
"axios": "^1.7.9",
"zod": "^3.24.1"
},
"devDependencies": {
"@types/node": "^22.10.5",
"typescript": "^5.7.3"
}
}
arxiv-server/tsconfig.json{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "build"]
}
4. Luego, la implementación del servidor principal con la funcionalidad de búsqueda arXiv se almacena en
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import axios from 'axios';
// Define types for arXiv API responses
interface ArxivEntry {
id: string;
title: string;
summary: string;
authors: Array<{ name: string }>;
published: string;
updated: string;
categories: string[];
primary_category: string;
links: Array<{ href: string; rel: string; type?: string }>;
}
interface ArxivSearchResult {
entries: ArxivEntry[];
totalResults: number;
startIndex: number;
itemsPerPage: number;
}
// Create an MCP server
const server = new McpServer({
name: "arxiv-server",
version: "0.1.0"
});
// Create axios instance for arXiv API
const arxivApi = axios.create({
baseURL: 'http://export.arxiv.org/api',
timeout: 30000,
});
/**
* Parse arXiv API XML response to JSON
*/
function parseArxivXML(xmlData: string): ArxivSearchResult {
const entries: ArxivEntry[] = [];
// Extract total results
const totalResultsMatch = xmlData.match(/<opensearch:totalResults[^>]*>(\d+)<\/opensearch:totalResults>/);
const totalResults = totalResultsMatch ? parseInt(totalResultsMatch[1]) : 0;
const startIndexMatch = xmlData.match(/<opensearch:startIndex[^>]*>(\d+)<\/opensearch:startIndex>/);
const startIndex = startIndexMatch ? parseInt(startIndexMatch[1]) : 0;
const itemsPerPageMatch = xmlData.match(/<opensearch:itemsPerPage[^>]*>(\d+)<\/opensearch:itemsPerPage>/);
const itemsPerPage = itemsPerPageMatch ? parseInt(itemsPerPageMatch[1]) : 0;
// Extract entries
const entryRegex = /<entry>([\s\S]*?)<\/entry>/g;
let entryMatch;
while ((entryMatch = entryRegex.exec(xmlData)) !== null) {
const entryXml = entryMatch[1];
// Extract ID
const idMatch = entryXml.match(/<id>([^<]+)<\/id>/);
const id = idMatch ? idMatch[1] : '';
// Extract title
const titleMatch = entryXml.match(/<title>([^<]+)<\/title>/);
const title = titleMatch ? titleMatch[1].trim().replace(/\s+/g, ' ') : '';
// Extract summary
const summaryMatch = entryXml.match(/<summary>([^<]+)<\/summary>/);
const summary = summaryMatch ? summaryMatch[1].trim().replace(/\s+/g, ' ') : '';
// Extract authors
const authors: Array<{ name: string }> = [];
const authorRegex = /<author>\s*<name>([^<]+)<\/name>/g;
let authorMatch;
while ((authorMatch = authorRegex.exec(entryXml)) !== null) {
authors.push({ name: authorMatch[1].trim() });
}
// Extract published date
const publishedMatch = entryXml.match(/<published>([^<]+)<\/published>/);
const published = publishedMatch ? publishedMatch[1] : '';
// Extract updated date
const updatedMatch = entryXml.match(/<updated>([^<]+)<\/updated>/);
const updated = updatedMatch ? updatedMatch[1] : '';
// Extract categories
const categories: string[] = [];
const categoryRegex = /<category[^>]+term="([^"]+)"/g;
let categoryMatch;
while ((categoryMatch = categoryRegex.exec(entryXml)) !== null) {
categories.push(categoryMatch[1]);
}
const primary_category = categories[0] || '';
// Extract links
const links: Array<{ href: string; rel: string; type?: string }> = [];
const linkRegex = /<link[^>]+href="([^"]+)"[^>]+rel="([^"]+)"(?:[^>]+type="([^"]+)")?/g;
let linkMatch;
while ((linkMatch = linkRegex.exec(entryXml)) !== null) {
links.push({
href: linkMatch[1],
rel: linkMatch[2],
type: linkMatch[3]
});
}
entries.push({
id,
title,
summary,
authors,
published,
updated,
categories,
primary_category,
links
});
}
return {
entries,
totalResults,
startIndex,
itemsPerPage
};
}
/**
* Format search results for display
*/
function formatSearchResults(result: ArxivSearchResult): string {
let output = `Found ${result.totalResults} results (showing ${result.entries.length})\n\n`;
result.entries.forEach((entry, índice) => {
output += `${index + 1}. ${entry.title}\n`;
output += ` ID: ${entry.id}\n`;
output += ` Authors: ${entry.authors.map(a => a.name).join(', ')}\n`;
output += ` Published: ${entry.published}\n`;
output += ` Categories: ${entry.categories.join(', ')}\n`;
output += ` Abstract: ${entry.summary.substring(0, 300)}${entry.summary.length > 300 ? '...' : ''}\n`;
// Find abstract link (not PDF)
const abstractLink = entry.links.find(l => l.rel === 'alternate');
if (abstractLink) {
output += ` URL: ${abstractLink.href}\n`;
}
output += '\n';
});
return output;
}
// Add a tool for searching arXiv papers
server.tool(
"search_arxiv",
{
query: z.string().describe("Search query (supports arXiv query syntax)"),
max_results: z.number().min(1).max(50).optional().describe("Maximum number of results to return (1-50, default: 10)"),
start: z.number().min(0).optional().describe("Starting index for pagination (default: 0)"),
sort_by: z.enum(["relevance", "lastUpdatedDate", "submittedDate"]).optional().describe("Sort order (default: relevance)"),
sort_order: z.enum(["ascending", "descending"]).optional().describe("Sort direction (default: descending)")
},
async ({ query, max_results = 10, start = 0, sort_by = "relevance", sort_order = "descending" }) => {
try {
// Enforce reasonable limits
const limitedMaxResults = Math.min(max_results, 50);
const limitedStart = Math.max(start, 0);
// Build query parameters
const params: Record<string, string | number> = {
search_query: query,
start: limitedStart,
max_results: limitedMaxResults,
};
if (sort_by) {
params.sortBy = sort_by;
}
if (sort_order) {
params.sortOrder = sort_order;
}
const response = await arxivApi.get('/query', { params });
// Parse XML response
const result = parseArxivXML(response.data);
// Format results
const formattedResults = formatSearchResults(result);
return {
content: [
{
type: "text",
text: formattedResults,
},
],
};
} catch (error) {
if (axios.isAxiosError(error)) {
return {
content: [
{
type: "text",
text: `arXiv API error: ${error.response?.data?.message ?? error.message}`,
},
],
isError: true,
};
}
throw error;
}
}
);
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('arXiv servidor MCP ejecutándose en stdio'); // Made with Bob
En esta etapa, si su servidor requiere alguna clave API, Bob se la pedirá.
5. Como siguiente paso, Bob instala las dependencias dentro del directorio arxiv-server ejecutando el siguiente comando.
mcp_settings.json.Bob/mcp.json{
"mcpServers": {}
"mcpServers": {
"arxiv": {
"command": "node",
"args": [ "/here/is/the/path/to/arxiv-server/build/index.js"
],
"disabled": false,
"alwaysAllow": [],
"disabledTools": []
}
}
}
Esta información completa la serie de pasos que toma Bob para configurar el servidor MCP.
Para completar la serie de tareas de la “lista de tareas”, Bob prueba el servidor MCP. Como se ve en la captura de pantalla anterior, Bob consulta la herramienta
Después de la ejecución exitosa, que puede ver haciendo clic en la zanahoria hacia abajo para expandir la ventana, Bob realizó otra prueba. Esta vez, la consulta es para 2 documentos de machine learning ordenados por fecha de envío descendente. Incluso con el uso de los diferentes parámetros, esta llamada a la herramienta MCP también se ejecutó correctamente.
Dado el éxito de las pruebas, Bob completó todas las subtareas.
Bob ya probó el servidor MCP por nosotros. Sin embargo, probemos algunas consultas propias en la ventana de chat para ver si Bob puede extrapolar los términos de búsqueda correctos y los parámetros necesarios.
Pregúntele a Bob: “¿Cuáles son los documentos más recientes sobre el rastreo de agentes de LLM?”
Por su cuenta, Bob extrajo la consulta correcta de nuestra instrucción y agregó algunas palabras clave adicionales para mejorar la búsqueda. Bob también estableció el número máximo de resultados en 10 y clasificó los documentos por relevancia. Excelente.
Probemos una consulta más.
Curiosamente, Bob modificó de manera automática la consulta de búsqueda al notar resultados no deseados. Bob no ejecuta llamadas a herramientas a ciegas, sino que colabora con el usuario como un agente útil. Después de dos iteraciones de esto, Bob devolvió varios documentos que se alinean bien con nuestra tarea inicial.
Muchos servidores MCP de código abierto también incluyen documentos para que otros puedan comenzar fácilmente. Peguemos esta instrucción en la ventana de chat:
“En este directorio, crea un archivo README.md para documentar este servidor MCP. Incluye instrucciones de configuración y uso”.
Con una simple instrucción, Bob creó un documento
¿Quizás le interese crear un agente de IA especializado en investigación con watsonx Orchestrate que pueda acceder a este servidor MCP? Bob puede crear un agente con tan solo una simple instrucción. En primer lugar, instale el servidor predefinido watsonx Orchestrate ADK desde el Marketplace que encontrará en el panel de configuración del MCP que exploramos en el paso 1. Luego, envíe este comando:
“Crea un agente de watsonx Orchestrate que utilice este servidor arxiv MCP”.
Si tiene el servicio watsonx Orchestrate ejecutado localmente, Bob ejecutará los comandos necesarios por usted. Si prefiere ejecutar los comandos más tarde, Bob escribirá los scripts y documentará los comandos necesarios.
Veamos cada archivo para entender mejor qué generó Bob. Este es el archivo toolkit-config.yaml
kind: mcp
name: arxiv-toolkit
description: Toolkit for searching arXiv research papers. Provides access to paper metadata, abstracts, and publication information from the arXiv database.
package_root: /local/path/to/arxiv-server
language: node
command: node /local/path/to/arxiv-server/arxiv-server/build/index.js
tools:
- "*"
# Made with Bob
A continuación, abramos el archivo research-assistant-agent.yaml
name: research-assistant
kind: native
description: AI research assistant that helps find and summarize academic papers from arXiv. Specializes in searching scientific literature, explaining research findings, and providing citations.
title: Research Assistant
instructions: |
You are an expert research assistant specializing in academic literature search on arXiv.
## Your Capabilities
- Search arXiv for papers on any scientific topic
- Summarize research findings from abstracts in plain language
- Identify key authors and research trends
- Suggest related papers and topics
- Provide proper citations with arXiv IDs and URLs
## When Responding to Users
1. Always provide arXiv IDs and direct URLs to papers
2. Summarize abstracts in accessible language
3. Highlight key contributions and findings
4. Suggest follow-up searches when relevant
5. Be concise but informative
## Using the search_arxiv Tool
Available parameters:
- query (required): Search query using arXiv syntax
- max_results (optional): 1-50 papers, default 10
- start (optional): Starting index for pagination, default 0
- sort_by (optional): "relevance", "submittedDate", or "lastUpdatedDate"
- sort_order (optional): "ascending" or "descending"
## Advanced Search Syntax
You can use these operators in queries:
- ti:keyword - Search in title
- au:author - Search by author name
- abs:keyword - Search in abstract
- cat:category - Filter by category (e.g., cs.AI, quant-ph, math.CO)
- AND, OR, ANDNOT - Boolean operators
Examples:
- "ti:transformer AND cat:cs.LG" - Transformer papers in machine learning
- "au:Hinton" - Papers by Geoffrey Hinton
- "quantum computing AND cat:quant-ph" - Quantum computing in quantum physics
## Common Categories
- cs.AI - Artificial Intelligence
- cs.LG - Machine Learning
- cs.CL - Computation and Language
- cs.CV - Computer Vision
- quant-ph - Quantum Physics
- math.CO - Combinatorics
- stat.ML - Machine Learning (Statistics)
## Response Format
When presenting papers, use this format:
**"Paper Title"**
- Authors: [Author names]
- Published: [Date]
- Categories: [Categories]
- Summary: [Brief summary of abstract]
- [View paper](arXiv URL)
## Handling Edge Cases
- If no results found: Suggest alternative search terms or broader queries
- If too many results: Recommend narrowing the search with categories or date filters
- If user asks for PDFs: Explain you provide metadata only, but include the URL where they can access the paper
- If unclear query: Ask clarifying questions about the research area or specific interests
tools:
- search_arxiv
config:
hidden: false
enable_cot: true
tags:
- research
- academic
- papers
- arxiv
- literature-search
# Made with Bob
Este archivo YAML configura nuestro asistente de investigación, un agente de IA especializado que agiliza la investigación académica buscando en arXiv, resumiendo artículos y proporcionando citas en un formato estructurado. Se incluyen instrucciones detalladas que guían el comportamiento del agente, desde la sintaxis de la consulta y el uso de herramientas hasta el formato de respuestas y el manejo de casos extremos. Toda esta información se detalla con la herramienta search_arxivsetup-instructions.md
En este tutorial, utilizamos IBM Bob, un desarrollador de IDE y pares que da prioridad a la IA, para optimizar la integración del MCP para la investigación académica. Construyó de manera eficiente un servidor MCP escalable capaz de buscar y recuperar documentos del repositorio arXiv.org. Ahora, su solución está lista para la producción, ya sea que elija abrir el código abierto para la investigación o desplegarla dentro de sus aplicaciones para mejorar el descubrimiento de conocimientos.
La verdadera magia de IBM Bob radica en su capacidad para transformar tareas de desarrollo complejas en flujos de trabajo intuitivos y basados en instrucciones. Con solo unas pocas entradas estratégicas, Bob acelera la creación de prototipos, reduce el código repetitivo e incluso sugiere optimizaciones, lo que le permite centrarse en la innovación en lugar de la implementación.
A medida que continúe explorando sus capacidades, considere cómo Bob puede refinar aún más su servidor MCP. Entre los beneficios podemos incluir filtrado avanzado, actualizaciones en tiempo real o integración con otras bases de datos académicas como PubMed o IEEE Xplore. Todas estas opciones, y muchas más, son posibles con unas sencillas instrucciones utilizando IBM Bob.
¿Desea dar el siguiente paso? Experimente con la personalización de su servidor MCP o profundice en las características de Bob para desbloquear aún más potencial de automatización. ¡Feliz programación!
Cree, implemente y gestione poderosos asistentes y agentes de IA que automaticen flujos de trabajo y procesos con IA generativa.
Construya el futuro de su empresa con soluciones de IA en las que pueda confiar.
Los servicios de IA de IBM Consulting ayudan a reinventar la forma en que las empresas trabajan con IA para la transformación.