@neurynae/toolcairn-mcp 0.2.0 → 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/dist/index.js CHANGED
@@ -556,9 +556,11 @@ 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 ──────────────────────────────────────────────────────────
@@ -639,13 +641,17 @@ var ToolCairnClient = 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-ToolCairn-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: z.string().min(1).max(500),
692
- context: z.object({ filters: z.record(z.string(), z.unknown()) }).optional(),
693
- query_id: z.string().uuid().optional(),
694
- user_id: z.string().optional()
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: z.string().uuid(),
698
- answers: z.array(z.object({ dimension: z.string(), value: z.string() }))
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: z.string().uuid(),
702
- chosen_tool: z.string(),
703
- reason: z.string().optional(),
704
- outcome: z.enum(["success", "failure", "replaced", "pending"]),
705
- feedback: z.string().optional(),
706
- replaced_by: z.string().optional()
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: z.string().min(1),
710
- constraints: z.object({
711
- deployment_model: z.enum(["self-hosted", "cloud", "embedded", "serverless"]).optional(),
712
- language: z.string().optional(),
713
- license: z.string().optional()
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: z.number().int().positive().max(10).default(5)
724
+ limit: z2.number().int().positive().max(10).default(5)
716
725
  };
717
726
  var checkIssueSchema = {
718
- tool_name: z.string(),
719
- issue_title: z.string(),
720
- retry_count: z.number().int().min(0).default(0),
721
- docs_consulted: z.boolean().default(false),
722
- issue_url: z.string().url().optional()
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: z.string(),
726
- tool_b: z.string()
734
+ tool_a: z2.string(),
735
+ tool_b: z2.string()
727
736
  };
728
737
  var suggestGraphUpdateSchema = {
729
- suggestion_type: z.enum(["new_tool", "new_edge", "update_health", "new_use_case"]),
730
- data: z.object({
731
- tool_name: z.string().optional(),
732
- github_url: z.string().url().optional(),
733
- description: z.string().optional(),
734
- relationship: z.object({
735
- source_tool: z.string(),
736
- target_tool: z.string(),
737
- edge_type: z.enum([
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: z.string().optional()
756
+ evidence: z2.string().optional()
748
757
  }).optional(),
749
- use_case: z.object({
750
- name: z.string(),
751
- description: z.string(),
752
- tools: z.array(z.string()).optional()
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: z.string().uuid().optional(),
756
- confidence: z.number().min(0).max(1).default(0.5)
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: z.string().min(1),
760
- tool_b: z.string().min(1),
761
- use_case: z.string().optional(),
762
- project_config: z.string().max(1e5).optional()
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: z.enum(["claude", "cursor", "windsurf", "copilot", "copilot-cli", "opencode", "generic"]),
766
- project_root: z.string().min(1),
767
- server_path: z.string().optional(),
768
- detected_files: z.array(z.string()).optional()
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: z.string().min(1).max(200),
772
- language: z.string().min(1).max(50),
773
- framework: z.string().optional(),
774
- detected_tools: z.array(z.object({
775
- name: z.string(),
776
- source: z.enum(["toolpilot", "manual", "non_oss"]),
777
- version: z.string().optional()
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: z.string().min(1).max(1e5)
790
+ config_content: z2.string().min(1).max(1e5)
782
791
  };
783
792
  var updateProjectConfigSchema = {
784
- current_config: z.string().min(1).max(1e5),
785
- action: z.enum(["add_tool", "remove_tool", "update_tool", "add_evaluation"]),
786
- tool_name: z.string().min(1),
787
- data: z.record(z.string(), z.unknown()).optional()
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: z.string().min(1).max(2e3),
791
- project_tools: z.array(z.string()).optional()
799
+ prompt: z2.string().min(1).max(2e3),
800
+ project_tools: z2.array(z2.string()).optional()
792
801
  };
793
802
  var verifySuggestionSchema = {
794
- query: z.string().min(1).max(500),
795
- agent_suggestions: z.array(z.string().min(1)).min(1).max(10)
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: z.string().min(1).max(2e3),
799
- classification: z.enum([
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: z.object({
806
- existing_tools: z.array(z.string()).optional(),
807
- language: z.string().optional(),
808
- framework: z.string().optional()
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
 
@@ -1756,7 +1765,7 @@ var _prisma = null;
1756
1765
  async function getPrisma() {
1757
1766
  if (!_prisma) {
1758
1767
  try {
1759
- const mod = await import("./dist-2HK3ZGXE.js");
1768
+ const mod = await import("./dist-LZ2PMHGT.js");
1760
1769
  _prisma = new mod.PrismaClient();
1761
1770
  } catch {
1762
1771
  }
@@ -1914,10 +1923,15 @@ async function buildProdServer() {
1914
1923
  const creds = await loadOrCreateCredentials();
1915
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
- { apiUrl: import_config.config.TOOLPILOT_API_URL, clientId: `${creds.client_id.slice(0, 8)}...` },
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(
@@ -2044,6 +2058,73 @@ async function buildProdServer() {
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