Skip to content

Commit 90e4b4c

Browse files
authored
Merge pull request #113 from taptap/feat/inject-params-per-call
fix(proxy): inject private params on every tool call for MCP Server compatibility
2 parents 24f1834 + 094f2fe commit 90e4b4c

4 files changed

Lines changed: 124 additions & 27 deletions

File tree

docs/PROXY.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,18 @@ cat config.json | node proxy.js
11381138
"options": {
11391139
"verbose": false,
11401140
"reconnect_interval": 5000,
1141-
"request_timeout": 30000
1141+
"request_timeout": 30000,
1142+
"tool_call_timeout": 300000,
1143+
"reset_timeout_on_progress": true,
1144+
"health_check_interval": 30000,
1145+
"enable_cookie_sticky": true,
1146+
"inject_params_per_call": true,
1147+
"log": {
1148+
"root": "/tmp/taptap-mcp/logs",
1149+
"enabled": false,
1150+
"level": "info",
1151+
"max_days": 7
1152+
}
11421153
}
11431154
}
11441155
```
@@ -1166,7 +1177,17 @@ node proxy.js
11661177
- `tenant.project_id` - 项目标识符(可选,仅用于日志)
11671178
- `options.verbose` - 详细日志模式(默认 `false`
11681179
- `options.reconnect_interval` - 重连间隔(毫秒,默认 `5000`
1169-
- `options.request_timeout` - 请求超时(毫秒,默认 `30000`
1180+
- `options.request_timeout` - 请求队列超时(毫秒,默认 `30000`
1181+
- `options.tool_call_timeout` - 工具调用超时(毫秒,默认 `300000`,即 5 分钟)
1182+
- `options.reset_timeout_on_progress` - 收到 progress 通知时重置超时计时器(默认 `true`
1183+
- `options.health_check_interval` - 健康检查间隔(毫秒,默认 `30000`)- 定期验证 Server 会话是否有效
1184+
- `options.enable_cookie_sticky` - 启用 Cookie 会话粘性(默认 `true`)- 用于 K8s 多副本部署时的会话粘性
1185+
- `options.inject_params_per_call` - 每次工具调用时注入私有参数(默认 `true`)- 为兼容不同 MCP Server 实现,默认每次调用都注入;如果目标 Server 支持从 Session 获取参数,可设为 `false` 以减少数据传输
1186+
- `options.log` - 日志配置对象(可选)
1187+
- `options.log.root` - 日志根目录(默认 `/tmp/taptap-mcp/logs`
1188+
- `options.log.enabled` - 是否启用文件日志(默认 `false`
1189+
- `options.log.level` - 日志级别(默认 `info`)- 支持:emergency, alert, critical, error, warning, notice, info, debug
1190+
- `options.log.max_days` - 日志保留天数(默认 `7`
11701191

11711192
### 6.5 部署场景
11721193

@@ -1384,6 +1405,15 @@ interface ProxyConfig {
13841405
request_timeout?: number; // 请求队列超时(默认 30000ms)
13851406
tool_call_timeout?: number; // Tool 调用超时(默认 300000ms,即 5 分钟)
13861407
reset_timeout_on_progress?: boolean; // 收到 progress 通知时重置超时(默认 true)
1408+
health_check_interval?: number; // 健康检查间隔(默认 30000ms)
1409+
enable_cookie_sticky?: boolean; // 启用 Cookie 会话粘性(默认 true)
1410+
inject_params_per_call?: boolean; // 每次工具调用时注入私有参数(默认 true)
1411+
log?: {
1412+
root?: string; // 日志根目录(默认 /tmp/taptap-mcp/logs)
1413+
enabled?: boolean; // 是否启用文件日志(默认 false)
1414+
level?: string; // 日志级别(默认 info)
1415+
max_days?: number; // 日志保留天数(默认 7)
1416+
};
13871417
};
13881418
}
13891419
```
@@ -1419,6 +1449,15 @@ function generateProxyConfig(user: User, project: Project, macToken: MacToken):
14191449
verbose: true, // 推荐开启详细日志
14201450
tool_call_timeout: 300000, // Tool 调用超时 5 分钟
14211451
reset_timeout_on_progress: true, // 收到 progress 通知时重置超时
1452+
health_check_interval: 30000, // 健康检查间隔 30 秒
1453+
enable_cookie_sticky: true, // 启用 Cookie 会话粘性
1454+
inject_params_per_call: true, // 每次调用都注入私有参数(推荐)
1455+
log: {
1456+
root: '/var/log/taptap-mcp', // TapCode 环境的日志目录
1457+
enabled: true, // 推荐开启文件日志
1458+
level: 'info',
1459+
max_days: 7,
1460+
},
14221461
},
14231462
};
14241463

