使用 IBM Bob 构建 MCP 服务器
了解如何使用 IBM Bob 构建自定义模型上下文协议 (MCP) 服务器,将 AI 模型连接到外部工具和数据源。本实践教程涵盖高级模式、审批工作流和 MCP 配置。
在本教程中,你将使用 IBM Bob 构建一个自定义 MCP 服务器,该服务器提供对 arXiv 的只读访问权限——arXiv 是一个面向科学论文的开放访问内容存储库。你也可以选择扩展该服务器,将其与 watsonx Orchestrate AI 智能体集成。
模型上下文协议 (MCP) 是一种开放标准,使大型语言模型 (LLM) 能够通过统一的客户端-服务器架构与外部工具、数据源和内容存储库进行通信。在 MCP 出现之前,每个 AI 助手都需要为每个外部工具建立自己专用的集成,使用 function calling 且无法互操作。MCP 则定义了一种单一的 JSON-RPC 2.0 协议,任何 MCP 主机都可以用它连接到任何 MCP 服务器。
前提条件
本教程构建一个查询 arXiv API 的 TypeScript MCP 服务器,无需 TypeScript 或 MCP 集成经验。
完成本教程需要以下内容:
IBM Bob IDE
在你的计算机上下载并安装 IBM Bob 应用程序。Bob 是一款独立的 IDE 应用程序,而非扩展。
Node.js
安装 Node.js 22 或更高版本,以便在本地构建和运行 TypeScript MCP 服务器。
设置工作区
启动 IBM Bob,打开 MCP 设置面板,并为服务器项目准备一个工作目录。
启动 IBM Bob
在你的计算机上启动 IBM Bob 应用程序。
打开 Bob 聊天面板
如果聊天面板尚未打开,请点击导航栏旁的 Bob 图标,或使用快捷键 Option + Command + B(Mac)或 Ctrl + Alt + B(Windows)。
打开 MCP 设置面板
点击聊天窗口右上角的齿轮图标,然后从左侧边栏选择 MCP。
MCP 设置面板通过启用或禁用服务器、自动批准特定工具、以及使用 MCP SDK 构建自定义集成来管理访问控制。
- 全局:存储在
mcp_settings.json中,应用于所有工作区。 - 项目:存储在项目根目录的
.bob/mcp.json中,可通过版本控制与团队共享。项目级设置会覆盖全局设置。
配置自动批准
在 Bob 聊天中,确保聊天输入框下方的自动批准权限仅设置为"Read"。此配置让 Bob 可以查看你的文件和目录内容,同时在每次运行命令前请求你的审查和批准。
打开项目目录
如果你有项目的首选目录,请在 IDE 中打开它。你也可以在聊天窗口中让 Bob 来完成这一步。
设置 Python 虚拟环境
创建 Python 虚拟环境是隔离项目依赖项的常见做法,可避免不同项目之间的冲突。将 Bob 切换到 Agent 模式(该模式可读取、写入和运行终端命令),然后创建环境。
创建并激活虚拟环境
在 Bob 聊天面板中输入以下 prompt:
In this directory, activate a Python virtual environment.Bob 会运行一系列终端命令。在每次提示时批准。这些命令会在 venv/ 目录中创建一个新的虚拟环境并将其激活。
生成 MCP 服务器构建计划
切换到 Plan 模式
点击聊天输入框下方的按钮,将交互模式更改为 Plan。此模式让 Bob 在编写任何代码之前为 MCP 服务器生成结构化计划。
提交服务器需求
在虚拟环境激活的情况下,向 Bob 提交以下 prompt。提前提供具体需求,让 Bob 在编写任何代码之前有足够的上下文来制定完整计划:
Create an MCP server named arxiv-server that provides read-only access to arXiv. The server should:
- Expose one tool, search_papers, for querying arXiv papers by keyword
- Accept a query string and an optional max_results parameter (default 5, max 20)
- Limit results to paper metadata and abstracts (no PDFs)
- Return title, authors, publication date, abstract, and arXiv URL for each result
- Normalize responses into a clean, structured JSON schema
- Handle API errors and empty results gracefully, returning a clear message instead of failing
- Use TypeScript/Node.js with the stdio transport
- Use the arXiv API v2, which requires no authenticationBob 会生成一个结构化的待办事项列表,涵盖项目脚手架、MCP 服务器实现、依赖项安装、服务器配置和测试。注意,Bob 会自动规划错误处理和身份验证考虑事项。即使目标 API(arXiv)不需要密钥,Bob 也会标注在需要认证的服务器中凭据的注入位置。
如果 Bob 提出澄清问题,请尽量回答,或告诉 Bob 做出合理假设。
构建和审查 MCP 服务器
审查并批准计划后,切换到 Agent 模式来执行每个步骤。由于 Bob 实时生成响应,你的输出和顺序可能与以下示例略有不同。
用以下 prompt 告诉 Bob 开始构建服务器:
Implement the plan.首先,Bob 搭建项目结构并运行 mkdir -p arxiv-server/src 创建项目目录。
接下来,Bob 生成 arxiv-server/package.json——Node.js 配置中心,用于声明项目的元数据、脚本和依赖项:
{
"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"
},
"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"
}
}Bob 还会创建 arxiv-server/tsconfig.json 来配置 TypeScript 编译器:
{
"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"]
}接下来,Bob 在 arxiv-server/src/index.ts 创建主服务器文件。该文件使用 MCP SDK 注册 search_arxiv 工具,为 arXiv 的 API 响应实现 XML 到 JSON 的解析,强制执行结果限制,并在 STDIO transport 上启动服务器——STDIO 是适合在与 MCP 主机同一台机器上运行的服务器的本地低延迟传输类型。
MCP SDK 的 server.tool() 调用是主要的集成点,它将工具暴露给任何 MCP 客户端。
#!/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';
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;
}
const server = new McpServer({ name: "arxiv-server", version: "0.1.0" });
const arxivApi = axios.create({
baseURL: 'http://export.arxiv.org/api',
timeout: 30000,
});
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 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(),
sort_order: z.enum(["ascending", "descending"]).optional()
},
async ({ query, max_results = 10, start = 0, sort_by = "relevance", sort_order = "descending" }) => {
try {
const params: Record<string, string | number> = {
search_query: query,
start: Math.max(start, 0),
max_results: Math.min(max_results, 50),
...(sort_by && { sortBy: sort_by }),
...(sort_order && { sortOrder: sort_order }),
};
const response = await arxivApi.get('/query', { params });
return {
content: [{ type: "text", text: formatSearchResults(parseArxivXML(response.data)) }],
};
} catch (error) {
if (axios.isAxiosError(error)) {
return {
content: [{ type: "text", text: `arXiv API error: ${error.response?.data?.message ?? error.message}` }],
isError: true,
};
}
throw error;
}
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('arXiv MCP server running on stdio');catch 块中的 isError: true 标志是 MCP 的标准错误处理模式。它向 MCP 客户端发出信号,表明工具调用失败,而不会导致服务器进程崩溃。
下一步,Bob 通过运行 cd arxiv-server && npm install 在 arxiv-server 目录中安装依赖项。
在项目范围内注册服务器
Bob 不会自动注册新服务器。明确告诉 Bob 添加它,并指定项目范围,使配置存储在 .bob/mcp.json 中,并可通过版本控制与团队共享。
告诉 Bob 注册服务器
在 Bob 聊天面板中输入以下 prompt:
Register the arxiv-server as an MCP server at project scope. Build it first if needed, then add it to .bob/mcp.json.审查生成的配置
Bob 将以下内容写入项目根目录的 .bob/mcp.json。command 和 args 字段告诉 MCP 客户端如何使用 STDIO transport 启动服务器进程。
{
"mcpServers": {
"arxiv-server": {
"command": "node",
"args": ["${workspaceFolder}/arxiv-server/build/index.js"]
}
}
}确认服务器已加载
Bob 写入此文件后会自动重新加载 MCP 配置。打开 MCP 设置面板(齿轮图标 > MCP)确认 arxiv-server 服务器已列出并启用,然后再继续。如果未显示,请点击服务器列表旁的重新加载图标。
重启 Bob
重启 Bob 以确保服务器正在运行并准备好接受查询。
测试 MCP 服务器
注册服务器后,Bob 会自动对 search_arxiv 工具运行两个验证查询。
第一个测试查询三篇按相关性排序的量子计算论文,第二个查询两篇按提交日期降序排列的机器学习论文。两个查询均成功执行,确认工具可访问且服务器的错误处理能正确管理不同的参数组合。
现在运行你自己的查询,验证 Bob 能否从自然语言中提取正确的参数。可以将以下示例 prompt 粘贴到 Bob 聊天面板中:
What are the latest papers on LLM agent tracing?为服务器编写文档
开源 MCP 服务器实现通常包含文档,让他人能够快速上手。让 Bob 来生成:
In this directory, create a README.md file to document this MCP server.
Include setup and usage instructions.Bob 会生成一份全面的 README.md,涵盖安装、多个 MCP 主机的配置(IBM Bob、Claude Desktop、Cursor、Claude Code)、需要 API 密钥的服务器的认证指南、本地文件访问模式和故障排除技巧。
清理资源
本教程会创建本地文件和服务器注册。如果你不打算继续使用 arXiv MCP 服务器,请将其删除。
在 Bob 中打开 MCP 设置面板(齿轮图标 > MCP),禁用或删除 arxiv-server 条目。或者,直接从 mcp_settings.json(全局范围)或 .bob/mcp.json(项目范围)中删除 arxiv-server 块。
后续步骤
在本教程中,你使用 IBM Bob 构建了一个 TypeScript MCP 服务器,使用 STDIO transport 对其进行配置,并通过实时 arXiv 查询对其进行测试——所有这些都通过自然语言 prompt 完成。
同样的工作流程适用于更复杂的 MCP 服务器实现:连接到数据库、本地文件或任何其他外部数据源的服务器。需要身份验证的服务器需要将凭据作为环境变量注入 MCP 配置 JSON 中。对于远程部署,将 STDIO transport 替换为 SSE。
- 了解 Bob 的 Code review 功能,在提交服务器代码之前发现问题。
- 了解模式,理解何时使用 Advanced、Code、Ask 和其他 Bob 角色。
- 探索 MCP 配置,了解全局与项目范围、自动批准工具和 SSE transport 设置的详细信息。
- 继续学习 IBM Bob 入门教程系列。