Token导航 LogoToken导航TokenDH.com
MCP Tool Router logo
AI代理未说明官方级别未说明来源级核验

MCP Tool Router

MCP Server

聚合多个MCP服务器的工具到一个统一的命名空间,解决工具名称冲突和上下文窗口膨胀问题。

工具数

0

提示词数

0

GitHub Stars

0

资源数

0
TypeScript中间件AI代理

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

SiluPanda

提供方

SiluPanda

最后核验

2026/5/17 20:20

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

mcp工具路由器

将来自多个MCP服务器的工具聚合到一个统一的命名空间中。

](https://www.npmjs.com/package/mcp-tool-router) ](https://www.npmjs.com/package/mcp-tool-router) ![license](https://github.com/SiluPanda/mcp-tool-router/blob/master/LICENSE) ](https://nodejs.org) ![TypeScript](https://www.typescriptlang.org/)

______________________________________________________________________

描述

mcp-tool-router 是MCP(模型上下文协议)服务器的程序化路由器和聚合器。它连接到多个上游MCP服务器,将它们的工具合并到一个统一的命名空间中,并根据命名空间前缀将工具调用路由到正确的上游。下游客户端从一个路由器看到一个工具列表——它不知道存在多个后端。

当LLM代理或MCP主机同时连接到许多MCP服务器时,会出现两个问题。首先,每个服务器的工具列表都被注入到上下文窗口中,在用户键入单个消息之前消耗数万个令牌。其次,工具名称冲突——两个服务器都公开了一个 search 工具强制临时消歧。

mcp-tool-router 在路由级别解决了这两个问题。来自每个上游的工具都使用可配置的前缀和分隔符进行命名空间(例如。, github/create_issue, jira/search),通过施工消除碰撞。选择性转发允许路由器仅公开每个上游工具的子集,从而减少上下文膨胀。中间件拦截用于日志记录、访问控制或参数注入的工具调用。

该架构反映了在相邻域中证明的模式:GraphQL联邦在网关后面合并子图模式,Envoy在单个入口后面反向代理HTTP微服务,以及 mcp-tool-router 使用基于前缀的路由在单个虚拟服务器后面组成MCP服务器。

关键设计决策

  • 零运行时依赖关系 --仅使用 node:events 来自Node.js
  • ES2022目标,CommonJS模块格式
  • TypeScript严格模式 全类型出口
  • 仅路由层 --提供与任何MCP服务器框架集成的工具调度逻辑

______________________________________________________________________

安装

npm install mcp-tool-router

需要Node.js>=18。

______________________________________________________________________

快速开始

import { ToolRouter } from 'mcp-tool-router';

const router = new ToolRouter({
  name: 'my-router',
  version: '1.0.0',
  separator: '/',
  conflictResolution: 'prefix',
});

// Register upstream servers with their tools and handlers
router.addServer('github', {
  tools: [
    { name: 'create_issue', description: 'Create a GitHub issue', inputSchema: { type: 'object', properties: { title: { type: 'string' } }, required: ['title'] } },
    { name: 'search', description: 'Search repositories' },
  ],
  handler: async (toolName, args) => {
    // Forward to actual MCP server or implement directly
    return { content: [{ type: 'text', text: `GitHub ${toolName}: ${JSON.stringify(args)}` }] };
  },
});

router.addServer('jira', {
  tools: [
    { name: 'create_ticket', description: 'Create a Jira ticket' },
    { name: 'search', description: 'Search Jira issues' },
  ],
  handler: async (toolName, args) => {
    return { content: [{ type: 'text', text: `Jira ${toolName}: ${JSON.stringify(args)}` }] };
  },
});

// Tools are namespaced automatically:
// github/create_issue, github/search, jira/create_ticket, jira/search
const tools = router.listTools();
console.log(tools.map(t => t.namespacedName));

// Route calls to the correct upstream server
const result = await router.callTool('github/create_issue', { title: 'Bug report' });

______________________________________________________________________

特性

命名空间管理

每个上游服务器的工具都以服务器名称(或自定义前缀)和可配置的分隔符作为前缀,以防止名称冲突。

// Default: server name is used as prefix
router.addServer('github', { tools, handler });
// Tool exposed as: github/create_issue

// Custom prefix
router.addServer('postgres', { tools, handler }).namespace('pg');
// Tool exposed as: pg/query

// Disable namespacing (use with caution -- collisions possible)
router.addServer('local', { tools, handler }).namespace(null);
// Tool exposed as: my_tool (original name, no prefix)

自定义分隔符

const dotRouter = new ToolRouter({ separator: '.' });
// Tools: github.create_issue, github.search

const dunderRouter = new ToolRouter({ separator: '__' });
// Tools: github__create_issue, github__search

const colonRouter = new ToolRouter({ separator: '::' });
// Tools: github::create_issue, github::search

工具筛选

控制每个上游的哪些工具暴露在外。过滤器支持精确的名称和glob模式(* 匹配任何字符, ? 匹配单个字符)。首先应用包含模式,然后应用排除模式,最后应用谓词函数。

// Include only specific tools (glob patterns supported)
router.addServer('github', { tools, handler })
  .include(['create_*', 'search']);

// Exclude dangerous tools
router.addServer('postgres', { tools, handler })
  .exclude(['drop_*', 'truncate_*']);

// Full filter config with predicate function
router.addServer('db', { tools, handler })
  .filter({
    include: ['*'],
    exclude: ['internal_*'],
    predicate: (tool) => !tool.annotations?.destructiveHint,
  });

工具别名

重命名工具以获得更短或更清晰的名称。当工具被别名化时,原始的命名空间名称将从工具列表中删除,只显示别名。

// Router-level alias: replaces the namespaced name entirely
router.alias('search', 'github/search_repositories');
// "github/search_repositories" is removed, "search" is exposed

// Server-level alias via the builder
router.addServer('github', { tools, handler })
  .alias('find', 'search_repositories');
// "github/search_repositories" is removed, "find" is exposed

中间件

拦截工具调用日志记录、访问控制、参数注入或响应修改。中间件遵循 (context, next) => response 图案。特定于服务器的中间件先于全局中间件运行。

// Global middleware: applies to all tool calls
router.use(async (ctx, next) => {
  console.log(`Calling ${ctx.namespacedName} on ${ctx.upstreamName}`);
  const result = await next();
  console.log(`Completed in context of ${ctx.upstreamName}`);
  return result;
});

// Server-specific middleware via the builder
router.addServer('db', { tools, handler })
  .use(async (ctx, next) => {
    if (ctx.toolDefinition.annotations?.destructiveHint) {
      return {
        content: [{ type: 'text', text: 'Denied: destructive operations are blocked' }],
        isError: true,
      };
    }
    return next();
  });

// Short-circuit: return without calling next() to skip the upstream
router.use(async (ctx, next) => {
  if (ctx.namespacedName === 'cached/tool') {
    return { content: [{ type: 'text', text: 'cached result' }] };
  }
  return next();
});

冲突解决

当来自不同服务器的工具共享相同的限定名时(通常在使用 null 前缀)。

// 'prefix' (default): tools are namespaced; collision on identical qualified names throws
const router = new ToolRouter({ conflictResolution: 'prefix' });

// 'first-wins': the first registered tool keeps the name, duplicates are silently dropped
const router2 = new ToolRouter({ conflictResolution: 'first-wins' });

// 'error': throw CollisionError immediately on any collision
const router3 = new ToolRouter({ conflictResolution: 'error' });

指标

跟踪每台服务器的呼叫计数、延迟和错误率。

const metrics = router.metrics;

console.log(metrics.totalCalls);    // Total calls across all servers
console.log(metrics.totalErrors);   // Total errors across all servers
console.log(metrics.totalTools);    // Number of tools in the route table
console.log(metrics.uptimeMs);      // Router uptime in milliseconds

// Per-upstream metrics
console.log(metrics.upstreams.github.callCount);
console.log(metrics.upstreams.github.errorCount);
console.log(metrics.upstreams.github.avgLatencyMs);
console.log(metrics.upstreams.github.lastCallAt);

事件

订阅路由器生命周期和工具调用事件。 ToolRouter 延伸 EventEmitter.

router.on('serverConnected', (e) => console.log(`Connected: ${e.name}`));
router.on('serverDisconnected', (e) => console.log(`Disconnected: ${e.name}`));
router.on('toolCall', (e) => {
  console.log(`Tool: ${e.tool}, Upstream: ${e.upstream}, Duration: ${e.durationMs}ms, Error: ${e.isError}`);
});

动态服务器管理

在运行时添加、删除和更新服务器。每次更改后,路由表都会自动重建。

// Add servers dynamically
router.addServer('new-server', { tools, handler });

// Remove a server (its tools are removed from the route table)
router.removeServer('old-server');

// Update a server's tool list without removing it
router.updateServerTools('github', [
  { name: 'search' },
  { name: 'create_issue' },
  { name: 'close_issue' },  // newly added
]);

______________________________________________________________________

API 参考

createRouter(options?)

创建并返回新的工厂函数 ToolRouter 例子

import { createRouter } from 'mcp-tool-router';

const router = createRouter({ name: 'my-router', version: '1.0.0' });

参数:

  • options (RouterOptions,可选)--请参阅 RouterOptions 在......下面

退货: ToolRouter

______________________________________________________________________

ToolRouter

聚合来自多个上游服务器的工具的主类。扩展 EventEmitter.

构造函数

new ToolRouter(options?: RouterOptions)

RouterOptions

属性类型默认值描述
namestring'mcp-tool-router'虚拟服务器的名称。
versionstring'1.0.0'虚拟服务器的版本。
separatorstring'/'位于命名空间前缀和工具名称之间的字符。
conflictResolutionConflictResolution'prefix'处理名称冲突的策略: 'prefix', 'first-wins',或 'error'.
healthCheckbooleanfalse是否启用健康检查。
connectionStrategy`'eager' \'lazy'`'eager'何时连接到上游服务器。
aggregateResourcesbooleantrue是否从上游聚集资源。
aggregatePromptsbooleantrue是否聚合来自上游的提示。
pageSizenumber0列表响应中每页的最大工具数。 0 禁用分页。

方法

方法签名描述
addServer(name: string, config: { tools?: ToolDefinition[]; handler?: ToolCallHandler; ... }) => UpstreamBuilder注册上游服务器。返回一个 UpstreamBuilder 为了实现流畅的配置。
removeServer(name: string) => boolean注销服务器并删除其工具。退货 true 如果服务器存在。
callTool(name: string, args?: Record) => Promise按其命名空间名称将工具调用路由到正确的上游。
listTools() => Array列出所有可用工具及其命名空间名称和上游来源。
listServers() => UpstreamInfo[]列出所有已注册的服务器及其状态和指标。
updateServerTools(name: string, tools: ToolDefinition[]) => void替换服务器的工具列表并重建路由表。
use(middleware: MiddlewareFn) => ToolRouter注册一个全局中间件函数。退货 this 用于链式。
alias(from: string, to: string) => ToolRouter注册路由器级工具别名。 to 是完全命名空间的名称。退货 this.
start() => Promise启动路由器。
stop() => Promise停止路由器并清除所有状态。
lookupRoute`(qualifiedName: string) => RouteEntry \undefined`按限定名称查找路线条目。

属性

属性类型描述
toolsReadonlyArray当前聚合工具列表。
upstreamsReadonlyArray当前上游服务器信息。
metricsRouterMetrics当前路由器指标快照。
routeCountnumber路由表中的条目数。
separatorstring已配置的命名空间分隔符。

事件

事件有效载荷描述
serverConnected{ name: string }添加服务器时触发。
serverDisconnected{ name: string }当服务器被移除时触发。
toolCallToolCallEvent在每次工具调用后发出,带有计时和错误信息。

______________________________________________________________________

UpstreamBuilder

流利的建设者返回 ToolRouter.addServer().所有方法返回 this 用于链式。

方法签名描述
namespace`(prefix: string \null) => UpstreamBuilder`设置命名空间前缀。通过 null 禁用命名空间。
filter(config: FilterConfig) => UpstreamBuilder设置包含/排除/谓词筛选器。
include(patterns: string[]) => UpstreamBuilder速记:只包括与这些glob模式匹配的工具。
exclude(toolNames: string[]) => UpstreamBuilder速记:排除与这些glob模式匹配的工具。
alias(from: string, to: string) => UpstreamBuilder注册服务器级别名。 to 是原始工具名称(在命名空间之前)。
use(middleware: MiddlewareFn) => UpstreamBuilder注册特定于此上游的中间件。

______________________________________________________________________

NamespaceManager

管理命名空间前缀应用程序和工具名称的剥离。

import { NamespaceManager } from 'mcp-tool-router';

const ns = new NamespaceManager('/', 'prefix');

构造函数

new NamespaceManager(separator?: string, conflictResolution?: ConflictResolution)
方法签名描述
qualify`(prefix: string \null, toolName: string) => string`根据前缀和工具名称构建限定名。如果前缀为,则返回原始名称 null.
dequalify`(qualifiedName: string) => { serverName: string; originalName: string } \null`去掉前缀,在出现第一个分隔符时拆分。
addTool`(serverName: string, tool: ToolDefinition, prefix?: string \null) => void`在服务器的命名空间下注册工具。
resolveTool`(qualifiedName: string) => NamespaceEntry \undefined`按合格名称查找已注册的工具。
listTools() => NamespaceEntry[]列出所有已注册的工具。
listToolsForServer(serverName: string) => NamespaceEntry[]列出特定服务器的工具。
removeServer(serverName: string) => void删除属于服务器的所有工具。
has(qualifiedName: string) => boolean检查是否注册了限定名称。
clear() => void删除所有条目。
getSeparator() => string获取已配置的分隔符。
getConflictResolution() => ConflictResolution获取配置的冲突解决策略。
sizenumber (getter)已注册的工具总数。

______________________________________________________________________

ServerRegistry

管理服务器注册、工具/资源/提示列表、状态和调用指标。

import { ServerRegistry } from 'mcp-tool-router';

const registry = new ServerRegistry();
方法签名描述
registerServer(config, tools, handler, resources?, prompts?) => void使用服务器的工具和处理程序注册服务器。
unregisterServer(name: string) => boolean删除服务器注册。
getServer`(name: string) => ServerEntry \undefined`按名称获取服务器条目。
hasServer(name: string) => boolean检查服务器是否已注册。
listServers() => ServerEntry[]列出所有已注册的服务器。
listServerNames() => string[]列出所有服务器名称。
updateTools(name: string, tools: ToolDefinition[]) => void更新服务器的工具列表。
updateResources(name: string, resources: ResourceDefinition[]) => void更新服务器的资源列表。
updatePrompts(name: string, prompts: PromptDefinition[]) => void更新服务器的提示列表。
updateStatus(name: string, status: UpstreamStatus) => void更新服务器的连接状态。
recordCall(name: string, durationMs: number, isError: boolean) => void记录工具调用以进行指标跟踪。
getUpstreamInfo`(name: string) => UpstreamInfo \undefined`使用指标获取聚合的上游信息。
clear() => void删除所有服务器注册。
sizenumber (getter)已注册的服务器数量。

______________________________________________________________________

RequestRouter

处理对正确上游服务器的路由工具调用。构建和维护路由表,执行中间件链,并记录调用指标。

import { RequestRouter } from 'mcp-tool-router';

const router = new RequestRouter(namespaceManager, serverRegistry);
方法签名描述
buildRouteTable() => void从当前命名空间和注册表状态重建路由表。
route(request: ToolCallRequest) => Promise将工具调用请求路由到正确的上游。
lookup`(qualifiedName: string) => RouteEntry \undefined`按限定名称查找路线条目。
listRoutes() => RouteEntry[]获取所有路线条目。
listTools() => ToolDefinition[]获取所有具有命名空间名称的工具定义。
addMiddleware(middleware: MiddlewareFn) => void注册一个全局中间件。
addServerMiddleware(serverName: string, middleware: MiddlewareFn) => void为特定服务器注册中间件。
addAlias(from: string, to: string) => void注册一个全局别名。
addServerAlias(serverName: string, from: string, to: string) => void注册每个服务器的别名。
sizenumber (getter)表中的路由数。

______________________________________________________________________

applyFilter(tools, filter?)

独立功能,应用 FilterConfig 到工具定义列表。

import { applyFilter } from 'mcp-tool-router';

const filtered = applyFilter(tools, {
  include: ['get_*'],
  exclude: ['get_internal_*'],
  predicate: (tool) => !!tool.description,
});

参数:

  • tools (ToolDefinition[])--要筛选的工具列表。
  • filter (FilterConfig,可选)--过滤器配置。如果省略,则返回所有工具。

退货: ToolDefinition[]

______________________________________________________________________

CollisionError

当来自不同上游服务器的两个工具解析为相同的限定名时抛出。

import { CollisionError } from 'mcp-tool-router';

try {
  ns.addTool('server2', { name: 'search' }, null);
} catch (err) {
  if (err instanceof CollisionError) {
    console.log(err.conflicts);
    // [{ name: 'search', upstreams: ['server1', 'server2'] }]
  }
}

属性:

  • conflicts (Array)--冲突名称列表以及产生这些名称的上游。

______________________________________________________________________

ConfigError

因配置无效而抛出(例如,分隔符无效、缺少必填字段)。

import { ConfigError } from 'mcp-tool-router';

______________________________________________________________________

类型导出

所有类型都从包入口点导出:

import type {
  ToolDefinition,
  ToolAnnotations,
  ResourceDefinition,
  PromptDefinition,
  PromptArgument,
  ServerConfig,
  RouterOptions,
  ConflictResolution,
  ToolCallRequest,
  ToolCallResponse,
  ToolCallHandler,
  ToolCallContext,
  ToolContent,
  MiddlewareFn,
  FilterConfig,
  AliasConfig,
  UpstreamStatus,
  UpstreamInfo,
  RouterMetrics,
  ToolCallEvent,
  UpstreamEvent,
  RouterEvents,
  RouteEntry,
  UpstreamTransportConfig,
  ReconnectConfig,
  ServerRegistration,
} from 'mcp-tool-router';

______________________________________________________________________

配置

ServerConfig

上游服务器注册的配置。

属性类型默认值描述
namestring必需上游服务器的唯一标识符。
transportUpstreamTransportConfig--传输配置(stdio, http,或 sse).
prefix`string \null`服务器名称命名空间前缀。 null 禁用命名空间。
separatorstring'/'覆盖此服务器的路由器级别分隔符。
filterFilterConfig--此服务器工具的包含/排除/谓词筛选器。
aliasesAliasConfig[]--此服务器的工具别名。
connectTimeoutnumber30000连接超时(毫秒)。
requestTimeoutnumber60000每个请求超时(毫秒)。
reconnectReconnectConfig--重新连接配置。
envRecord--环境变量(stdio传输)。
cwdstring--工作目录(stdio传输)。
headersRecord--HTTP标头(HTTP/sse传输)。

FilterConfig

属性类型描述
includestring[]球状图案。仅包括与至少一种模式匹配的工具。
excludestring[]球状图案。不包括与任何模式匹配的工具。
predicate(tool: ToolDefinition) => boolean功能过滤器。返回 true 包括, false 排除。

ReconnectConfig

属性类型默认值描述
enabledbooleantrue断开连接时是否自动重新连接。
maxAttemptsnumber10放弃前的最大重新连接尝试次数。
initialDelayMsnumber1000首次重新连接尝试前的初始延迟。
maxDelayMsnumber30000重新连接尝试之间的最大延迟。
backoffMultipliernumber2每次尝试失败后,应用乘数计算延迟。

UpstreamTransportConfig

type UpstreamTransportConfig =
  | { type: 'stdio'; command: string; args?: string[] }
  | { type: 'http'; url: string }
  | { type: 'sse'; url: string };

______________________________________________________________________

错误处理

未知工具

callTool 使用路由表中不存在的工具名称调用,响应具有 isError: true 内容包含 Unknown tool: "".

const result = await router.callTool('nonexistent/tool', {});
if (result.isError) {
  console.error(result.content[0]); // { type: 'text', text: 'Unknown tool: "nonexistent/tool"' }
}

上游不可用

当目标上游服务器断开连接或处于非连接状态时,响应具有 isError: true 内容描述了服务器状态。

const result = await router.callTool('github/search', {});
if (result.isError) {
  console.error(result.content[0]); // { type: 'text', text: 'Server "github" is disconnected' }
}

处理程序错误

如果上游处理程序抛出异常,则会捕获错误并将其作为错误响应返回。错误也记录在服务器的指标中。

const result = await router.callTool('flaky/operation', {});
if (result.isError) {
  // { type: 'text', text: 'Error calling tool "operation" on server "flaky": Connection timeout' }
}

名称冲突

CollisionError 当两台服务器生成相同的限定工具名称并且冲突解决策略为 'error''prefix'.

import { CollisionError } from 'mcp-tool-router';

try {
  router.addServer('server2', { tools: [{ name: 'search' }], handler }).namespace(null);
} catch (err) {
  if (err instanceof CollisionError) {
    console.error(err.message);
    // Tool name collision detected: "search" is exposed by both upstream "server1" and upstream "server2"
    console.error(err.conflicts);
  }
}

重复的服务器名称

尝试使用已注册的名称注册服务器会抛出 Error.

router.addServer('github', { tools: [], handler });
router.addServer('github', { tools: [], handler }); // throws: Server "github" is already registered

______________________________________________________________________

高级用法

具有过滤和别名的多服务器聚合

import { ToolRouter } from 'mcp-tool-router';

const router = new ToolRouter({
  name: 'enterprise-router',
  version: '2.0.0',
  separator: '/',
});

// GitHub: expose only read operations
router.addServer('github', {
  tools: [
    { name: 'create_issue', description: 'Create issue', annotations: { readOnlyHint: false } },
    { name: 'search', description: 'Search repos', annotations: { readOnlyHint: true } },
    { name: 'get_repo', description: 'Get repo info', annotations: { readOnlyHint: true } },
    { name: 'delete_repo', description: 'Delete repo', annotations: { destructiveHint: true } },
  ],
  handler: githubHandler,
}).filter({
  predicate: (tool) => !tool.annotations?.destructiveHint,
}).namespace('gh');

// Postgres: hide dangerous DDL operations
router.addServer('postgres', {
  tools: [
    { name: 'query', description: 'Run SQL query' },
    { name: 'list_tables', description: 'List tables' },
    { name: 'drop_table', description: 'Drop table' },
    { name: 'truncate_table', description: 'Truncate table' },
  ],
  handler: pgHandler,
}).exclude(['drop_*', 'truncate_*']).namespace('pg');

// Slack: expose everything, add a short alias
router.addServer('slack', {
  tools: [
    { name: 'send_message', description: 'Send a message' },
    { name: 'list_channels', description: 'List channels' },
  ],
  handler: slackHandler,
});

// Router-level alias for convenience
router.alias('send', 'slack/send_message');

// Final tool list:
// gh/create_issue, gh/search, gh/get_repo, pg/query, pg/list_tables,
// slack/list_channels, send

访问控制中间件

router.use(async (ctx, next) => {
  if (ctx.toolDefinition.annotations?.destructiveHint) {
    return {
      content: [{ type: 'text', text: 'Access denied: destructive operations are not allowed' }],
      isError: true,
    };
  }
  return next();
});

日志和审计中间件

router.use(async (ctx, next) => {
  const start = Date.now();
  console.log(`[AUDIT] Calling ${ctx.namespacedName} on ${ctx.upstreamName}`);

  const result = await next();

  console.log(`[AUDIT] ${ctx.namespacedName} completed in ${Date.now() - start}ms, error=${!!result.isError}`);
  return result;
});

服务器特定中间件

// Add input validation middleware only to the database server
router.addServer('db', { tools, handler })
  .use(async (ctx, next) => {
    // Inject a read-only flag for safety
    if (!ctx.arguments.readOnly) {
      ctx.arguments.readOnly = true;
    }
    return next();
  });

响应修改中间件

router.use(async (ctx, next) => {
  const result = await next();
  // Redact sensitive data from all responses
  return {
    ...result,
    content: result.content.map(c =>
      c.type === 'text'
        ? { ...c, text: c.text.replace(/\b\d{3}-\d{2}-\d{4}\b/g, '***-**-****') }
        : c
    ),
  };
});

使用事件和指标进行监控

const router = new ToolRouter({ name: 'monitored-router' });

router.on('serverConnected', ({ name }) => {
  console.log(`[EVENT] Server connected: ${name}`);
});

router.on('serverDisconnected', ({ name }) => {
  console.log(`[EVENT] Server disconnected: ${name}`);
});

router.on('toolCall', (event) => {
  if (event.isError) {
    console.error(`[ERROR] ${event.tool} on ${event.upstream}: ${event.errorMessage}`);
  }
});

// Periodic metrics reporting
setInterval(() => {
  const m = router.metrics;
  console.log(`[METRICS] Tools: ${m.totalTools}, Calls: ${m.totalCalls}, Errors: ${m.totalErrors}, Uptime: ${m.uptimeMs}ms`);
  for (const [name, info] of Object.entries(m.upstreams)) {
    console.log(`  ${name}: calls=${info.callCount}, errors=${info.errorCount}, avg=${info.avgLatencyMs.toFixed(1)}ms`);
  }
}, 60_000);

生命周期管理

const router = new ToolRouter({ name: 'managed-router' });

// Register servers
router.addServer('github', { tools: githubTools, handler: githubHandler });
router.addServer('slack', { tools: slackTools, handler: slackHandler });

// Start the router
await router.start();

// ... use the router ...

// Dynamically add a new server
router.addServer('jira', { tools: jiraTools, handler: jiraHandler });

// Dynamically update tools when upstream changes
router.updateServerTools('github', updatedGithubTools);

// Remove a server
router.removeServer('slack');

// Stop and clean up
await router.stop();

______________________________________________________________________

TypeScript

此包是用TypeScript编写的,启用了严格模式。所有公共类型都从包入口点导出。

import { ToolRouter, createRouter, NamespaceManager, ServerRegistry, RequestRouter, applyFilter, CollisionError, ConfigError } from 'mcp-tool-router';

import type {
  ToolDefinition,
  ToolAnnotations,
  ResourceDefinition,
  PromptDefinition,
  PromptArgument,
  ServerConfig,
  RouterOptions,
  ConflictResolution,
  ToolCallRequest,
  ToolCallResponse,
  ToolCallHandler,
  ToolCallContext,
  ToolContent,
  MiddlewareFn,
  FilterConfig,
  AliasConfig,
  UpstreamStatus,
  UpstreamInfo,
  RouterMetrics,
  ToolCallEvent,
  UpstreamEvent,
  RouterEvents,
  RouteEntry,
  UpstreamTransportConfig,
  ReconnectConfig,
  ServerRegistration,
} from 'mcp-tool-router';

编译输出包括 .d.ts 申报文件和 .d.ts.map IDE导航的声明映射。该包以ES2022为目标,并发出CommonJS模块。

______________________________________________________________________

许可证

麻省理工学院

目录标签

目录标签

TypeScript中间件AI代理工具聚合本地部署命名空间管理路由分发LLM集成

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

none

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明none部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP