@neurynae/toolcairn-mcp 0.7.0 → 0.8.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 +179 -126
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -184,6 +184,31 @@ import { homedir } from "os";
|
|
|
184
184
|
import { join } from "path";
|
|
185
185
|
var CREDENTIALS_DIR = join(homedir(), ".toolcairn");
|
|
186
186
|
var CREDENTIALS_FILE = join(CREDENTIALS_DIR, "credentials.json");
|
|
187
|
+
var PENDING_AUTH_FILE = join(CREDENTIALS_DIR, "pending-auth.json");
|
|
188
|
+
async function savePendingAuth(data) {
|
|
189
|
+
await mkdir(CREDENTIALS_DIR, { recursive: true });
|
|
190
|
+
await writeFile(PENDING_AUTH_FILE, JSON.stringify(data, null, 2), "utf-8");
|
|
191
|
+
}
|
|
192
|
+
async function loadPendingAuth() {
|
|
193
|
+
try {
|
|
194
|
+
const raw = await readFile(PENDING_AUTH_FILE, "utf-8");
|
|
195
|
+
const data = JSON.parse(raw);
|
|
196
|
+
if (new Date(data.expires_at) < /* @__PURE__ */ new Date()) {
|
|
197
|
+
await clearPendingAuth();
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
return data;
|
|
201
|
+
} catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async function clearPendingAuth() {
|
|
206
|
+
try {
|
|
207
|
+
const { unlink } = await import("fs/promises");
|
|
208
|
+
await unlink(PENDING_AUTH_FILE);
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
187
212
|
function isTokenValid(creds) {
|
|
188
213
|
if (!creds.access_token)
|
|
189
214
|
return false;
|
|
@@ -261,13 +286,7 @@ async function openBrowser(url) {
|
|
|
261
286
|
cmd = "xdg-open";
|
|
262
287
|
args = [url];
|
|
263
288
|
}
|
|
264
|
-
const child = spawn(cmd, args, {
|
|
265
|
-
detached: true,
|
|
266
|
-
// detach from parent process group
|
|
267
|
-
stdio: "ignore",
|
|
268
|
-
// don't inherit parent's stdio
|
|
269
|
-
shell: false
|
|
270
|
-
});
|
|
289
|
+
const child = spawn(cmd, args, { detached: true, stdio: "ignore", shell: false });
|
|
271
290
|
child.unref();
|
|
272
291
|
} catch {
|
|
273
292
|
}
|
|
@@ -276,21 +295,48 @@ async function requestDeviceCode(apiUrl) {
|
|
|
276
295
|
const res = await fetch(`${apiUrl}/v1/auth/device-code`, { method: "POST" });
|
|
277
296
|
if (!res.ok)
|
|
278
297
|
throw new Error("Failed to start device auth. Check your internet connection.");
|
|
279
|
-
|
|
298
|
+
const data = await res.json();
|
|
299
|
+
await savePendingAuth({
|
|
300
|
+
device_code: data.device_code,
|
|
301
|
+
user_code: data.user_code,
|
|
302
|
+
verification_uri: data.verification_uri,
|
|
303
|
+
expires_at: new Date(Date.now() + data.expires_in * 1e3).toISOString(),
|
|
304
|
+
api_url: apiUrl
|
|
305
|
+
});
|
|
306
|
+
return data;
|
|
280
307
|
}
|
|
281
308
|
async function startDeviceAuth(apiUrl) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
309
|
+
const pending = await loadPendingAuth();
|
|
310
|
+
let codeData;
|
|
311
|
+
if (pending && pending.api_url === apiUrl) {
|
|
312
|
+
codeData = {
|
|
313
|
+
device_code: pending.device_code,
|
|
314
|
+
user_code: pending.user_code,
|
|
315
|
+
verification_uri: pending.verification_uri,
|
|
316
|
+
expires_in: Math.floor((new Date(pending.expires_at).getTime() - Date.now()) / 1e3),
|
|
317
|
+
interval: 5
|
|
318
|
+
};
|
|
319
|
+
process.stderr.write("\n ToolCairn: Waiting for sign-in confirmation...\n");
|
|
320
|
+
process.stderr.write(` URL: ${codeData.verification_uri}
|
|
321
|
+
`);
|
|
322
|
+
process.stderr.write(` Code: ${codeData.user_code}
|
|
323
|
+
|
|
324
|
+
`);
|
|
325
|
+
} else {
|
|
326
|
+
codeData = await requestDeviceCode(apiUrl);
|
|
327
|
+
process.stderr.write("\n\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\n");
|
|
328
|
+
process.stderr.write(" ToolCairn \u2014 Sign In Required\n");
|
|
329
|
+
process.stderr.write("\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\n");
|
|
330
|
+
process.stderr.write("\n Opening browser for authentication...\n\n");
|
|
331
|
+
process.stderr.write(` URL: ${codeData.verification_uri}
|
|
288
332
|
`);
|
|
289
|
-
|
|
333
|
+
process.stderr.write(` Code: ${codeData.user_code}
|
|
290
334
|
`);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
335
|
+
process.stderr.write("\n Waiting... (browser should open automatically)\n\n");
|
|
336
|
+
await openBrowser(codeData.verification_uri);
|
|
337
|
+
}
|
|
338
|
+
const result = await pollForToken(apiUrl, codeData.device_code, 5);
|
|
339
|
+
await clearPendingAuth();
|
|
294
340
|
await upgradeToAuthenticated(result.access_token, result.api_key, result.user);
|
|
295
341
|
process.stderr.write(`
|
|
296
342
|
\u2713 Signed in as ${result.user.email}
|
|
@@ -314,8 +360,10 @@ async function pollForToken(apiUrl, deviceCode, intervalSec) {
|
|
|
314
360
|
const data = await res.json();
|
|
315
361
|
if (data.error === "authorization_pending")
|
|
316
362
|
continue;
|
|
317
|
-
if (data.error === "expired_token")
|
|
363
|
+
if (data.error === "expired_token") {
|
|
364
|
+
await clearPendingAuth();
|
|
318
365
|
throw new Error("Device code expired. Please try again.");
|
|
366
|
+
}
|
|
319
367
|
if (data.error)
|
|
320
368
|
throw new Error(`Authorization failed: ${data.error}`);
|
|
321
369
|
if (data.access_token)
|
|
@@ -810,62 +858,61 @@ async function createIfAbsent(filePath, content, label) {
|
|
|
810
858
|
// src/server.prod.ts
|
|
811
859
|
init_esm_shims();
|
|
812
860
|
var import_config = __toESM(require_dist(), 1);
|
|
813
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
814
861
|
|
|
815
862
|
// ../../packages/tools/dist/local.js
|
|
816
863
|
init_esm_shims();
|
|
817
864
|
|
|
818
865
|
// ../../packages/tools/dist/schemas.js
|
|
819
866
|
init_esm_shims();
|
|
820
|
-
import { z
|
|
867
|
+
import { z } from "zod";
|
|
821
868
|
var searchToolsSchema = {
|
|
822
|
-
query:
|
|
823
|
-
context:
|
|
824
|
-
query_id:
|
|
825
|
-
user_id:
|
|
869
|
+
query: z.string().min(1).max(500),
|
|
870
|
+
context: z.object({ filters: z.record(z.string(), z.unknown()) }).optional(),
|
|
871
|
+
query_id: z.string().uuid().optional(),
|
|
872
|
+
user_id: z.string().optional()
|
|
826
873
|
};
|
|
827
874
|
var searchToolsRespondSchema = {
|
|
828
|
-
query_id:
|
|
829
|
-
answers:
|
|
875
|
+
query_id: z.string().uuid(),
|
|
876
|
+
answers: z.array(z.object({ dimension: z.string(), value: z.string() }))
|
|
830
877
|
};
|
|
831
878
|
var reportOutcomeSchema = {
|
|
832
|
-
query_id:
|
|
833
|
-
chosen_tool:
|
|
834
|
-
reason:
|
|
835
|
-
outcome:
|
|
836
|
-
feedback:
|
|
837
|
-
replaced_by:
|
|
879
|
+
query_id: z.string().uuid(),
|
|
880
|
+
chosen_tool: z.string(),
|
|
881
|
+
reason: z.string().optional(),
|
|
882
|
+
outcome: z.enum(["success", "failure", "replaced", "pending"]),
|
|
883
|
+
feedback: z.string().optional(),
|
|
884
|
+
replaced_by: z.string().optional()
|
|
838
885
|
};
|
|
839
886
|
var getStackSchema = {
|
|
840
|
-
use_case:
|
|
841
|
-
constraints:
|
|
842
|
-
deployment_model:
|
|
843
|
-
language:
|
|
844
|
-
license:
|
|
887
|
+
use_case: z.string().min(1),
|
|
888
|
+
constraints: z.object({
|
|
889
|
+
deployment_model: z.enum(["self-hosted", "cloud", "embedded", "serverless"]).optional(),
|
|
890
|
+
language: z.string().optional(),
|
|
891
|
+
license: z.string().optional()
|
|
845
892
|
}).optional(),
|
|
846
|
-
limit:
|
|
893
|
+
limit: z.number().int().positive().max(10).default(5)
|
|
847
894
|
};
|
|
848
895
|
var checkIssueSchema = {
|
|
849
|
-
tool_name:
|
|
850
|
-
issue_title:
|
|
851
|
-
retry_count:
|
|
852
|
-
docs_consulted:
|
|
853
|
-
issue_url:
|
|
896
|
+
tool_name: z.string(),
|
|
897
|
+
issue_title: z.string(),
|
|
898
|
+
retry_count: z.number().int().min(0).default(0),
|
|
899
|
+
docs_consulted: z.boolean().default(false),
|
|
900
|
+
issue_url: z.string().url().optional()
|
|
854
901
|
};
|
|
855
902
|
var checkCompatibilitySchema = {
|
|
856
|
-
tool_a:
|
|
857
|
-
tool_b:
|
|
903
|
+
tool_a: z.string(),
|
|
904
|
+
tool_b: z.string()
|
|
858
905
|
};
|
|
859
906
|
var suggestGraphUpdateSchema = {
|
|
860
|
-
suggestion_type:
|
|
861
|
-
data:
|
|
862
|
-
tool_name:
|
|
863
|
-
github_url:
|
|
864
|
-
description:
|
|
865
|
-
relationship:
|
|
866
|
-
source_tool:
|
|
867
|
-
target_tool:
|
|
868
|
-
edge_type:
|
|
907
|
+
suggestion_type: z.enum(["new_tool", "new_edge", "update_health", "new_use_case"]),
|
|
908
|
+
data: z.object({
|
|
909
|
+
tool_name: z.string().optional(),
|
|
910
|
+
github_url: z.string().url().optional(),
|
|
911
|
+
description: z.string().optional(),
|
|
912
|
+
relationship: z.object({
|
|
913
|
+
source_tool: z.string(),
|
|
914
|
+
target_tool: z.string(),
|
|
915
|
+
edge_type: z.enum([
|
|
869
916
|
"SOLVES",
|
|
870
917
|
"REQUIRES",
|
|
871
918
|
"INTEGRATES_WITH",
|
|
@@ -875,68 +922,68 @@ var suggestGraphUpdateSchema = {
|
|
|
875
922
|
"BREAKS_FROM",
|
|
876
923
|
"COMPATIBLE_WITH"
|
|
877
924
|
]),
|
|
878
|
-
evidence:
|
|
925
|
+
evidence: z.string().optional()
|
|
879
926
|
}).optional(),
|
|
880
|
-
use_case:
|
|
881
|
-
name:
|
|
882
|
-
description:
|
|
883
|
-
tools:
|
|
927
|
+
use_case: z.object({
|
|
928
|
+
name: z.string(),
|
|
929
|
+
description: z.string(),
|
|
930
|
+
tools: z.array(z.string()).optional()
|
|
884
931
|
}).optional()
|
|
885
932
|
}),
|
|
886
|
-
query_id:
|
|
887
|
-
confidence:
|
|
933
|
+
query_id: z.string().uuid().optional(),
|
|
934
|
+
confidence: z.number().min(0).max(1).default(0.5)
|
|
888
935
|
};
|
|
889
936
|
var compareToolsSchema = {
|
|
890
|
-
tool_a:
|
|
891
|
-
tool_b:
|
|
892
|
-
use_case:
|
|
893
|
-
project_config:
|
|
937
|
+
tool_a: z.string().min(1),
|
|
938
|
+
tool_b: z.string().min(1),
|
|
939
|
+
use_case: z.string().optional(),
|
|
940
|
+
project_config: z.string().max(1e5).optional()
|
|
894
941
|
};
|
|
895
942
|
var toolpilotInitSchema = {
|
|
896
|
-
agent:
|
|
897
|
-
project_root:
|
|
898
|
-
server_path:
|
|
899
|
-
detected_files:
|
|
943
|
+
agent: z.enum(["claude", "cursor", "windsurf", "copilot", "copilot-cli", "opencode", "generic"]),
|
|
944
|
+
project_root: z.string().min(1),
|
|
945
|
+
server_path: z.string().optional(),
|
|
946
|
+
detected_files: z.array(z.string()).optional()
|
|
900
947
|
};
|
|
901
948
|
var initProjectConfigSchema = {
|
|
902
|
-
project_name:
|
|
903
|
-
language:
|
|
904
|
-
framework:
|
|
905
|
-
detected_tools:
|
|
906
|
-
name:
|
|
907
|
-
source:
|
|
908
|
-
version:
|
|
949
|
+
project_name: z.string().min(1).max(200),
|
|
950
|
+
language: z.string().min(1).max(50),
|
|
951
|
+
framework: z.string().optional(),
|
|
952
|
+
detected_tools: z.array(z.object({
|
|
953
|
+
name: z.string(),
|
|
954
|
+
source: z.enum(["toolpilot", "manual", "non_oss"]),
|
|
955
|
+
version: z.string().optional()
|
|
909
956
|
})).optional()
|
|
910
957
|
};
|
|
911
958
|
var readProjectConfigSchema = {
|
|
912
|
-
config_content:
|
|
959
|
+
config_content: z.string().min(1).max(1e5)
|
|
913
960
|
};
|
|
914
961
|
var updateProjectConfigSchema = {
|
|
915
|
-
current_config:
|
|
916
|
-
action:
|
|
917
|
-
tool_name:
|
|
918
|
-
data:
|
|
962
|
+
current_config: z.string().min(1).max(1e5),
|
|
963
|
+
action: z.enum(["add_tool", "remove_tool", "update_tool", "add_evaluation"]),
|
|
964
|
+
tool_name: z.string().min(1),
|
|
965
|
+
data: z.record(z.string(), z.unknown()).optional()
|
|
919
966
|
};
|
|
920
967
|
var classifyPromptSchema = {
|
|
921
|
-
prompt:
|
|
922
|
-
project_tools:
|
|
968
|
+
prompt: z.string().min(1).max(2e3),
|
|
969
|
+
project_tools: z.array(z.string()).optional()
|
|
923
970
|
};
|
|
924
971
|
var verifySuggestionSchema = {
|
|
925
|
-
query:
|
|
926
|
-
agent_suggestions:
|
|
972
|
+
query: z.string().min(1).max(500),
|
|
973
|
+
agent_suggestions: z.array(z.string().min(1)).min(1).max(10)
|
|
927
974
|
};
|
|
928
975
|
var refineRequirementSchema = {
|
|
929
|
-
prompt:
|
|
930
|
-
classification:
|
|
976
|
+
prompt: z.string().min(1).max(2e3),
|
|
977
|
+
classification: z.enum([
|
|
931
978
|
"tool_discovery",
|
|
932
979
|
"stack_building",
|
|
933
980
|
"tool_comparison",
|
|
934
981
|
"tool_configuration"
|
|
935
982
|
]),
|
|
936
|
-
project_context:
|
|
937
|
-
existing_tools:
|
|
938
|
-
language:
|
|
939
|
-
framework:
|
|
983
|
+
project_context: z.object({
|
|
984
|
+
existing_tools: z.array(z.string()).optional(),
|
|
985
|
+
language: z.string().optional(),
|
|
986
|
+
framework: z.string().optional()
|
|
940
987
|
}).optional()
|
|
941
988
|
};
|
|
942
989
|
|
|
@@ -1876,6 +1923,7 @@ async function handleUpdateProjectConfig(args) {
|
|
|
1876
1923
|
|
|
1877
1924
|
// src/server.prod.ts
|
|
1878
1925
|
import pino8 from "pino";
|
|
1926
|
+
import { z as z2 } from "zod";
|
|
1879
1927
|
|
|
1880
1928
|
// src/middleware/event-logger.ts
|
|
1881
1929
|
init_esm_shims();
|
|
@@ -2041,27 +2089,17 @@ The server wrote the file at startup. You still need to fill in the project deta
|
|
|
2041
2089
|
| A tool worked well or was replaced | \`report_outcome\` |
|
|
2042
2090
|
| Tool added/removed from project | \`update_project_config\` |
|
|
2043
2091
|
`.trim();
|
|
2044
|
-
async function
|
|
2092
|
+
async function addToolsToServer(server) {
|
|
2045
2093
|
const creds = await loadCredentials();
|
|
2046
2094
|
if (!creds || !isTokenValid(creds)) {
|
|
2047
|
-
throw new Error("ToolCairn: authentication required.
|
|
2095
|
+
throw new Error("ToolCairn: authentication required.");
|
|
2048
2096
|
}
|
|
2049
2097
|
const remote = new ToolCairnClient({
|
|
2050
2098
|
baseUrl: import_config.config.TOOLPILOT_API_URL,
|
|
2051
2099
|
apiKey: creds.client_id,
|
|
2052
2100
|
accessToken: creds.access_token
|
|
2053
2101
|
});
|
|
2054
|
-
logger8.info(
|
|
2055
|
-
{
|
|
2056
|
-
apiUrl: import_config.config.TOOLPILOT_API_URL,
|
|
2057
|
-
user: creds.user_email
|
|
2058
|
-
},
|
|
2059
|
-
"Production MCP mode: authenticated"
|
|
2060
|
-
);
|
|
2061
|
-
const server = new McpServer(
|
|
2062
|
-
{ name: "toolcairn", version: "0.1.0" },
|
|
2063
|
-
{ instructions: SETUP_INSTRUCTIONS }
|
|
2064
|
-
);
|
|
2102
|
+
logger8.info({ user: creds.user_email }, "Registering production tools");
|
|
2065
2103
|
server.registerTool(
|
|
2066
2104
|
"classify_prompt",
|
|
2067
2105
|
{
|
|
@@ -2186,8 +2224,8 @@ async function buildProdServer() {
|
|
|
2186
2224
|
"toolcairn_auth",
|
|
2187
2225
|
{
|
|
2188
2226
|
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.',
|
|
2189
|
-
inputSchema:
|
|
2190
|
-
action:
|
|
2227
|
+
inputSchema: z2.object({
|
|
2228
|
+
action: z2.enum(["login", "status", "logout"]).describe(
|
|
2191
2229
|
'"login" opens a browser to authenticate, "status" shows current auth state, "logout" clears authentication'
|
|
2192
2230
|
)
|
|
2193
2231
|
})
|
|
@@ -2248,6 +2286,13 @@ async function buildProdServer() {
|
|
|
2248
2286
|
}
|
|
2249
2287
|
}
|
|
2250
2288
|
);
|
|
2289
|
+
}
|
|
2290
|
+
async function buildProdServer() {
|
|
2291
|
+
const server = new McpServer(
|
|
2292
|
+
{ name: "toolcairn", version: "0.1.0" },
|
|
2293
|
+
{ instructions: SETUP_INSTRUCTIONS }
|
|
2294
|
+
);
|
|
2295
|
+
await addToolsToServer(server);
|
|
2251
2296
|
return server;
|
|
2252
2297
|
}
|
|
2253
2298
|
|
|
@@ -2280,32 +2325,29 @@ async function main() {
|
|
|
2280
2325
|
let verificationUri = "https://toolcairn.neurynae.com/signup";
|
|
2281
2326
|
let userCode = "";
|
|
2282
2327
|
try {
|
|
2283
|
-
const
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
logger9.info(
|
|
2288
|
-
}
|
|
2289
|
-
|
|
2290
|
-
|
|
2328
|
+
const pending = await loadPendingAuth();
|
|
2329
|
+
if (pending) {
|
|
2330
|
+
verificationUri = pending.verification_uri;
|
|
2331
|
+
userCode = pending.user_code;
|
|
2332
|
+
logger9.info({ userCode }, "Resuming pending sign-in");
|
|
2333
|
+
} else {
|
|
2334
|
+
const codeData = await requestDeviceCode(import_config3.config.TOOLPILOT_API_URL);
|
|
2335
|
+
verificationUri = codeData.verification_uri;
|
|
2336
|
+
userCode = codeData.user_code;
|
|
2337
|
+
logger9.info({ userCode }, "New sign-in started");
|
|
2338
|
+
}
|
|
2291
2339
|
} catch (err) {
|
|
2292
2340
|
logger9.error({ err }, "Could not reach ToolCairn API \u2014 check your connection");
|
|
2293
2341
|
}
|
|
2294
|
-
|
|
2295
|
-
{ name: "toolcairn", version: "0.1.0" },
|
|
2296
|
-
{
|
|
2297
|
-
instructions: userCode ? `# ToolCairn \u2014 Sign In Required
|
|
2342
|
+
const instructions = userCode ? `# ToolCairn \u2014 Sign In Required
|
|
2298
2343
|
|
|
2299
2344
|
A browser window should have opened automatically.
|
|
2300
2345
|
|
|
2301
2346
|
**Sign-in URL:** ${verificationUri}
|
|
2302
2347
|
**Code to confirm:** \`${userCode}\`
|
|
2303
2348
|
|
|
2304
|
-
Open the URL, sign in, and confirm the code shown
|
|
2305
|
-
|
|
2306
|
-
Visit ${verificationUri} to create an account, then restart your agent.`
|
|
2307
|
-
}
|
|
2308
|
-
);
|
|
2349
|
+
Open the URL, sign in, and confirm the code shown. All 14 tools will appear automatically \u2014 no restart needed.` : "# ToolCairn \u2014 Sign In Required\n\nVisit https://toolcairn.neurynae.com to create an account, then reconnect.";
|
|
2350
|
+
server = new McpServer2({ name: "toolcairn", version: "0.1.0" }, { instructions });
|
|
2309
2351
|
server.registerTool(
|
|
2310
2352
|
"toolcairn_auth",
|
|
2311
2353
|
{
|
|
@@ -2320,16 +2362,27 @@ Visit ${verificationUri} to create an account, then restart your agent.`
|
|
|
2320
2362
|
authenticated: false,
|
|
2321
2363
|
sign_in_url: verificationUri,
|
|
2322
2364
|
code: userCode || null,
|
|
2323
|
-
message: userCode ? `Open ${verificationUri}
|
|
2365
|
+
message: userCode ? `Open ${verificationUri} and confirm code "${userCode}". Tools will appear automatically when confirmed.` : "Visit toolcairn.neurynae.com to sign up."
|
|
2324
2366
|
})
|
|
2325
2367
|
}
|
|
2326
2368
|
]
|
|
2327
2369
|
})
|
|
2328
2370
|
);
|
|
2371
|
+
startDeviceAuth(import_config3.config.TOOLPILOT_API_URL).then(async () => {
|
|
2372
|
+
logger9.info("Sign-in complete \u2014 adding all tools to running server");
|
|
2373
|
+
try {
|
|
2374
|
+
await addToolsToServer(server);
|
|
2375
|
+
logger9.info("All ToolCairn tools now available");
|
|
2376
|
+
} catch (err) {
|
|
2377
|
+
logger9.error({ err }, "Failed to add tools after sign-in \u2014 please reconnect");
|
|
2378
|
+
}
|
|
2379
|
+
}).catch((err) => {
|
|
2380
|
+
logger9.error({ err }, "Sign-in failed \u2014 please try again");
|
|
2381
|
+
});
|
|
2329
2382
|
}
|
|
2330
2383
|
const transport = createTransport();
|
|
2331
2384
|
await server.connect(transport);
|
|
2332
|
-
logger9.info(authenticated ? "ToolCairn MCP ready" : "ToolCairn MCP ready (sign-in
|
|
2385
|
+
logger9.info(authenticated ? "ToolCairn MCP ready" : "ToolCairn MCP ready (awaiting sign-in)");
|
|
2333
2386
|
}
|
|
2334
2387
|
main().catch((error) => {
|
|
2335
2388
|
pino9({ name: "@toolcairn/mcp-server" }).error({ err: error }, "Failed to start MCP server");
|