@neurynae/toolcairn-mcp 0.9.0 → 0.9.2
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/dist/index.js +74 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1424,7 +1424,8 @@ var initProjectConfigSchema = {
|
|
|
1424
1424
|
framework: z.string().optional(),
|
|
1425
1425
|
detected_tools: z.array(z.object({
|
|
1426
1426
|
name: z.string(),
|
|
1427
|
-
source
|
|
1427
|
+
// 'toolcairn' is the current canonical source; 'toolpilot' kept for pre-rename configs
|
|
1428
|
+
source: z.enum(["toolcairn", "toolpilot", "manual", "non_oss"]),
|
|
1428
1429
|
version: z.string().optional()
|
|
1429
1430
|
})).optional()
|
|
1430
1431
|
};
|
|
@@ -1512,7 +1513,7 @@ ${args.prompt}
|
|
|
1512
1513
|
"""${projectToolsContext}
|
|
1513
1514
|
|
|
1514
1515
|
Your response (one category name only):`;
|
|
1515
|
-
const needs_tool_search_prompt = `Based on this classification, determine if
|
|
1516
|
+
const needs_tool_search_prompt = `Based on this classification, determine if ToolCairn tool search should be invoked.
|
|
1516
1517
|
Respond with 1 if the classification is one of: tool_discovery, stack_building, tool_comparison
|
|
1517
1518
|
Respond with 0 if the classification is: tool_configuration, debugging, general_coding
|
|
1518
1519
|
Respond with ONLY 0 or 1.`;
|
|
@@ -1528,7 +1529,7 @@ Respond with ONLY 0 or 1.`;
|
|
|
1528
1529
|
"general_coding"
|
|
1529
1530
|
],
|
|
1530
1531
|
tool_required_if: TOOL_REQUIRED_CLASSIFICATIONS,
|
|
1531
|
-
instructions: "Step 1: Send classification_prompt to the LLM and get a classification. Step 2: If classification is in tool_required_if, call refine_requirement with the classification. Otherwise, proceed without
|
|
1532
|
+
instructions: "Step 1: Send classification_prompt to the LLM and get a classification. Step 2: If classification is in tool_required_if, call refine_requirement with the classification. Otherwise, proceed without ToolCairn search."
|
|
1532
1533
|
});
|
|
1533
1534
|
} catch (e) {
|
|
1534
1535
|
logger2.error({ err: e }, "classify_prompt failed");
|
|
@@ -1542,29 +1543,35 @@ var import_errors5 = __toESM(require_dist2(), 1);
|
|
|
1542
1543
|
|
|
1543
1544
|
// ../../packages/tools-local/dist/templates/agent-instructions.js
|
|
1544
1545
|
init_esm_shims();
|
|
1545
|
-
var
|
|
1546
|
-
|
|
1546
|
+
var IS_WINDOWS = process.platform === "win32";
|
|
1547
|
+
var TOOLCAIRN_MCP_ENTRY = IS_WINDOWS ? {
|
|
1548
|
+
toolcairn: {
|
|
1549
|
+
command: "cmd",
|
|
1550
|
+
args: ["/c", "npx", "-y", "@neurynae/toolcairn-mcp"]
|
|
1551
|
+
}
|
|
1552
|
+
} : {
|
|
1553
|
+
toolcairn: {
|
|
1547
1554
|
command: "npx",
|
|
1548
|
-
args: ["-y", "@toolcairn
|
|
1555
|
+
args: ["-y", "@neurynae/toolcairn-mcp"]
|
|
1549
1556
|
}
|
|
1550
1557
|
};
|
|
1551
1558
|
var CORE_RULES = `
|
|
1552
|
-
##
|
|
1559
|
+
## ToolCairn \u2014 Tool Intelligence MCP
|
|
1553
1560
|
|
|
1554
|
-
|
|
1561
|
+
ToolCairn is your tool intelligence co-pilot. It has a graph database of 500+ indexed tools with health signals, compatibility data, and known issue tracking. Always use it before recommending any tool, library, or framework.
|
|
1555
1562
|
|
|
1556
1563
|
### Workflow for Tool Selection
|
|
1557
1564
|
|
|
1558
1565
|
1. **Before recommending any tool**: Always call \`search_tools\` first. Never recommend from training data alone.
|
|
1559
1566
|
2. **When user describes a use case**: Call \`classify_prompt\` first, then \`refine_requirement\` if tool selection is needed.
|
|
1560
|
-
3. **When starting a new project**: Call \`
|
|
1561
|
-
4. **When resuming work on a project**: Read .
|
|
1567
|
+
3. **When starting a new project**: Call \`toolcairn_init\` to set up .toolcairn/config.json.
|
|
1568
|
+
4. **When resuming work on a project**: Read .toolcairn/config.json via \`read_project_config\` to see confirmed tools.
|
|
1562
1569
|
5. **When a tool is selected**: Call \`update_project_config\` to persist the choice.
|
|
1563
1570
|
6. **When encountering an error with a tool**: Call \`check_issue\` before debugging \u2014 it may be a known issue with an open GitHub ticket.
|
|
1564
1571
|
7. **When user asks to compare tools**: Call \`compare_tools\` for a structured comparison with health data.
|
|
1565
1572
|
8. **When user chooses a non-indexed/proprietary tool**: Add it to config with source: "non_oss" via \`update_project_config\`.
|
|
1566
1573
|
|
|
1567
|
-
### Available
|
|
1574
|
+
### Available ToolCairn MCP Tools
|
|
1568
1575
|
|
|
1569
1576
|
| Tool | When to use |
|
|
1570
1577
|
|------|------------|
|
|
@@ -1577,17 +1584,17 @@ ToolPilot is your tool intelligence co-pilot. It has a graph database of 500+ in
|
|
|
1577
1584
|
| \`check_compatibility\` | Check if two tools work well together |
|
|
1578
1585
|
| \`compare_tools\` | Compare two tools with health and graph data |
|
|
1579
1586
|
| \`report_outcome\` | Report whether a recommended tool worked (improves future results) |
|
|
1580
|
-
| \`
|
|
1581
|
-
| \`init_project_config\` | Initialize .
|
|
1582
|
-
| \`read_project_config\` | Parse .
|
|
1583
|
-
| \`update_project_config\` | Add/remove/update tools in .
|
|
1584
|
-
| \`suggest_graph_update\` | Suggest a new tool or relationship for the
|
|
1587
|
+
| \`toolcairn_init\` | Set up ToolCairn for a new project |
|
|
1588
|
+
| \`init_project_config\` | Initialize .toolcairn/config.json |
|
|
1589
|
+
| \`read_project_config\` | Parse .toolcairn/config.json to get confirmed tools |
|
|
1590
|
+
| \`update_project_config\` | Add/remove/update tools in .toolcairn/config.json |
|
|
1591
|
+
| \`suggest_graph_update\` | Suggest a new tool or relationship for the ToolCairn graph |
|
|
1585
1592
|
|
|
1586
1593
|
### Rules
|
|
1587
1594
|
|
|
1588
|
-
- NEVER recommend a tool without first checking
|
|
1589
|
-
- Always check .
|
|
1590
|
-
- Prefer open-source tools from
|
|
1595
|
+
- NEVER recommend a tool without first checking ToolCairn unless the tool is already in .toolcairn/config.json
|
|
1596
|
+
- Always check .toolcairn/config.json at the start of a session if it exists
|
|
1597
|
+
- Prefer open-source tools from ToolCairn index; flag proprietary alternatives clearly
|
|
1591
1598
|
- After selecting a tool, always call \`update_project_config\` to persist it
|
|
1592
1599
|
- After using a tool successfully/unsuccessfully, call \`report_outcome\`
|
|
1593
1600
|
`;
|
|
@@ -1663,20 +1670,29 @@ function getInstructionsForAgent(agent) {
|
|
|
1663
1670
|
function getMcpConfigEntry(serverPath) {
|
|
1664
1671
|
if (serverPath) {
|
|
1665
1672
|
return {
|
|
1666
|
-
|
|
1673
|
+
toolcairn: {
|
|
1667
1674
|
command: "node",
|
|
1668
1675
|
args: [serverPath]
|
|
1669
1676
|
}
|
|
1670
1677
|
};
|
|
1671
1678
|
}
|
|
1672
|
-
return
|
|
1679
|
+
return TOOLCAIRN_MCP_ENTRY;
|
|
1673
1680
|
}
|
|
1674
1681
|
function getOpenCodeMcpEntry(serverPath) {
|
|
1675
|
-
|
|
1682
|
+
if (serverPath) {
|
|
1683
|
+
return {
|
|
1684
|
+
toolcairn: {
|
|
1685
|
+
type: "local",
|
|
1686
|
+
command: ["node", serverPath],
|
|
1687
|
+
enabled: true
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
const command = IS_WINDOWS ? ["cmd", "/c", "npx", "-y", "@neurynae/toolcairn-mcp"] : ["npx", "-y", "@neurynae/toolcairn-mcp"];
|
|
1676
1692
|
return {
|
|
1677
|
-
|
|
1693
|
+
toolcairn: {
|
|
1678
1694
|
type: "local",
|
|
1679
|
-
command
|
|
1695
|
+
command,
|
|
1680
1696
|
enabled: true
|
|
1681
1697
|
}
|
|
1682
1698
|
};
|
|
@@ -1690,7 +1706,7 @@ function generateTrackerHtml2(eventsPath) {
|
|
|
1690
1706
|
<head>
|
|
1691
1707
|
<meta charset="UTF-8" />
|
|
1692
1708
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
1693
|
-
<title>
|
|
1709
|
+
<title>ToolCairn Tracker</title>
|
|
1694
1710
|
<style>
|
|
1695
1711
|
:root {
|
|
1696
1712
|
--bg: #0a0a0f;
|
|
@@ -1787,7 +1803,7 @@ function generateTrackerHtml2(eventsPath) {
|
|
|
1787
1803
|
<circle cx="10" cy="10" r="9" stroke="#7c5cfc" stroke-width="1.5"/>
|
|
1788
1804
|
<path d="M6 10h8M10 6v8" stroke="#7c5cfc" stroke-width="1.5" stroke-linecap="round"/>
|
|
1789
1805
|
</svg>
|
|
1790
|
-
<h1><span>Tool</span>
|
|
1806
|
+
<h1><span>Tool</span>Cairn Tracker</h1>
|
|
1791
1807
|
<div id="statusText" style="font-size:12px; color:var(--muted);">Loading...</div>
|
|
1792
1808
|
<div id="statusDot" class="status-dot paused"></div>
|
|
1793
1809
|
</header>
|
|
@@ -1816,7 +1832,7 @@ function generateTrackerHtml2(eventsPath) {
|
|
|
1816
1832
|
<div class="empty" id="emptyState">
|
|
1817
1833
|
<svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M13 20h14M20 13v14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1818
1834
|
<p>Waiting for MCP tool calls...</p>
|
|
1819
|
-
<code>Set
|
|
1835
|
+
<code>Set TOOLCAIRN_EVENTS_PATH in your MCP server env</code>
|
|
1820
1836
|
</div>
|
|
1821
1837
|
</div>
|
|
1822
1838
|
<div class="sidebar">
|
|
@@ -2078,7 +2094,7 @@ function renderAll() {
|
|
|
2078
2094
|
// \u2500\u2500\u2500 Boot \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2079
2095
|
if (!EVENTS_PATH || EVENTS_PATH === 'null') {
|
|
2080
2096
|
document.getElementById('statusText').textContent = 'No events path configured';
|
|
2081
|
-
document.getElementById('emptyState').querySelector('p').textContent = '
|
|
2097
|
+
document.getElementById('emptyState').querySelector('p').textContent = 'TOOLCAIRN_EVENTS_PATH not set in MCP server environment';
|
|
2082
2098
|
} else {
|
|
2083
2099
|
startPolling();
|
|
2084
2100
|
}
|
|
@@ -2088,19 +2104,19 @@ if (!EVENTS_PATH || EVENTS_PATH === 'null') {
|
|
|
2088
2104
|
}
|
|
2089
2105
|
|
|
2090
2106
|
// ../../packages/tools-local/dist/handlers/toolcairn-init.js
|
|
2091
|
-
var logger3 = (0, import_errors5.createMcpLogger)({ name: "@toolcairn/tools:
|
|
2107
|
+
var logger3 = (0, import_errors5.createMcpLogger)({ name: "@toolcairn/tools:toolcairn-init" });
|
|
2092
2108
|
async function handleToolcairnInit(args) {
|
|
2093
2109
|
try {
|
|
2094
|
-
logger3.info({ agent: args.agent, project_root: args.project_root }, "
|
|
2110
|
+
logger3.info({ agent: args.agent, project_root: args.project_root }, "toolcairn_init called");
|
|
2095
2111
|
const instructions = getInstructionsForAgent(args.agent);
|
|
2096
2112
|
const isOpenCode = args.agent === "opencode";
|
|
2097
2113
|
const mcpConfigEntry = isOpenCode ? getOpenCodeMcpEntry(args.server_path) : getMcpConfigEntry(args.server_path);
|
|
2098
2114
|
const mcpConfigFile = isOpenCode ? "opencode.json" : ".mcp.json";
|
|
2099
2115
|
const hasMcpJson = args.detected_files?.some((f) => f === mcpConfigFile || f.endsWith(`/${mcpConfigFile}`));
|
|
2100
2116
|
const hasInstructionFile = args.detected_files?.some((f) => f.endsWith(instructions.file_path));
|
|
2101
|
-
const
|
|
2102
|
-
const hasTrackerHtml = args.detected_files?.some((f) => f.includes(".
|
|
2103
|
-
const eventsPath = `${args.project_root}/.
|
|
2117
|
+
const hasToolcairnConfig = args.detected_files?.some((f) => f.includes(".toolcairn/config.json"));
|
|
2118
|
+
const hasTrackerHtml = args.detected_files?.some((f) => f.includes(".toolcairn/tracker.html"));
|
|
2119
|
+
const eventsPath = `${args.project_root}/.toolcairn/events.jsonl`;
|
|
2104
2120
|
const setupSteps = [];
|
|
2105
2121
|
let step = 1;
|
|
2106
2122
|
setupSteps.push({
|
|
@@ -2111,7 +2127,7 @@ async function handleToolcairnInit(args) {
|
|
|
2111
2127
|
note: hasInstructionFile ? `Append the content to your existing ${instructions.file_path}` : `Create ${instructions.file_path} with the content`
|
|
2112
2128
|
});
|
|
2113
2129
|
const mcpContent = isOpenCode ? JSON.stringify({ mcp: mcpConfigEntry }, null, 2) : JSON.stringify({ mcpServers: mcpConfigEntry }, null, 2);
|
|
2114
|
-
const mcpMergeNote = isOpenCode ? `Merge the
|
|
2130
|
+
const mcpMergeNote = isOpenCode ? `Merge the toolcairn entry into your existing ${mcpConfigFile} under "mcp"` : `Merge the toolcairn entry into your existing ${mcpConfigFile} under "mcpServers"`;
|
|
2115
2131
|
const mcpCreateNote = isOpenCode ? `Create ${mcpConfigFile} with this content (OpenCode MCP config format)` : `Create ${mcpConfigFile} with this content`;
|
|
2116
2132
|
setupSteps.push({
|
|
2117
2133
|
step: step++,
|
|
@@ -2120,29 +2136,29 @@ async function handleToolcairnInit(args) {
|
|
|
2120
2136
|
content: mcpContent,
|
|
2121
2137
|
note: hasMcpJson ? mcpMergeNote : mcpCreateNote
|
|
2122
2138
|
});
|
|
2123
|
-
if (!
|
|
2139
|
+
if (!hasToolcairnConfig) {
|
|
2124
2140
|
setupSteps.push({
|
|
2125
2141
|
step: step++,
|
|
2126
2142
|
action: "create",
|
|
2127
|
-
file: ".
|
|
2128
|
-
note: "Call init_project_config to generate the config content, then write to .
|
|
2143
|
+
file: ".toolcairn/config.json",
|
|
2144
|
+
note: "Call init_project_config to generate the config content, then write to .toolcairn/config.json"
|
|
2129
2145
|
});
|
|
2130
2146
|
}
|
|
2131
2147
|
if (!hasTrackerHtml) {
|
|
2132
2148
|
setupSteps.push({
|
|
2133
2149
|
step: step++,
|
|
2134
2150
|
action: "create",
|
|
2135
|
-
file: ".
|
|
2151
|
+
file: ".toolcairn/tracker.html",
|
|
2136
2152
|
content: generateTrackerHtml2(eventsPath),
|
|
2137
|
-
note: `Open .
|
|
2153
|
+
note: `Open .toolcairn/tracker.html in your browser to monitor MCP tool calls in real time. Set TOOLCAIRN_EVENTS_PATH=${eventsPath} in your MCP server environment to enable event logging.`
|
|
2138
2154
|
});
|
|
2139
2155
|
}
|
|
2140
2156
|
setupSteps.push({
|
|
2141
2157
|
step: step++,
|
|
2142
2158
|
action: "append",
|
|
2143
2159
|
file: ".gitignore",
|
|
2144
|
-
content: "\n#
|
|
2145
|
-
note: "Add .
|
|
2160
|
+
content: "\n# ToolCairn\n.toolcairn/events.jsonl\n",
|
|
2161
|
+
note: "Add .toolcairn/events.jsonl to .gitignore (the tracker event log)"
|
|
2146
2162
|
});
|
|
2147
2163
|
const agentFileLabel = {
|
|
2148
2164
|
claude: "CLAUDE.md",
|
|
@@ -2160,16 +2176,16 @@ async function handleToolcairnInit(args) {
|
|
|
2160
2176
|
mcp_config_entry: mcpConfigEntry,
|
|
2161
2177
|
events_path: eventsPath,
|
|
2162
2178
|
summary: [
|
|
2163
|
-
`
|
|
2179
|
+
`ToolCairn setup for ${args.agent} agent in ${args.project_root}`,
|
|
2164
2180
|
`Instructions will be added to: ${instructions.file_path}`,
|
|
2165
|
-
`MCP server entry:
|
|
2166
|
-
|
|
2167
|
-
hasTrackerHtml ? ".
|
|
2181
|
+
`MCP server entry: toolcairn \u2192 ${mcpConfigFile}`,
|
|
2182
|
+
hasToolcairnConfig ? ".toolcairn/config.json already exists \u2014 skipping init" : "Run init_project_config next to generate .toolcairn/config.json",
|
|
2183
|
+
hasTrackerHtml ? ".toolcairn/tracker.html already exists \u2014 skipping" : "Tracker dashboard: open .toolcairn/tracker.html in browser"
|
|
2168
2184
|
].join("\n"),
|
|
2169
|
-
next_steps:
|
|
2185
|
+
next_steps: hasToolcairnConfig ? "Setup complete. Open .toolcairn/tracker.html to monitor tool calls." : "After completing setup steps, call init_project_config to initialize .toolcairn/config.json."
|
|
2170
2186
|
});
|
|
2171
2187
|
} catch (e) {
|
|
2172
|
-
logger3.error({ err: e }, "
|
|
2188
|
+
logger3.error({ err: e }, "toolcairn_init failed");
|
|
2173
2189
|
return errResult("init_error", e instanceof Error ? e.message : String(e));
|
|
2174
2190
|
}
|
|
2175
2191
|
}
|
|
@@ -2187,7 +2203,7 @@ async function handleInitProjectConfig(args) {
|
|
|
2187
2203
|
source: t.source,
|
|
2188
2204
|
version: t.version,
|
|
2189
2205
|
chosen_at: now,
|
|
2190
|
-
chosen_reason: "Auto-detected from project files during
|
|
2206
|
+
chosen_reason: "Auto-detected from project files during toolcairn_init",
|
|
2191
2207
|
alternatives_considered: []
|
|
2192
2208
|
}));
|
|
2193
2209
|
const config5 = {
|
|
@@ -2213,8 +2229,8 @@ async function handleInitProjectConfig(args) {
|
|
|
2213
2229
|
const config_json = JSON.stringify(config5, null, 2);
|
|
2214
2230
|
return okResult({
|
|
2215
2231
|
config_json,
|
|
2216
|
-
file_path: ".
|
|
2217
|
-
instructions: "Create the directory .
|
|
2232
|
+
file_path: ".toolcairn/config.json",
|
|
2233
|
+
instructions: "Create the directory .toolcairn/ in your project root (if it does not exist), then write this config_json content to .toolcairn/config.json. Also add .toolcairn/ to .gitignore if not already present.",
|
|
2218
2234
|
confirmed_count: confirmedTools.length,
|
|
2219
2235
|
next_step: confirmedTools.length > 0 ? "Config initialized with auto-detected tools. Use search_tools to find any additional tools you need." : "Config initialized. Use classify_prompt \u2192 refine_requirement \u2192 search_tools to discover tools for your project."
|
|
2220
2236
|
});
|
|
@@ -2260,13 +2276,13 @@ async function handleReadProjectConfig(args) {
|
|
|
2260
2276
|
};
|
|
2261
2277
|
});
|
|
2262
2278
|
const non_oss_tools = config5.tools.confirmed.filter((t) => t.source === "non_oss").map((t) => t.name);
|
|
2263
|
-
const
|
|
2279
|
+
const toolcairn_indexed_tools = config5.tools.confirmed.filter((t) => t.source === "toolcairn" || t.source === "toolpilot").map((t) => t.name);
|
|
2264
2280
|
return okResult({
|
|
2265
2281
|
project: config5.project,
|
|
2266
2282
|
confirmed_tools: confirmedToolNames,
|
|
2267
2283
|
pending_tools: pendingToolNames,
|
|
2268
2284
|
non_oss_tools,
|
|
2269
|
-
|
|
2285
|
+
toolcairn_indexed_tools,
|
|
2270
2286
|
stale_tools: staleTools,
|
|
2271
2287
|
total_confirmed: confirmedToolNames.length,
|
|
2272
2288
|
total_pending: pendingToolNames.length,
|
|
@@ -2306,11 +2322,11 @@ async function handleUpdateProjectConfig(args) {
|
|
|
2306
2322
|
if (!config5.tools.confirmed.some((t) => t.name === args.tool_name)) {
|
|
2307
2323
|
const newTool = {
|
|
2308
2324
|
name: args.tool_name,
|
|
2309
|
-
source: data.source ?? "
|
|
2325
|
+
source: data.source ?? "toolcairn",
|
|
2310
2326
|
github_url: data.github_url,
|
|
2311
2327
|
version: data.version,
|
|
2312
2328
|
chosen_at: now,
|
|
2313
|
-
chosen_reason: data.chosen_reason ?? "Selected via
|
|
2329
|
+
chosen_reason: data.chosen_reason ?? "Selected via ToolCairn",
|
|
2314
2330
|
alternatives_considered: data.alternatives_considered ?? [],
|
|
2315
2331
|
query_id: data.query_id,
|
|
2316
2332
|
notes: data.notes
|
|
@@ -2321,7 +2337,7 @@ async function handleUpdateProjectConfig(args) {
|
|
|
2321
2337
|
action: "add_tool",
|
|
2322
2338
|
tool: args.tool_name,
|
|
2323
2339
|
timestamp: now,
|
|
2324
|
-
reason: data.chosen_reason ?? "Added via
|
|
2340
|
+
reason: data.chosen_reason ?? "Added via ToolCairn recommendation"
|
|
2325
2341
|
});
|
|
2326
2342
|
break;
|
|
2327
2343
|
}
|
|
@@ -2381,12 +2397,12 @@ async function handleUpdateProjectConfig(args) {
|
|
|
2381
2397
|
const updated_config_json = JSON.stringify(config5, null, 2);
|
|
2382
2398
|
return okResult({
|
|
2383
2399
|
updated_config_json,
|
|
2384
|
-
file_path: ".
|
|
2400
|
+
file_path: ".toolcairn/config.json",
|
|
2385
2401
|
action_applied: args.action,
|
|
2386
2402
|
tool_name: args.tool_name,
|
|
2387
2403
|
confirmed_count: config5.tools.confirmed.length,
|
|
2388
2404
|
pending_count: config5.tools.pending_evaluation.length,
|
|
2389
|
-
instructions: "Write updated_config_json to .
|
|
2405
|
+
instructions: "Write updated_config_json to .toolcairn/config.json to persist this change."
|
|
2390
2406
|
});
|
|
2391
2407
|
} catch (e) {
|
|
2392
2408
|
logger6.error({ err: e }, "update_project_config failed");
|
|
@@ -2642,7 +2658,7 @@ async function addToolsToServer(server) {
|
|
|
2642
2658
|
server.registerTool(
|
|
2643
2659
|
"get_stack",
|
|
2644
2660
|
{
|
|
2645
|
-
description: 'Build a complementary tool stack for a project use case. For best results, call refine_requirement first with classification "stack_building", evaluate its decomposition_prompt to get sub-needs, then pass each {sub_need_type, keyword_sentence} object as a sub_needs entry. This lets get_stack keyword-match per layer (e.g. "web-framework", "database", "auth") instead of one broad search. Falls back to balanced search when sub_needs is omitted.',
|
|
2661
|
+
description: 'Build a complementary tool stack for a project use case. For best results, call refine_requirement first with classification "stack_building", evaluate its decomposition_prompt to get sub-needs, then pass each {sub_need_type, keyword_sentence} object as a sub_needs entry. This lets get_stack keyword-match per layer (e.g. "web-framework", "database", "auth") instead of one broad search. Falls back to balanced search when sub_needs is omitted. Each tool in the returned stack also carries a `version` object with the recommended version that is cross-compatible with the rest of the stack (downgraded from latest if needed to satisfy peer constraints), plus a top-level `compatibility_matrix` + `stack_compatibility` summarising cross-tool version fit.',
|
|
2646
2662
|
inputSchema: getStackSchema
|
|
2647
2663
|
},
|
|
2648
2664
|
wrap("get_stack", async (args) => remote.getStack(args))
|