cloudflare-mcp-smart-proxy 1.5.19 → 1.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/connector-cli.js CHANGED
@@ -38,6 +38,8 @@ function printUsage() {
38
38
  console.error(' --codex-device-identity-path <path> Shared CloudMCP device identity');
39
39
  console.error(' --app-server-socket <path> Current runtime Codex app-server socket');
40
40
  console.error(' --runtime-id <id> Current Codex runtime identity');
41
+ console.error(' --probe-timeout-ms <ms> Fresh MCP catalog probe timeout (30000-300000; default 120000)');
42
+ console.error(' Env: CLOUDMCP_CONNECTOR_PROBE_TIMEOUT_MS');
41
43
  console.error(' --dry-run Show output without writing');
42
44
  console.error(' --show-secrets Explicitly include credentials in print output');
43
45
  console.error(' --approval-code <code> One-time code shown by the CloudMCP administrator');
@@ -85,6 +87,27 @@ function resolveRequiredOption(options, flagName, envNames = []) {
85
87
  throw new Error(`Missing required option --${flagName}`);
86
88
  }
87
89
 
90
+ function resolveConnectorProbeTimeoutMs(options = {}, env = process.env) {
91
+ const raw = options['probe-timeout-ms'] || env.CLOUDMCP_CONNECTOR_PROBE_TIMEOUT_MS || '120000';
92
+ const timeoutMs = Number(raw);
93
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 30_000 || timeoutMs > 300_000) {
94
+ throw new Error('probe-timeout-ms must be an integer between 30000 and 300000');
95
+ }
96
+ return timeoutMs;
97
+ }
98
+
99
+ async function runCodexReload(options, serverName, {
100
+ reload = reloadCodexMcpServer,
101
+ env = process.env
102
+ } = {}) {
103
+ return reload({
104
+ serverName,
105
+ socketPath: options['app-server-socket'] || env.CODEX_APP_SERVER_SOCKET || '',
106
+ runtimeId: options['runtime-id'] || env.CODEX_RUNTIME_ID || '',
107
+ timeoutMs: resolveConnectorProbeTimeoutMs(options, env)
108
+ });
109
+ }
110
+
88
111
  function buildInstallOptions(options) {
89
112
  const workspaceRoot = path.resolve(options['workspace-root'] || process.cwd());
90
113
  return {
@@ -181,11 +204,7 @@ async function runActivation(options) {
181
204
  dryRun: options.dryRun === true
182
205
  });
183
206
  if (options.ecosystem === 'codex' && !options.dryRun) {
184
- result.activation = await reloadCodexMcpServer({
185
- serverName: result.serverName,
186
- socketPath: options['app-server-socket'] || process.env.CODEX_APP_SERVER_SOCKET || '',
187
- runtimeId: options['runtime-id'] || process.env.CODEX_RUNTIME_ID || ''
188
- });
207
+ result.activation = await runCodexReload(options, result.serverName);
189
208
  }
190
209
  if (!options.dryRun) fs.chmodSync(paths.credentialPath, 0o600);
191
210
  if (!options.dryRun && pending) {
@@ -357,11 +376,7 @@ async function main() {
357
376
  if (options.command === 'install') {
358
377
  const result = installReferenceConnector(buildInstallOptions(options));
359
378
  if (options.ecosystem === 'codex' && !options.dryRun) {
360
- result.activation = await reloadCodexMcpServer({
361
- serverName: result.serverName,
362
- socketPath: options['app-server-socket'] || process.env.CODEX_APP_SERVER_SOCKET || '',
363
- runtimeId: options['runtime-id'] || process.env.CODEX_RUNTIME_ID || ''
364
- });
379
+ result.activation = await runCodexReload(options, result.serverName);
365
380
  }
366
381
  printInstallResult(result);
367
382
  return;
@@ -371,11 +386,7 @@ async function main() {
371
386
  if (options.ecosystem !== 'codex') {
372
387
  throw new Error('Runtime reload is currently supported only for Codex');
373
388
  }
374
- const activation = await reloadCodexMcpServer({
375
- serverName: options['server-name'] || 'cloudmcp',
376
- socketPath: options['app-server-socket'] || process.env.CODEX_APP_SERVER_SOCKET || '',
377
- runtimeId: options['runtime-id'] || process.env.CODEX_RUNTIME_ID || ''
378
- });
389
+ const activation = await runCodexReload(options, options['server-name'] || 'cloudmcp');
379
390
  printInstallResult({
380
391
  ecosystem: 'codex',
381
392
  scope: 'user',
@@ -413,4 +424,10 @@ if (isMainEntrypoint()) {
413
424
  main();
414
425
  }
415
426
 
416
- export { isMainEntrypoint, parseArgs, shouldInstallExistingCredential };
427
+ export {
428
+ isMainEntrypoint,
429
+ parseArgs,
430
+ resolveConnectorProbeTimeoutMs,
431
+ runCodexReload,
432
+ shouldInstallExistingCredential
433
+ };
package/index.js CHANGED
@@ -148,7 +148,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
148
148
  });
149
149
 
150
150
  // 工具调用处理器
151
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
151
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
152
152
  const { name, arguments: args } = request.params;
153
153
 
154
154
  if (!name) {
@@ -165,7 +165,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
165
165
 
166
166
  try {
167
167
  await refreshProjectScope();
168
- const result = await router.executeTool(name, args || {});
168
+ const result = await router.executeTool(name, args || {}, { signal: extra.signal });
169
169
 
170
170
  // 格式化响应
171
171
  if (typeof result === 'string') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudflare-mcp-smart-proxy",
3
- "version": "1.5.19",
3
+ "version": "1.5.20",
4
4
  "description": "Smart proxy for Cloudflare MCP - routes tools to cloud or local execution",
5
5
  "repository": {
6
6
  "type": "git",
package/src/router.js CHANGED
@@ -139,7 +139,7 @@ export class SmartRouter {
139
139
  /**
140
140
  * 执行工具调用
141
141
  */
142
- async executeTool(toolName, params) {
142
+ async executeTool(toolName, params, { signal = null } = {}) {
143
143
  const route = this.routeTool(toolName);
144
144
 
145
145
  if (route === 'local') {
@@ -151,7 +151,7 @@ export class SmartRouter {
151
151
  projectIdentity: this.localTools?.connectorBridge?.state?.projectIdentity
152
152
  }
153
153
  : params;
154
- return await this.callCloudTool(toolName, recoveryParams);
154
+ return await this.callCloudTool(toolName, recoveryParams, { signal });
155
155
  }
156
156
  }
157
157
 
@@ -179,7 +179,7 @@ export class SmartRouter {
179
179
  /**
180
180
  * 调用云端工具
181
181
  */
182
- async callCloudTool(toolName, params, { workspaceId = null } = {}) {
182
+ async callCloudTool(toolName, params, { workspaceId = null, signal = null } = {}) {
183
183
  // 对于 skill_* 工具,自动注入项目根路径信息
184
184
  if (toolName.startsWith('skill_')) {
185
185
  // 如果参数中没有 project_root 且没有 paths,自动添加 project_root
@@ -205,9 +205,10 @@ export class SmartRouter {
205
205
  }
206
206
 
207
207
  try {
208
+ const requestId = Date.now();
208
209
  const body = JSON.stringify({
209
210
  jsonrpc: '2.0',
210
- id: Date.now(),
211
+ id: requestId,
211
212
  method: 'tools/call',
212
213
  params: {
213
214
  name: toolName,
@@ -222,11 +223,13 @@ export class SmartRouter {
222
223
  headers: {
223
224
  'Authorization': `Bearer ${this.cloudApiKey}`,
224
225
  'Content-Type': 'application/json',
226
+ 'X-Request-ID': String(requestId),
225
227
  ...this.getScopeHeaders(),
226
228
  ...(workspaceId ? { 'X-CloudMCP-Workspace-ID': workspaceId } : {}),
227
229
  ...signedHeaders
228
230
  },
229
- body
231
+ body,
232
+ signal
230
233
  });
231
234
 
232
235
  if (!response.ok) {