@neurynae/toolcairn-mcp 0.1.4 → 0.3.0
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/README.md +209 -0
- package/dist/{dist-2HK3ZGXE.js → dist-LZ2PMHGT.js} +72 -5
- package/dist/{dist-2HK3ZGXE.js.map → dist-LZ2PMHGT.js.map} +1 -1
- package/dist/index.js +196 -115
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -79,7 +79,7 @@ function generateTrackerHtml(eventsPath) {
|
|
|
79
79
|
<head>
|
|
80
80
|
<meta charset="UTF-8" />
|
|
81
81
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
82
|
-
<title>
|
|
82
|
+
<title>ToolCairn Tracker</title>
|
|
83
83
|
<style>
|
|
84
84
|
:root {
|
|
85
85
|
--bg: #0a0a0f;
|
|
@@ -205,7 +205,7 @@ function generateTrackerHtml(eventsPath) {
|
|
|
205
205
|
<div class="empty" id="emptyState">
|
|
206
206
|
<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>
|
|
207
207
|
<p>Waiting for MCP tool calls...</p>
|
|
208
|
-
<code>Set
|
|
208
|
+
<code>Set TOOLCAIRN_EVENTS_PATH in your MCP server env</code>
|
|
209
209
|
</div>
|
|
210
210
|
</div>
|
|
211
211
|
<div class="sidebar">
|
|
@@ -467,7 +467,7 @@ function renderAll() {
|
|
|
467
467
|
// \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
|
|
468
468
|
if (!EVENTS_PATH || EVENTS_PATH === 'null') {
|
|
469
469
|
document.getElementById('statusText').textContent = 'No events path configured';
|
|
470
|
-
document.getElementById('emptyState').querySelector('p').textContent = '
|
|
470
|
+
document.getElementById('emptyState').querySelector('p').textContent = 'TOOLCAIRN_EVENTS_PATH not set in MCP server environment';
|
|
471
471
|
} else {
|
|
472
472
|
startPolling();
|
|
473
473
|
}
|
|
@@ -477,7 +477,7 @@ if (!EVENTS_PATH || EVENTS_PATH === 'null') {
|
|
|
477
477
|
}
|
|
478
478
|
|
|
479
479
|
// src/project-setup.ts
|
|
480
|
-
var logger = pino({ name: "@
|
|
480
|
+
var logger = pino({ name: "@toolcairn/mcp-server:project-setup" });
|
|
481
481
|
var INITIAL_CONFIG = {
|
|
482
482
|
version: "1.0",
|
|
483
483
|
project: {
|
|
@@ -552,13 +552,15 @@ init_esm_shims();
|
|
|
552
552
|
// ../../packages/remote/dist/client.js
|
|
553
553
|
init_esm_shims();
|
|
554
554
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
555
|
-
var
|
|
555
|
+
var ToolCairnClient = class {
|
|
556
556
|
baseUrl;
|
|
557
557
|
apiKey;
|
|
558
558
|
timeoutMs;
|
|
559
|
+
accessToken;
|
|
559
560
|
constructor(opts) {
|
|
560
561
|
this.baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
561
562
|
this.apiKey = opts.apiKey;
|
|
563
|
+
this.accessToken = opts.accessToken;
|
|
562
564
|
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
563
565
|
}
|
|
564
566
|
// ── Core Search ──────────────────────────────────────────────────────────
|
|
@@ -630,7 +632,7 @@ var ToolPilotClient = class {
|
|
|
630
632
|
text: JSON.stringify({
|
|
631
633
|
ok: false,
|
|
632
634
|
error: "network_error",
|
|
633
|
-
message: `
|
|
635
|
+
message: `ToolCairn API unreachable: ${msg}. Check your internet connection or try again later.`
|
|
634
636
|
})
|
|
635
637
|
}
|
|
636
638
|
],
|
|
@@ -639,13 +641,17 @@ var ToolPilotClient = class {
|
|
|
639
641
|
}
|
|
640
642
|
}
|
|
641
643
|
rawPost(path, body) {
|
|
644
|
+
const headers = {
|
|
645
|
+
"Content-Type": "application/json",
|
|
646
|
+
"X-ToolCairn-Key": this.apiKey,
|
|
647
|
+
"Accept-Encoding": "gzip"
|
|
648
|
+
};
|
|
649
|
+
if (this.accessToken) {
|
|
650
|
+
headers.Authorization = `Bearer ${this.accessToken}`;
|
|
651
|
+
}
|
|
642
652
|
return fetch(`${this.baseUrl}${path}`, {
|
|
643
653
|
method: "POST",
|
|
644
|
-
headers
|
|
645
|
-
"Content-Type": "application/json",
|
|
646
|
-
"X-ToolPilot-Key": this.apiKey,
|
|
647
|
-
"Accept-Encoding": "gzip"
|
|
648
|
-
},
|
|
654
|
+
headers,
|
|
649
655
|
body: JSON.stringify(body),
|
|
650
656
|
signal: AbortSignal.timeout(this.timeoutMs)
|
|
651
657
|
});
|
|
@@ -681,60 +687,63 @@ async function saveCredentials(creds) {
|
|
|
681
687
|
await writeFile2(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), "utf-8");
|
|
682
688
|
}
|
|
683
689
|
|
|
690
|
+
// ../../packages/remote/dist/device-auth.js
|
|
691
|
+
init_esm_shims();
|
|
692
|
+
|
|
684
693
|
// ../../packages/tools/dist/local.js
|
|
685
694
|
init_esm_shims();
|
|
686
695
|
|
|
687
696
|
// ../../packages/tools/dist/schemas.js
|
|
688
697
|
init_esm_shims();
|
|
689
|
-
import { z } from "zod";
|
|
698
|
+
import { z as z2 } from "zod";
|
|
690
699
|
var searchToolsSchema = {
|
|
691
|
-
query:
|
|
692
|
-
context:
|
|
693
|
-
query_id:
|
|
694
|
-
user_id:
|
|
700
|
+
query: z2.string().min(1).max(500),
|
|
701
|
+
context: z2.object({ filters: z2.record(z2.string(), z2.unknown()) }).optional(),
|
|
702
|
+
query_id: z2.string().uuid().optional(),
|
|
703
|
+
user_id: z2.string().optional()
|
|
695
704
|
};
|
|
696
705
|
var searchToolsRespondSchema = {
|
|
697
|
-
query_id:
|
|
698
|
-
answers:
|
|
706
|
+
query_id: z2.string().uuid(),
|
|
707
|
+
answers: z2.array(z2.object({ dimension: z2.string(), value: z2.string() }))
|
|
699
708
|
};
|
|
700
709
|
var reportOutcomeSchema = {
|
|
701
|
-
query_id:
|
|
702
|
-
chosen_tool:
|
|
703
|
-
reason:
|
|
704
|
-
outcome:
|
|
705
|
-
feedback:
|
|
706
|
-
replaced_by:
|
|
710
|
+
query_id: z2.string().uuid(),
|
|
711
|
+
chosen_tool: z2.string(),
|
|
712
|
+
reason: z2.string().optional(),
|
|
713
|
+
outcome: z2.enum(["success", "failure", "replaced", "pending"]),
|
|
714
|
+
feedback: z2.string().optional(),
|
|
715
|
+
replaced_by: z2.string().optional()
|
|
707
716
|
};
|
|
708
717
|
var getStackSchema = {
|
|
709
|
-
use_case:
|
|
710
|
-
constraints:
|
|
711
|
-
deployment_model:
|
|
712
|
-
language:
|
|
713
|
-
license:
|
|
718
|
+
use_case: z2.string().min(1),
|
|
719
|
+
constraints: z2.object({
|
|
720
|
+
deployment_model: z2.enum(["self-hosted", "cloud", "embedded", "serverless"]).optional(),
|
|
721
|
+
language: z2.string().optional(),
|
|
722
|
+
license: z2.string().optional()
|
|
714
723
|
}).optional(),
|
|
715
|
-
limit:
|
|
724
|
+
limit: z2.number().int().positive().max(10).default(5)
|
|
716
725
|
};
|
|
717
726
|
var checkIssueSchema = {
|
|
718
|
-
tool_name:
|
|
719
|
-
issue_title:
|
|
720
|
-
retry_count:
|
|
721
|
-
docs_consulted:
|
|
722
|
-
issue_url:
|
|
727
|
+
tool_name: z2.string(),
|
|
728
|
+
issue_title: z2.string(),
|
|
729
|
+
retry_count: z2.number().int().min(0).default(0),
|
|
730
|
+
docs_consulted: z2.boolean().default(false),
|
|
731
|
+
issue_url: z2.string().url().optional()
|
|
723
732
|
};
|
|
724
733
|
var checkCompatibilitySchema = {
|
|
725
|
-
tool_a:
|
|
726
|
-
tool_b:
|
|
734
|
+
tool_a: z2.string(),
|
|
735
|
+
tool_b: z2.string()
|
|
727
736
|
};
|
|
728
737
|
var suggestGraphUpdateSchema = {
|
|
729
|
-
suggestion_type:
|
|
730
|
-
data:
|
|
731
|
-
tool_name:
|
|
732
|
-
github_url:
|
|
733
|
-
description:
|
|
734
|
-
relationship:
|
|
735
|
-
source_tool:
|
|
736
|
-
target_tool:
|
|
737
|
-
edge_type:
|
|
738
|
+
suggestion_type: z2.enum(["new_tool", "new_edge", "update_health", "new_use_case"]),
|
|
739
|
+
data: z2.object({
|
|
740
|
+
tool_name: z2.string().optional(),
|
|
741
|
+
github_url: z2.string().url().optional(),
|
|
742
|
+
description: z2.string().optional(),
|
|
743
|
+
relationship: z2.object({
|
|
744
|
+
source_tool: z2.string(),
|
|
745
|
+
target_tool: z2.string(),
|
|
746
|
+
edge_type: z2.enum([
|
|
738
747
|
"SOLVES",
|
|
739
748
|
"REQUIRES",
|
|
740
749
|
"INTEGRATES_WITH",
|
|
@@ -744,68 +753,68 @@ var suggestGraphUpdateSchema = {
|
|
|
744
753
|
"BREAKS_FROM",
|
|
745
754
|
"COMPATIBLE_WITH"
|
|
746
755
|
]),
|
|
747
|
-
evidence:
|
|
756
|
+
evidence: z2.string().optional()
|
|
748
757
|
}).optional(),
|
|
749
|
-
use_case:
|
|
750
|
-
name:
|
|
751
|
-
description:
|
|
752
|
-
tools:
|
|
758
|
+
use_case: z2.object({
|
|
759
|
+
name: z2.string(),
|
|
760
|
+
description: z2.string(),
|
|
761
|
+
tools: z2.array(z2.string()).optional()
|
|
753
762
|
}).optional()
|
|
754
763
|
}),
|
|
755
|
-
query_id:
|
|
756
|
-
confidence:
|
|
764
|
+
query_id: z2.string().uuid().optional(),
|
|
765
|
+
confidence: z2.number().min(0).max(1).default(0.5)
|
|
757
766
|
};
|
|
758
767
|
var compareToolsSchema = {
|
|
759
|
-
tool_a:
|
|
760
|
-
tool_b:
|
|
761
|
-
use_case:
|
|
762
|
-
project_config:
|
|
768
|
+
tool_a: z2.string().min(1),
|
|
769
|
+
tool_b: z2.string().min(1),
|
|
770
|
+
use_case: z2.string().optional(),
|
|
771
|
+
project_config: z2.string().max(1e5).optional()
|
|
763
772
|
};
|
|
764
773
|
var toolpilotInitSchema = {
|
|
765
|
-
agent:
|
|
766
|
-
project_root:
|
|
767
|
-
server_path:
|
|
768
|
-
detected_files:
|
|
774
|
+
agent: z2.enum(["claude", "cursor", "windsurf", "copilot", "copilot-cli", "opencode", "generic"]),
|
|
775
|
+
project_root: z2.string().min(1),
|
|
776
|
+
server_path: z2.string().optional(),
|
|
777
|
+
detected_files: z2.array(z2.string()).optional()
|
|
769
778
|
};
|
|
770
779
|
var initProjectConfigSchema = {
|
|
771
|
-
project_name:
|
|
772
|
-
language:
|
|
773
|
-
framework:
|
|
774
|
-
detected_tools:
|
|
775
|
-
name:
|
|
776
|
-
source:
|
|
777
|
-
version:
|
|
780
|
+
project_name: z2.string().min(1).max(200),
|
|
781
|
+
language: z2.string().min(1).max(50),
|
|
782
|
+
framework: z2.string().optional(),
|
|
783
|
+
detected_tools: z2.array(z2.object({
|
|
784
|
+
name: z2.string(),
|
|
785
|
+
source: z2.enum(["toolpilot", "manual", "non_oss"]),
|
|
786
|
+
version: z2.string().optional()
|
|
778
787
|
})).optional()
|
|
779
788
|
};
|
|
780
789
|
var readProjectConfigSchema = {
|
|
781
|
-
config_content:
|
|
790
|
+
config_content: z2.string().min(1).max(1e5)
|
|
782
791
|
};
|
|
783
792
|
var updateProjectConfigSchema = {
|
|
784
|
-
current_config:
|
|
785
|
-
action:
|
|
786
|
-
tool_name:
|
|
787
|
-
data:
|
|
793
|
+
current_config: z2.string().min(1).max(1e5),
|
|
794
|
+
action: z2.enum(["add_tool", "remove_tool", "update_tool", "add_evaluation"]),
|
|
795
|
+
tool_name: z2.string().min(1),
|
|
796
|
+
data: z2.record(z2.string(), z2.unknown()).optional()
|
|
788
797
|
};
|
|
789
798
|
var classifyPromptSchema = {
|
|
790
|
-
prompt:
|
|
791
|
-
project_tools:
|
|
799
|
+
prompt: z2.string().min(1).max(2e3),
|
|
800
|
+
project_tools: z2.array(z2.string()).optional()
|
|
792
801
|
};
|
|
793
802
|
var verifySuggestionSchema = {
|
|
794
|
-
query:
|
|
795
|
-
agent_suggestions:
|
|
803
|
+
query: z2.string().min(1).max(500),
|
|
804
|
+
agent_suggestions: z2.array(z2.string().min(1)).min(1).max(10)
|
|
796
805
|
};
|
|
797
806
|
var refineRequirementSchema = {
|
|
798
|
-
prompt:
|
|
799
|
-
classification:
|
|
807
|
+
prompt: z2.string().min(1).max(2e3),
|
|
808
|
+
classification: z2.enum([
|
|
800
809
|
"tool_discovery",
|
|
801
810
|
"stack_building",
|
|
802
811
|
"tool_comparison",
|
|
803
812
|
"tool_configuration"
|
|
804
813
|
]),
|
|
805
|
-
project_context:
|
|
806
|
-
existing_tools:
|
|
807
|
-
language:
|
|
808
|
-
framework:
|
|
814
|
+
project_context: z2.object({
|
|
815
|
+
existing_tools: z2.array(z2.string()).optional(),
|
|
816
|
+
language: z2.string().optional(),
|
|
817
|
+
framework: z2.string().optional()
|
|
809
818
|
}).optional()
|
|
810
819
|
};
|
|
811
820
|
|
|
@@ -1751,12 +1760,12 @@ init_esm_shims();
|
|
|
1751
1760
|
import { appendFile, mkdir as mkdir3 } from "fs/promises";
|
|
1752
1761
|
import { dirname } from "path";
|
|
1753
1762
|
import pino7 from "pino";
|
|
1754
|
-
var logger7 = pino7({ name: "@
|
|
1763
|
+
var logger7 = pino7({ name: "@toolcairn/mcp-server:event-logger" });
|
|
1755
1764
|
var _prisma = null;
|
|
1756
1765
|
async function getPrisma() {
|
|
1757
1766
|
if (!_prisma) {
|
|
1758
1767
|
try {
|
|
1759
|
-
const mod = await import("./dist-
|
|
1768
|
+
const mod = await import("./dist-LZ2PMHGT.js");
|
|
1760
1769
|
_prisma = new mod.PrismaClient();
|
|
1761
1770
|
} catch {
|
|
1762
1771
|
}
|
|
@@ -1764,10 +1773,10 @@ async function getPrisma() {
|
|
|
1764
1773
|
return _prisma;
|
|
1765
1774
|
}
|
|
1766
1775
|
function isTrackingEnabled() {
|
|
1767
|
-
return process.env.
|
|
1776
|
+
return process.env.TOOLCAIRN_TRACKING_ENABLED !== "false";
|
|
1768
1777
|
}
|
|
1769
1778
|
function getEventsPath() {
|
|
1770
|
-
return process.env.
|
|
1779
|
+
return process.env.TOOLCAIRN_EVENTS_PATH ?? null;
|
|
1771
1780
|
}
|
|
1772
1781
|
function extractQueryId(args) {
|
|
1773
1782
|
if (typeof args.query_id === "string") return args.query_id;
|
|
@@ -1866,37 +1875,37 @@ function withEventLogging(toolName, handler) {
|
|
|
1866
1875
|
}
|
|
1867
1876
|
|
|
1868
1877
|
// src/server.prod.ts
|
|
1869
|
-
var logger8 = pino8({ name: "@
|
|
1878
|
+
var logger8 = pino8({ name: "@toolcairn/mcp-server:prod" });
|
|
1870
1879
|
var SETUP_INSTRUCTIONS = `
|
|
1871
|
-
#
|
|
1880
|
+
# ToolCairn \u2014 Agent Setup Instructions
|
|
1872
1881
|
|
|
1873
|
-
You are connected to the
|
|
1882
|
+
You are connected to the ToolCairn MCP server. ToolCairn is your active tool intelligence co-pilot.
|
|
1874
1883
|
|
|
1875
1884
|
## On Every Session Start \u2014 Do This First
|
|
1876
1885
|
|
|
1877
|
-
Read \`.
|
|
1886
|
+
Read \`.toolcairn/config.json\` in the project root. The server auto-creates this file on startup,
|
|
1878
1887
|
so it will almost always exist \u2014 but it may be an empty scaffold that still needs configuration.
|
|
1879
1888
|
|
|
1880
1889
|
### Case 1 \u2014 File does NOT exist (rare: read-only filesystem or manual deletion):
|
|
1881
1890
|
1. List the project root files (package.json, requirements.txt, CLAUDE.md, .cursorrules, .mcp.json, etc.)
|
|
1882
|
-
2. Call \`
|
|
1891
|
+
2. Call \`toolcairn_init\` with your agent type, project root path, and the list of detected files.
|
|
1883
1892
|
3. Call \`init_project_config\` \u2014 pass project name, language, framework, and any tools you detect.
|
|
1884
|
-
4. Write the returned \`config_json\` to \`.
|
|
1893
|
+
4. Write the returned \`config_json\` to \`.toolcairn/config.json\`.
|
|
1885
1894
|
|
|
1886
1895
|
### Case 2 \u2014 File EXISTS but \`project.name\` is empty (auto-created scaffold \u2014 not yet configured):
|
|
1887
1896
|
The server wrote the file at startup. You still need to fill in the project details:
|
|
1888
1897
|
1. List the project root files to detect the tech stack.
|
|
1889
|
-
2. Call \`
|
|
1890
|
-
This appends
|
|
1898
|
+
2. Call \`toolcairn_init\` with your agent type, project root, and detected files.
|
|
1899
|
+
This appends ToolCairn rules to CLAUDE.md (or equivalent) and sets up the tracker.
|
|
1891
1900
|
3. Call \`init_project_config\` with the project name, language, framework, and detected tools.
|
|
1892
|
-
4. Write the returned \`config_json\` to \`.
|
|
1901
|
+
4. Write the returned \`config_json\` to \`.toolcairn/config.json\` (overwrites the empty scaffold).
|
|
1893
1902
|
|
|
1894
1903
|
### Case 3 \u2014 File EXISTS and \`project.name\` is set (returning to a configured project):
|
|
1895
1904
|
1. Call \`read_project_config\` with the file content.
|
|
1896
1905
|
2. If \`stale_tools\` is non-empty, inform the user and offer to re-verify those tools.
|
|
1897
1906
|
3. If \`pending_evaluation\` is non-empty, offer to run \`search_tools\` or \`compare_tools\`.
|
|
1898
1907
|
|
|
1899
|
-
## When to Use
|
|
1908
|
+
## When to Use ToolCairn Tools
|
|
1900
1909
|
|
|
1901
1910
|
| Situation | Tool to call |
|
|
1902
1911
|
|-----------|-------------|
|
|
@@ -1912,38 +1921,43 @@ The server wrote the file at startup. You still need to fill in the project deta
|
|
|
1912
1921
|
`.trim();
|
|
1913
1922
|
async function buildProdServer() {
|
|
1914
1923
|
const creds = await loadOrCreateCredentials();
|
|
1915
|
-
const remote = new
|
|
1924
|
+
const remote = new ToolCairnClient({
|
|
1916
1925
|
baseUrl: import_config.config.TOOLPILOT_API_URL,
|
|
1917
|
-
apiKey: creds.client_id
|
|
1926
|
+
apiKey: creds.client_id,
|
|
1927
|
+
accessToken: creds.access_token
|
|
1918
1928
|
});
|
|
1919
1929
|
logger8.info(
|
|
1920
|
-
{
|
|
1930
|
+
{
|
|
1931
|
+
apiUrl: import_config.config.TOOLPILOT_API_URL,
|
|
1932
|
+
clientId: `${creds.client_id.slice(0, 8)}...`,
|
|
1933
|
+
authenticated: !!creds.access_token
|
|
1934
|
+
},
|
|
1921
1935
|
"Production MCP mode: connecting to remote API"
|
|
1922
1936
|
);
|
|
1923
1937
|
const server = new McpServer(
|
|
1924
|
-
{ name: "
|
|
1938
|
+
{ name: "toolcairn", version: "0.1.0" },
|
|
1925
1939
|
{ instructions: SETUP_INSTRUCTIONS }
|
|
1926
1940
|
);
|
|
1927
1941
|
server.registerTool(
|
|
1928
1942
|
"classify_prompt",
|
|
1929
1943
|
{
|
|
1930
|
-
description: "Classify a developer prompt to determine if
|
|
1944
|
+
description: "Classify a developer prompt to determine if ToolCairn tool search is needed. Returns a structured classification prompt for the agent to evaluate.",
|
|
1931
1945
|
inputSchema: classifyPromptSchema
|
|
1932
1946
|
},
|
|
1933
1947
|
withEventLogging("classify_prompt", async (args) => handleClassifyPrompt(args))
|
|
1934
1948
|
);
|
|
1935
1949
|
server.registerTool(
|
|
1936
|
-
"
|
|
1950
|
+
"toolcairn_init",
|
|
1937
1951
|
{
|
|
1938
|
-
description: "Set up
|
|
1952
|
+
description: "Set up ToolCairn integration for the current project. Generates agent instruction content, MCP config entry, and project config initializer.",
|
|
1939
1953
|
inputSchema: toolpilotInitSchema
|
|
1940
1954
|
},
|
|
1941
|
-
withEventLogging("
|
|
1955
|
+
withEventLogging("toolcairn_init", async (args) => handleToolpilotInit(args))
|
|
1942
1956
|
);
|
|
1943
1957
|
server.registerTool(
|
|
1944
1958
|
"init_project_config",
|
|
1945
1959
|
{
|
|
1946
|
-
description: "Initialize a .
|
|
1960
|
+
description: "Initialize a .toolcairn/config.json file for the current project. Returns the config JSON for the agent to write to disk.",
|
|
1947
1961
|
inputSchema: initProjectConfigSchema
|
|
1948
1962
|
},
|
|
1949
1963
|
withEventLogging("init_project_config", async (args) => handleInitProjectConfig(args))
|
|
@@ -1951,7 +1965,7 @@ async function buildProdServer() {
|
|
|
1951
1965
|
server.registerTool(
|
|
1952
1966
|
"read_project_config",
|
|
1953
1967
|
{
|
|
1954
|
-
description: "Parse and validate a .
|
|
1968
|
+
description: "Parse and validate a .toolcairn/config.json file. Returns confirmed tools, pending evaluations, stale tools, and agent instructions.",
|
|
1955
1969
|
inputSchema: readProjectConfigSchema
|
|
1956
1970
|
},
|
|
1957
1971
|
withEventLogging("read_project_config", async (args) => handleReadProjectConfig(args))
|
|
@@ -1959,7 +1973,7 @@ async function buildProdServer() {
|
|
|
1959
1973
|
server.registerTool(
|
|
1960
1974
|
"update_project_config",
|
|
1961
1975
|
{
|
|
1962
|
-
description: "Apply a mutation to .
|
|
1976
|
+
description: "Apply a mutation to .toolcairn/config.json and return the updated content. Actions: add_tool, remove_tool, update_tool, add_evaluation.",
|
|
1963
1977
|
inputSchema: updateProjectConfigSchema
|
|
1964
1978
|
},
|
|
1965
1979
|
withEventLogging("update_project_config", async (args) => handleUpdateProjectConfig(args))
|
|
@@ -2023,7 +2037,7 @@ async function buildProdServer() {
|
|
|
2023
2037
|
server.registerTool(
|
|
2024
2038
|
"verify_suggestion",
|
|
2025
2039
|
{
|
|
2026
|
-
description: "Validate agent-suggested tools against the
|
|
2040
|
+
description: "Validate agent-suggested tools against the ToolCairn graph.",
|
|
2027
2041
|
inputSchema: verifySuggestionSchema
|
|
2028
2042
|
},
|
|
2029
2043
|
withEventLogging("verify_suggestion", async (args) => remote.verifySuggestion(args))
|
|
@@ -2031,7 +2045,7 @@ async function buildProdServer() {
|
|
|
2031
2045
|
server.registerTool(
|
|
2032
2046
|
"report_outcome",
|
|
2033
2047
|
{
|
|
2034
|
-
description: "Report the outcome of using a tool recommended by
|
|
2048
|
+
description: "Report the outcome of using a tool recommended by ToolCairn (fire-and-forget).",
|
|
2035
2049
|
inputSchema: reportOutcomeSchema
|
|
2036
2050
|
},
|
|
2037
2051
|
withEventLogging("report_outcome", async (args) => remote.reportOutcome(args))
|
|
@@ -2039,11 +2053,78 @@ async function buildProdServer() {
|
|
|
2039
2053
|
server.registerTool(
|
|
2040
2054
|
"suggest_graph_update",
|
|
2041
2055
|
{
|
|
2042
|
-
description: "Suggest a new tool, relationship, use case, or health update to the
|
|
2056
|
+
description: "Suggest a new tool, relationship, use case, or health update to the ToolCairn graph.",
|
|
2043
2057
|
inputSchema: suggestGraphUpdateSchema
|
|
2044
2058
|
},
|
|
2045
2059
|
withEventLogging("suggest_graph_update", async (args) => remote.suggestGraphUpdate(args))
|
|
2046
2060
|
);
|
|
2061
|
+
server.registerTool(
|
|
2062
|
+
"toolcairn_auth",
|
|
2063
|
+
{
|
|
2064
|
+
description: 'Manage your ToolCairn authentication. Use "login" to authenticate via browser (unlocks higher rate limits), "status" to check current auth state, or "logout" to revert to anonymous mode.',
|
|
2065
|
+
inputSchema: z.object({
|
|
2066
|
+
action: z.enum(["login", "status", "logout"]).describe(
|
|
2067
|
+
'"login" opens a browser to authenticate, "status" shows current auth state, "logout" clears authentication'
|
|
2068
|
+
)
|
|
2069
|
+
})
|
|
2070
|
+
},
|
|
2071
|
+
async ({ action }) => {
|
|
2072
|
+
if (action === "status") {
|
|
2073
|
+
const c = await loadOrCreateCredentials();
|
|
2074
|
+
const isAuth = !!c.access_token;
|
|
2075
|
+
return {
|
|
2076
|
+
content: [
|
|
2077
|
+
{
|
|
2078
|
+
type: "text",
|
|
2079
|
+
text: JSON.stringify({
|
|
2080
|
+
authenticated: isAuth,
|
|
2081
|
+
user_email: c.user_email ?? null,
|
|
2082
|
+
user_name: c.user_name ?? null,
|
|
2083
|
+
authenticated_at: c.authenticated_at ?? null,
|
|
2084
|
+
tier: isAuth ? "authenticated" : "anonymous (free, 60 req/min)"
|
|
2085
|
+
})
|
|
2086
|
+
}
|
|
2087
|
+
]
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
if (action === "logout") {
|
|
2091
|
+
await clearAuthentication();
|
|
2092
|
+
return {
|
|
2093
|
+
content: [
|
|
2094
|
+
{
|
|
2095
|
+
type: "text",
|
|
2096
|
+
text: JSON.stringify({
|
|
2097
|
+
ok: true,
|
|
2098
|
+
message: "Logged out. Reverted to anonymous mode."
|
|
2099
|
+
})
|
|
2100
|
+
}
|
|
2101
|
+
]
|
|
2102
|
+
};
|
|
2103
|
+
}
|
|
2104
|
+
try {
|
|
2105
|
+
const user = await startDeviceAuth(import_config.config.TOOLPILOT_API_URL);
|
|
2106
|
+
return {
|
|
2107
|
+
content: [
|
|
2108
|
+
{
|
|
2109
|
+
type: "text",
|
|
2110
|
+
text: JSON.stringify({
|
|
2111
|
+
ok: true,
|
|
2112
|
+
message: `Successfully authenticated as ${user.email}. All tools are now authorized.`,
|
|
2113
|
+
user_email: user.email,
|
|
2114
|
+
user_name: user.name
|
|
2115
|
+
})
|
|
2116
|
+
}
|
|
2117
|
+
]
|
|
2118
|
+
};
|
|
2119
|
+
} catch (err) {
|
|
2120
|
+
const msg = err instanceof Error ? err.message : "Authentication failed";
|
|
2121
|
+
return {
|
|
2122
|
+
content: [{ type: "text", text: JSON.stringify({ ok: false, error: msg }) }],
|
|
2123
|
+
isError: true
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
);
|
|
2047
2128
|
return server;
|
|
2048
2129
|
}
|
|
2049
2130
|
|
|
@@ -2063,17 +2144,17 @@ function createTransport() {
|
|
|
2063
2144
|
|
|
2064
2145
|
// src/index.prod.ts
|
|
2065
2146
|
process.env.TOOLPILOT_MODE = "production";
|
|
2066
|
-
var logger9 = pino9({ name: "@
|
|
2147
|
+
var logger9 = pino9({ name: "@toolcairn/mcp-server" });
|
|
2067
2148
|
async function main() {
|
|
2068
|
-
logger9.info("Starting
|
|
2149
|
+
logger9.info("Starting ToolCairn MCP Server (production mode)");
|
|
2069
2150
|
await ensureProjectSetup();
|
|
2070
2151
|
const server = await buildProdServer();
|
|
2071
2152
|
const transport = createTransport();
|
|
2072
2153
|
await server.connect(transport);
|
|
2073
|
-
logger9.info("
|
|
2154
|
+
logger9.info("ToolCairn MCP Server started");
|
|
2074
2155
|
}
|
|
2075
2156
|
main().catch((error) => {
|
|
2076
|
-
pino9({ name: "@
|
|
2157
|
+
pino9({ name: "@toolcairn/mcp-server" }).error({ err: error }, "Failed to start MCP server");
|
|
2077
2158
|
process.exit(1);
|
|
2078
2159
|
});
|
|
2079
2160
|
//# sourceMappingURL=index.js.map
|