lynkr 8.0.0 → 9.0.1
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/.lynkr/telemetry.db +0 -0
- package/.lynkr/telemetry.db-shm +0 -0
- package/.lynkr/telemetry.db-wal +0 -0
- package/README.md +196 -322
- package/lynkr-skill.tar.gz +0 -0
- package/package.json +4 -3
- package/src/api/openai-router.js +64 -13
- package/src/api/providers-handler.js +171 -3
- package/src/api/router.js +9 -2
- package/src/clients/circuit-breaker.js +10 -247
- package/src/clients/codex-process.js +342 -0
- package/src/clients/codex-utils.js +143 -0
- package/src/clients/databricks.js +210 -63
- package/src/clients/resilience.js +540 -0
- package/src/clients/retry.js +22 -167
- package/src/clients/standard-tools.js +23 -0
- package/src/config/index.js +77 -0
- package/src/context/compression.js +42 -9
- package/src/context/distill.js +492 -0
- package/src/orchestrator/index.js +48 -8
- package/src/routing/complexity-analyzer.js +258 -5
- package/src/routing/index.js +12 -2
- package/src/routing/latency-tracker.js +148 -0
- package/src/routing/model-tiers.js +2 -0
- package/src/routing/quality-scorer.js +113 -0
- package/src/routing/telemetry.js +464 -0
- package/src/server.js +13 -12
- package/src/tools/code-graph.js +538 -0
- package/src/tools/code-mode.js +304 -0
- package/src/tools/index.js +4 -0
- package/src/tools/lazy-loader.js +18 -0
- package/src/tools/mcp-remote.js +7 -0
- package/src/tools/smart-selection.js +11 -0
- package/src/tools/tinyfish.js +358 -0
- package/src/tools/truncate.js +1 -0
- package/src/utils/payload.js +206 -0
- package/src/utils/perf-timer.js +80 -0
- package/.github/FUNDING.yml +0 -15
- package/.github/workflows/README.md +0 -215
- package/.github/workflows/ci.yml +0 -69
- package/.github/workflows/index.yml +0 -62
- package/.github/workflows/web-tools-tests.yml +0 -56
- package/CITATIONS.bib +0 -6
- package/DEPLOYMENT.md +0 -1001
- package/LYNKR-TUI-PLAN.md +0 -984
- package/PERFORMANCE-REPORT.md +0 -866
- package/PLAN-per-client-model-routing.md +0 -252
- package/docs/42642f749da6234f41b6b425c3bb07c9.txt +0 -1
- package/docs/BingSiteAuth.xml +0 -4
- package/docs/docs-style.css +0 -478
- package/docs/docs.html +0 -198
- package/docs/google5be250e608e6da39.html +0 -1
- package/docs/index.html +0 -577
- package/docs/index.md +0 -584
- package/docs/robots.txt +0 -4
- package/docs/sitemap.xml +0 -44
- package/docs/style.css +0 -1223
- package/docs/toon-integration-spec.md +0 -130
- package/documentation/README.md +0 -101
- package/documentation/api.md +0 -806
- package/documentation/claude-code-cli.md +0 -679
- package/documentation/codex-cli.md +0 -397
- package/documentation/contributing.md +0 -571
- package/documentation/cursor-integration.md +0 -734
- package/documentation/docker.md +0 -874
- package/documentation/embeddings.md +0 -762
- package/documentation/faq.md +0 -713
- package/documentation/features.md +0 -403
- package/documentation/headroom.md +0 -519
- package/documentation/installation.md +0 -758
- package/documentation/memory-system.md +0 -476
- package/documentation/production.md +0 -636
- package/documentation/providers.md +0 -1009
- package/documentation/routing.md +0 -476
- package/documentation/testing.md +0 -629
- package/documentation/token-optimization.md +0 -325
- package/documentation/tools.md +0 -697
- package/documentation/troubleshooting.md +0 -969
- package/final-test.js +0 -33
- package/headroom-sidecar/config.py +0 -93
- package/headroom-sidecar/requirements.txt +0 -14
- package/headroom-sidecar/server.py +0 -451
- package/monitor-agents.sh +0 -31
- package/scripts/audit-log-reader.js +0 -399
- package/scripts/compact-dictionary.js +0 -204
- package/scripts/test-deduplication.js +0 -448
- package/src/db/database.sqlite +0 -0
- package/te +0 -11622
- package/test/README.md +0 -212
- package/test/azure-openai-config.test.js +0 -213
- package/test/azure-openai-error-resilience.test.js +0 -238
- package/test/azure-openai-format-conversion.test.js +0 -354
- package/test/azure-openai-integration.test.js +0 -287
- package/test/azure-openai-routing.test.js +0 -175
- package/test/azure-openai-streaming.test.js +0 -171
- package/test/bedrock-integration.test.js +0 -457
- package/test/comprehensive-test-suite.js +0 -928
- package/test/config-validation.test.js +0 -207
- package/test/cursor-integration.test.js +0 -484
- package/test/format-conversion.test.js +0 -578
- package/test/hybrid-routing-integration.test.js +0 -269
- package/test/hybrid-routing-performance.test.js +0 -428
- package/test/llamacpp-integration.test.js +0 -882
- package/test/lmstudio-integration.test.js +0 -347
- package/test/memory/extractor.test.js +0 -398
- package/test/memory/retriever.test.js +0 -613
- package/test/memory/retriever.test.js.bak +0 -585
- package/test/memory/search.test.js +0 -537
- package/test/memory/search.test.js.bak +0 -389
- package/test/memory/store.test.js +0 -344
- package/test/memory/store.test.js.bak +0 -312
- package/test/memory/surprise.test.js +0 -300
- package/test/memory-performance.test.js +0 -472
- package/test/openai-integration.test.js +0 -683
- package/test/openrouter-error-resilience.test.js +0 -418
- package/test/passthrough-mode.test.js +0 -385
- package/test/performance-benchmark.js +0 -351
- package/test/performance-tests.js +0 -528
- package/test/routing.test.js +0 -225
- package/test/toon-compression.test.js +0 -131
- package/test/web-tools.test.js +0 -329
- package/test-agents-simple.js +0 -43
- package/test-cli-connection.sh +0 -33
- package/test-learning-unit.js +0 -126
- package/test-learning.js +0 -112
- package/test-parallel-agents.sh +0 -124
- package/test-parallel-direct.js +0 -155
- package/test-subagents.sh +0 -117
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Mode — Meta-Tools for MCP Token Optimization
|
|
3
|
+
*
|
|
4
|
+
* Replaces 100+ individual MCP tool definitions with 4 meta-tools,
|
|
5
|
+
* reducing tool-catalog token overhead from ~17,500 to ~700 tokens.
|
|
6
|
+
*
|
|
7
|
+
* Inspired by Bifrost's Code Mode. Instead of sending every MCP tool
|
|
8
|
+
* schema in every request, the LLM discovers tools lazily:
|
|
9
|
+
* 1. mcp_list_tools → discover available tools (compact)
|
|
10
|
+
* 2. mcp_tool_info → load full schema for one tool
|
|
11
|
+
* 3. mcp_tool_docs → get usage examples
|
|
12
|
+
* 4. mcp_execute → execute a tool by name
|
|
13
|
+
*
|
|
14
|
+
* Activation: CODE_MODE_ENABLED=true
|
|
15
|
+
*
|
|
16
|
+
* @module tools/code-mode
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const { registerTool } = require('.');
|
|
20
|
+
const { listServers, ensureClient } = require('../mcp');
|
|
21
|
+
const config = require('../config');
|
|
22
|
+
const logger = require('../logger');
|
|
23
|
+
|
|
24
|
+
// ── Tool List Cache ─────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
let toolListCache = null;
|
|
27
|
+
let toolListCacheTs = 0;
|
|
28
|
+
|
|
29
|
+
function getCacheTtl() {
|
|
30
|
+
return config.mcp?.codeMode?.toolListCacheTtl || 60_000;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Fetch tool lists from all MCP servers, with caching.
|
|
35
|
+
* @param {string} [filterServerId] - Optional: only fetch from this server
|
|
36
|
+
* @param {boolean} [forceRefresh] - Bypass cache
|
|
37
|
+
* @returns {Promise<Object>} { serverId: [{ name, description }] }
|
|
38
|
+
*/
|
|
39
|
+
async function fetchToolList(filterServerId, forceRefresh = false) {
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
if (!forceRefresh && toolListCache && (now - toolListCacheTs < getCacheTtl())) {
|
|
42
|
+
if (filterServerId) {
|
|
43
|
+
return { [filterServerId]: toolListCache[filterServerId] || [] };
|
|
44
|
+
}
|
|
45
|
+
return toolListCache;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const servers = listServers();
|
|
49
|
+
const result = {};
|
|
50
|
+
|
|
51
|
+
await Promise.all(
|
|
52
|
+
servers.map(async (server) => {
|
|
53
|
+
if (filterServerId && server.id !== filterServerId) return;
|
|
54
|
+
try {
|
|
55
|
+
const client = await ensureClient(server.id);
|
|
56
|
+
if (!client) {
|
|
57
|
+
result[server.id] = { error: 'Server not available' };
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const response = await client.request('tools/list', {});
|
|
61
|
+
const tools = Array.isArray(response?.tools) ? response.tools : [];
|
|
62
|
+
result[server.id] = tools.map(t => ({
|
|
63
|
+
name: t.name ?? t.method ?? 'unknown',
|
|
64
|
+
description: (t.description || '').substring(0, 100),
|
|
65
|
+
}));
|
|
66
|
+
} catch (err) {
|
|
67
|
+
result[server.id] = { error: err.message };
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Update cache if we fetched all servers
|
|
73
|
+
if (!filterServerId) {
|
|
74
|
+
toolListCache = result;
|
|
75
|
+
toolListCacheTs = now;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return filterServerId ? { [filterServerId]: result[filterServerId] || [] } : result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Fetch full tool schema for a specific tool on a specific server.
|
|
83
|
+
* @param {string} serverId
|
|
84
|
+
* @param {string} toolName
|
|
85
|
+
* @returns {Promise<Object|null>}
|
|
86
|
+
*/
|
|
87
|
+
async function fetchToolSchema(serverId, toolName) {
|
|
88
|
+
const client = await ensureClient(serverId);
|
|
89
|
+
if (!client) return null;
|
|
90
|
+
|
|
91
|
+
const response = await client.request('tools/list', {});
|
|
92
|
+
const tools = Array.isArray(response?.tools) ? response.tools : [];
|
|
93
|
+
return tools.find(t => (t.name ?? t.method) === toolName) || null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Generate a usage example from a tool's input schema.
|
|
98
|
+
* @param {Object} tool - Tool definition with inputSchema
|
|
99
|
+
* @returns {string} Example JSON
|
|
100
|
+
*/
|
|
101
|
+
function generateExample(tool) {
|
|
102
|
+
const schema = tool.inputSchema || tool.input_schema || {};
|
|
103
|
+
const props = schema.properties || {};
|
|
104
|
+
const example = {};
|
|
105
|
+
|
|
106
|
+
for (const [key, def] of Object.entries(props)) {
|
|
107
|
+
if (def.type === 'string') example[key] = def.example || `<${key}>`;
|
|
108
|
+
else if (def.type === 'number' || def.type === 'integer') example[key] = def.example || 0;
|
|
109
|
+
else if (def.type === 'boolean') example[key] = def.example ?? true;
|
|
110
|
+
else if (def.type === 'array') example[key] = [];
|
|
111
|
+
else if (def.type === 'object') example[key] = {};
|
|
112
|
+
else example[key] = null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return JSON.stringify(example, null, 2);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ── Meta-Tool Registration ──────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
function registerCodeModeTools() {
|
|
121
|
+
// 1. mcp_list_tools — discover available tools
|
|
122
|
+
registerTool(
|
|
123
|
+
'mcp_list_tools',
|
|
124
|
+
async ({ args = {} }) => {
|
|
125
|
+
const serverId = args.server_id || null;
|
|
126
|
+
const forceRefresh = args.force_refresh === true;
|
|
127
|
+
const result = await fetchToolList(serverId, forceRefresh);
|
|
128
|
+
|
|
129
|
+
// Add summary stats
|
|
130
|
+
let totalTools = 0;
|
|
131
|
+
for (const tools of Object.values(result)) {
|
|
132
|
+
if (Array.isArray(tools)) totalTools += tools.length;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
ok: true,
|
|
137
|
+
status: 200,
|
|
138
|
+
content: JSON.stringify({ total_tools: totalTools, servers: result }, null, 2),
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
category: 'code-mode',
|
|
143
|
+
description: 'List all available MCP tools across all servers. Returns tool names and brief descriptions. Use this first to discover what tools are available.',
|
|
144
|
+
input_schema: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
server_id: { type: 'string', description: 'Optional: filter to a specific MCP server ID' },
|
|
148
|
+
force_refresh: { type: 'boolean', description: 'Bypass cache and refresh tool list' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// 2. mcp_tool_info — load full schema for one tool
|
|
155
|
+
registerTool(
|
|
156
|
+
'mcp_tool_info',
|
|
157
|
+
async ({ args = {} }) => {
|
|
158
|
+
const serverId = args.server_id;
|
|
159
|
+
const toolName = args.tool_name;
|
|
160
|
+
|
|
161
|
+
if (!serverId || !toolName) {
|
|
162
|
+
throw new Error('mcp_tool_info requires server_id and tool_name');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const tool = await fetchToolSchema(serverId, toolName);
|
|
166
|
+
if (!tool) {
|
|
167
|
+
throw new Error(`Tool "${toolName}" not found on server "${serverId}"`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
ok: true,
|
|
172
|
+
status: 200,
|
|
173
|
+
content: JSON.stringify({
|
|
174
|
+
server: serverId,
|
|
175
|
+
name: tool.name ?? tool.method,
|
|
176
|
+
description: tool.description || '',
|
|
177
|
+
inputSchema: tool.inputSchema || tool.input_schema || {},
|
|
178
|
+
}, null, 2),
|
|
179
|
+
};
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
category: 'code-mode',
|
|
183
|
+
description: 'Get the full schema and detailed description for a specific MCP tool. Use after mcp_list_tools to get the exact parameters needed before calling mcp_execute.',
|
|
184
|
+
input_schema: {
|
|
185
|
+
type: 'object',
|
|
186
|
+
properties: {
|
|
187
|
+
server_id: { type: 'string', description: 'MCP server ID' },
|
|
188
|
+
tool_name: { type: 'string', description: 'Tool name from mcp_list_tools' },
|
|
189
|
+
},
|
|
190
|
+
required: ['server_id', 'tool_name'],
|
|
191
|
+
},
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
// 3. mcp_tool_docs — usage examples
|
|
196
|
+
registerTool(
|
|
197
|
+
'mcp_tool_docs',
|
|
198
|
+
async ({ args = {} }) => {
|
|
199
|
+
const serverId = args.server_id;
|
|
200
|
+
const toolName = args.tool_name;
|
|
201
|
+
|
|
202
|
+
if (!serverId || !toolName) {
|
|
203
|
+
throw new Error('mcp_tool_docs requires server_id and tool_name');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const tool = await fetchToolSchema(serverId, toolName);
|
|
207
|
+
if (!tool) {
|
|
208
|
+
throw new Error(`Tool "${toolName}" not found on server "${serverId}"`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const schema = tool.inputSchema || tool.input_schema || {};
|
|
212
|
+
const params = Object.entries(schema.properties || {}).map(([name, def]) => ({
|
|
213
|
+
name,
|
|
214
|
+
type: def.type || 'any',
|
|
215
|
+
required: (schema.required || []).includes(name),
|
|
216
|
+
description: def.description || '',
|
|
217
|
+
}));
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
ok: true,
|
|
221
|
+
status: 200,
|
|
222
|
+
content: JSON.stringify({
|
|
223
|
+
server: serverId,
|
|
224
|
+
tool: tool.name ?? tool.method,
|
|
225
|
+
description: tool.description || '',
|
|
226
|
+
parameters: params,
|
|
227
|
+
example_arguments: generateExample(tool),
|
|
228
|
+
usage: `Use mcp_execute with server_id="${serverId}", tool_name="${toolName}", and arguments matching the schema above.`,
|
|
229
|
+
}, null, 2),
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
category: 'code-mode',
|
|
234
|
+
description: 'Get usage documentation, parameter details, and example arguments for an MCP tool.',
|
|
235
|
+
input_schema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
server_id: { type: 'string', description: 'MCP server ID' },
|
|
239
|
+
tool_name: { type: 'string', description: 'Tool name' },
|
|
240
|
+
},
|
|
241
|
+
required: ['server_id', 'tool_name'],
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// 4. mcp_execute — execute a tool by name
|
|
247
|
+
registerTool(
|
|
248
|
+
'mcp_execute',
|
|
249
|
+
async ({ args = {} }) => {
|
|
250
|
+
const serverId = args.server_id;
|
|
251
|
+
const toolName = args.tool_name;
|
|
252
|
+
const toolArgs = args.arguments ?? {};
|
|
253
|
+
|
|
254
|
+
if (!serverId || !toolName) {
|
|
255
|
+
throw new Error('mcp_execute requires server_id and tool_name');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const client = await ensureClient(serverId.trim());
|
|
259
|
+
if (!client) {
|
|
260
|
+
throw new Error(`MCP server "${serverId}" is not available.`);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const result = await client.request(toolName.trim(), toolArgs);
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
ok: true,
|
|
267
|
+
status: 200,
|
|
268
|
+
content: JSON.stringify({
|
|
269
|
+
server: serverId,
|
|
270
|
+
tool: toolName,
|
|
271
|
+
result,
|
|
272
|
+
}, null, 2),
|
|
273
|
+
metadata: { server: serverId, tool: toolName },
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
category: 'code-mode',
|
|
278
|
+
description: 'Execute an MCP tool by name with JSON arguments. First use mcp_list_tools to discover tools, then mcp_tool_info to get the schema, then this tool to execute.',
|
|
279
|
+
input_schema: {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
server_id: { type: 'string', description: 'MCP server ID' },
|
|
283
|
+
tool_name: { type: 'string', description: 'Tool method name' },
|
|
284
|
+
arguments: {
|
|
285
|
+
type: 'object',
|
|
286
|
+
description: 'JSON arguments matching the tool input schema',
|
|
287
|
+
additionalProperties: true,
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
required: ['server_id', 'tool_name'],
|
|
291
|
+
},
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
logger.info('[code-mode] Registered 4 meta-tools: mcp_list_tools, mcp_tool_info, mcp_tool_docs, mcp_execute');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
module.exports = {
|
|
299
|
+
registerCodeModeTools,
|
|
300
|
+
// Exported for testing
|
|
301
|
+
fetchToolList,
|
|
302
|
+
fetchToolSchema,
|
|
303
|
+
generateExample,
|
|
304
|
+
};
|
package/src/tools/index.js
CHANGED
|
@@ -30,6 +30,10 @@ const TOOL_ALIASES = {
|
|
|
30
30
|
WebSearch: "web_search",
|
|
31
31
|
web_fetch: "web_fetch",
|
|
32
32
|
webfetch: "web_fetch",
|
|
33
|
+
web_agent: "web_agent",
|
|
34
|
+
webagent: "web_agent",
|
|
35
|
+
WebAgent: "web_agent",
|
|
36
|
+
tinyfish: "web_agent",
|
|
33
37
|
task: "fs_write",
|
|
34
38
|
write: "fs_write",
|
|
35
39
|
filewrite: "fs_write",
|
package/src/tools/lazy-loader.js
CHANGED
|
@@ -57,6 +57,11 @@ const TOOL_CATEGORIES = {
|
|
|
57
57
|
loader: () => require('./tasks').registerTaskTools,
|
|
58
58
|
priority: 2,
|
|
59
59
|
},
|
|
60
|
+
tinyfish: {
|
|
61
|
+
keywords: ['tinyfish', 'web_agent', 'automate', 'scrape', 'extract', 'crawl', 'browser'],
|
|
62
|
+
loader: () => require('./tinyfish').registerTinyFishTools,
|
|
63
|
+
priority: 2,
|
|
64
|
+
},
|
|
60
65
|
tests: {
|
|
61
66
|
keywords: ['test', 'jest', 'mocha', 'pytest', 'unittest', 'spec', 'coverage', 'assert'],
|
|
62
67
|
loader: () => require('./tests').registerTestTools,
|
|
@@ -72,6 +77,11 @@ const TOOL_CATEGORIES = {
|
|
|
72
77
|
loader: () => require('./agent-task').registerAgentTaskTool,
|
|
73
78
|
priority: 2,
|
|
74
79
|
},
|
|
80
|
+
'code-mode': {
|
|
81
|
+
keywords: ['mcp', 'execute', 'server', 'tool', 'code mode'],
|
|
82
|
+
loader: () => require('./code-mode').registerCodeModeTools,
|
|
83
|
+
priority: 3,
|
|
84
|
+
},
|
|
75
85
|
};
|
|
76
86
|
|
|
77
87
|
/**
|
|
@@ -276,7 +286,15 @@ function loadCategoryForTool(toolName) {
|
|
|
276
286
|
'workspace_sandbox_sessions': 'mcp',
|
|
277
287
|
'workspace_mcp_servers': 'mcp',
|
|
278
288
|
|
|
289
|
+
// Code Mode meta-tools
|
|
290
|
+
'mcp_list_tools': 'code-mode',
|
|
291
|
+
'mcp_tool_info': 'code-mode',
|
|
292
|
+
'mcp_tool_docs': 'code-mode',
|
|
293
|
+
'mcp_execute': 'code-mode',
|
|
294
|
+
|
|
279
295
|
// Agent task
|
|
296
|
+
// TinyFish (web agent)
|
|
297
|
+
'web_agent': 'tinyfish',
|
|
280
298
|
'agent_task': 'agentTask',
|
|
281
299
|
};
|
|
282
300
|
|
package/src/tools/mcp-remote.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const { registerTool } = require(".");
|
|
2
2
|
const { listServers, ensureClient } = require("../mcp");
|
|
3
|
+
const config = require("../config");
|
|
3
4
|
const logger = require("../logger");
|
|
4
5
|
|
|
5
6
|
const REMOTE_TOOL_PREFIX = "mcp";
|
|
@@ -12,6 +13,12 @@ function sanitiseName(value) {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async function registerRemoteTools() {
|
|
16
|
+
// Code Mode: register 4 meta-tools instead of individual remote tools
|
|
17
|
+
if (config.mcp?.codeMode?.enabled) {
|
|
18
|
+
const { registerCodeModeTools } = require("./code-mode");
|
|
19
|
+
registerCodeModeTools();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
15
22
|
const servers = listServers();
|
|
16
23
|
await Promise.all(
|
|
17
24
|
servers.map(async (server) => {
|
|
@@ -316,6 +316,17 @@ function selectToolsSmartly(tools, classification, options = {}) {
|
|
|
316
316
|
selectedTools = selectedTools.filter(t => minimalTools.includes(t.name));
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
// Code Mode: always include the 4 meta-tools (only ~700 tokens total)
|
|
320
|
+
const codeConfig = require('../config');
|
|
321
|
+
if (codeConfig.mcp?.codeMode?.enabled) {
|
|
322
|
+
const codeModeNames = new Set(['mcp_list_tools', 'mcp_tool_info', 'mcp_tool_docs', 'mcp_execute']);
|
|
323
|
+
for (const tool of tools) {
|
|
324
|
+
if (codeModeNames.has(tool.name) && !selectedTools.some(t => t.name === tool.name)) {
|
|
325
|
+
selectedTools.push(tool);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
319
330
|
return selectedTools;
|
|
320
331
|
}
|
|
321
332
|
|