package-lock.json

Lines changed: 30 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/mcp-proxy/proxy.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,38 @@ export class TapTapMCPProxy {
196196
return headers;
197197
}
198198

199+
/**
200+
* 注入私有参数到工具调用参数中
201+
*
202+
* 私有参数已在初始化连接时通过 Headers 传递,此方法用于在每次工具调用时
203+
* 也注入这些参数,以兼容不支持从 Session 获取参数的 MCP Server。
204+
*
205+
* 注入的参数(以下划线开头,表示私有):
206+
* - _mac_token: MAC 认证令牌
207+
* - _user_id: 用户标识(可选)
208+
* - _project_id: 项目标识(可选)
209+
* - _project_path: 项目路径(可选)
210+
*/
211+
private injectPrivateParams(args: Record<string, unknown> | undefined): Record<string, unknown> {
212+
const injected: Record<string, unknown> = { ...(args || {}) };
213+
214+
// 注入 MAC Token(必需)
215+
injected._mac_token = this.config.auth;
216+
217+
// 注入可选的会话上下文参数
218+
if (this.config.tenant.user_id) {
219+
injected._user_id = this.config.tenant.user_id;
220+
}
221+
if (this.config.tenant.project_id) {
222+
injected._project_id = this.config.tenant.project_id;
223+
}
224+
if (this.config.tenant.project_path) {
225+
injected._project_path = this.config.tenant.project_path;
226+
}
227+
228+
return injected;
229+
}
230+
199231
/**
200232
* 连接到 TapTap MCP Server
201233
*/
@@ -631,14 +663,16 @@ export class TapTapMCPProxy {
631663
return result;
632664
});
633665

634-
// 拦截 tools/call - 直接透传(参数已在 Session 创建时通过 Headers 传递)
666+
// 拦截 tools/call - 注入私有参数后转发
635667
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
636668
const { name, arguments: args } = request.params;
637669

670+
// 根据配置决定是否在每次调用时注入私有参数(默认注入,兼容不同 MCP Server)
671+
const shouldInjectParams = this.config.options?.inject_params_per_call ?? true;
672+
const finalArgs = shouldInjectParams ? this.injectPrivateParams(args) : args;
673+
638674
if (this.config.options?.verbose) {
639-
this.log('debug', `Tool call: ${name}`);
640-
// 注意:MAC Token 和其他参数已在 Session 创建时通过 Headers 传递
641-
// 无需每次工具调用都注入,减少数据传输量
675+
this.log('debug', `Tool call: ${name} (inject_params_per_call: ${shouldInjectParams})`);
642676
}
643677

644678
// 检查连接状态
@@ -650,7 +684,7 @@ export class TapTapMCPProxy {
650684
return new Promise((resolve, reject) => {
651685
this.pendingRequests.push({
652686
name,
653-
arguments: args,
687+
arguments: finalArgs,
654688
resolve,
655689
reject,
656690
timestamp: Date.now(),
@@ -665,12 +699,12 @@ export class TapTapMCPProxy {
665699
);
666700
}
667701

668-
// 透传到 TapTap Server(捕获网络错误并触发重连)
702+
// 转发到 TapTap Server(捕获网络错误并触发重连)
669703
try {
670704
const result = await this.client.callTool(
671705
{
672706
name,
673-
arguments: args,
707+
arguments: finalArgs,
674708
},
675709
undefined, // resultSchema
676710
{
@@ -695,7 +729,7 @@ export class TapTapMCPProxy {
695729
return new Promise((resolve, reject) => {
696730
this.pendingRequests.push({
697731
name,
698-
arguments: args,
732+
arguments: finalArgs,
699733
resolve,
700734
reject,
701735
timestamp: Date.now(),

src/mcp-proxy/types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ export interface ProxyConfig {
9898
* 确保同一 Proxy 的所有请求被路由到同一个 MCP Server Pod
9999
*/
100100
enable_cookie_sticky?: boolean;
101+
/**
102+
* 每次工具调用时也注入私有参数(默认 true)
103+
*
104+
* 私有参数(_mac_token, _user_id, _project_id, _project_path)会在两个时机传递:
105+
* 1. 初始化连接时:始终通过 HTTP Headers 传递(不受此配置影响)
106+
* 2. 每次工具调用时:通过工具参数注入(由此配置控制)
107+
*
108+
* 为兼容不同的 MCP Server 实现,默认每次调用都注入。
109+
* 如果目标 Server 支持从 Session 获取这些参数,可设置为 false 以减少数据传输量。
110+
*/
111+
inject_params_per_call?: boolean;
101112
/** 日志配置 */
102113
log?: LogConfig;
103114
};

0 commit comments

Comments
 (0)