@neiracore/mcp-server 1.0.3 → 1.2.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 +105 -170
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +106 -171
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -112,12 +112,6 @@ var ServerContext = class {
|
|
|
112
112
|
getAid() {
|
|
113
113
|
return this.credentials?.aid ?? null;
|
|
114
114
|
}
|
|
115
|
-
/**
|
|
116
|
-
* Get the current login key (nk_...) or null.
|
|
117
|
-
*/
|
|
118
|
-
getLoginKey() {
|
|
119
|
-
return this.credentials?.login_key ?? null;
|
|
120
|
-
}
|
|
121
115
|
/**
|
|
122
116
|
* Hot-reload credentials after registration (no server restart needed).
|
|
123
117
|
*/
|
|
@@ -359,38 +353,11 @@ function registerSearchTool(server, ctx) {
|
|
|
359
353
|
InputSchema2,
|
|
360
354
|
async (args) => {
|
|
361
355
|
try {
|
|
362
|
-
ctx.requireAuth();
|
|
356
|
+
const client = ctx.requireAuth();
|
|
363
357
|
const aid = ctx.getAid();
|
|
364
|
-
const loginKey = ctx.getLoginKey();
|
|
365
358
|
ctx.log("debug", `Searching: "${truncate(args.query, 50)}" limit=${args.limit}`);
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
looking_for: args.query
|
|
369
|
-
};
|
|
370
|
-
if (args.limit !== void 0) body.limit = args.limit;
|
|
371
|
-
const headers = {
|
|
372
|
-
"Content-Type": "application/json"
|
|
373
|
-
};
|
|
374
|
-
if (loginKey) {
|
|
375
|
-
headers["Authorization"] = `Bearer ${loginKey}`;
|
|
376
|
-
}
|
|
377
|
-
const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/search`, {
|
|
378
|
-
method: "POST",
|
|
379
|
-
headers,
|
|
380
|
-
body: JSON.stringify(body)
|
|
381
|
-
});
|
|
382
|
-
if (!res.ok) {
|
|
383
|
-
const text = await res.text();
|
|
384
|
-
let msg = `Search failed (HTTP ${res.status})`;
|
|
385
|
-
try {
|
|
386
|
-
const err = JSON.parse(text);
|
|
387
|
-
if (err.message) msg = err.message;
|
|
388
|
-
} catch {
|
|
389
|
-
}
|
|
390
|
-
return textResult(`\u274C ${msg}`);
|
|
391
|
-
}
|
|
392
|
-
const result = await res.json();
|
|
393
|
-
if (!result.matches || result.matches.length === 0) {
|
|
359
|
+
const result = await client.search(args.query, args.limit, aid);
|
|
360
|
+
if (result.matches.length === 0) {
|
|
394
361
|
return textResult(
|
|
395
362
|
`\u{1F50D} No agents found matching "${args.query}".
|
|
396
363
|
|
|
@@ -437,24 +404,11 @@ function registerStatusTool(server, ctx) {
|
|
|
437
404
|
InputSchema3,
|
|
438
405
|
async (args) => {
|
|
439
406
|
try {
|
|
440
|
-
ctx.requireAuth();
|
|
407
|
+
const client = ctx.requireAuth();
|
|
441
408
|
const targetAid = args.aid ?? ctx.getAid();
|
|
442
409
|
const isSelf = !args.aid || args.aid === ctx.getAid();
|
|
443
410
|
ctx.log("debug", `Status check for: ${targetAid.slice(0, 8)}...`);
|
|
444
|
-
const
|
|
445
|
-
`${ctx.getBaseUrl()}/api/acsp/status?aid=${targetAid}`
|
|
446
|
-
);
|
|
447
|
-
if (!res.ok) {
|
|
448
|
-
const text = await res.text();
|
|
449
|
-
let msg = `Status check failed (HTTP ${res.status})`;
|
|
450
|
-
try {
|
|
451
|
-
const err = JSON.parse(text);
|
|
452
|
-
if (err.message) msg = err.message;
|
|
453
|
-
} catch {
|
|
454
|
-
}
|
|
455
|
-
return textResult(`\u274C ${msg}`);
|
|
456
|
-
}
|
|
457
|
-
const result = await res.json();
|
|
411
|
+
const result = await client.status(targetAid);
|
|
458
412
|
const lines = [
|
|
459
413
|
isSelf ? "\u{1F4CA} Your Agent Status\n" : `\u{1F4CA} Agent Status: ${targetAid.slice(0, 8)}...
|
|
460
414
|
`,
|
|
@@ -494,9 +448,8 @@ function registerConnectTool(server, ctx) {
|
|
|
494
448
|
InputSchema4,
|
|
495
449
|
async (args) => {
|
|
496
450
|
try {
|
|
497
|
-
ctx.requireAuth();
|
|
451
|
+
const client = ctx.requireAuth();
|
|
498
452
|
const creds = ctx.credentials;
|
|
499
|
-
const loginKey = ctx.getLoginKey();
|
|
500
453
|
ctx.log("info", `Connecting to: ${args.target_aid.slice(0, 8)}...`);
|
|
501
454
|
const enrichedMessage = [
|
|
502
455
|
`[Connection Request from ${creds.agent_name}]`,
|
|
@@ -504,41 +457,17 @@ function registerConnectTool(server, ctx) {
|
|
|
504
457
|
"",
|
|
505
458
|
args.message
|
|
506
459
|
].join("\n");
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (loginKey) {
|
|
511
|
-
headers["Authorization"] = `Bearer ${loginKey}`;
|
|
512
|
-
}
|
|
513
|
-
const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/message/send`, {
|
|
514
|
-
method: "POST",
|
|
515
|
-
headers,
|
|
516
|
-
body: JSON.stringify({
|
|
517
|
-
sender_aid: creds.aid,
|
|
518
|
-
recipient_aid: args.target_aid,
|
|
519
|
-
content: enrichedMessage
|
|
520
|
-
})
|
|
460
|
+
const result = await client.message.send({
|
|
461
|
+
to: args.target_aid,
|
|
462
|
+
content: enrichedMessage
|
|
521
463
|
});
|
|
522
|
-
|
|
523
|
-
const text = await res.text();
|
|
524
|
-
let msg = `Connect failed (HTTP ${res.status})`;
|
|
525
|
-
try {
|
|
526
|
-
const err = JSON.parse(text);
|
|
527
|
-
if (err.message) msg = err.message;
|
|
528
|
-
} catch {
|
|
529
|
-
}
|
|
530
|
-
return textResult(`\u274C ${msg}`);
|
|
531
|
-
}
|
|
532
|
-
const result = await res.json();
|
|
533
|
-
const msgId = result.message_id ?? result.id ?? "sent";
|
|
534
|
-
const ts = result.created_at ?? result.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
535
|
-
ctx.log("info", `Connection sent: ${msgId}`);
|
|
464
|
+
ctx.log("info", `Connection sent: ${result.message_id}`);
|
|
536
465
|
return textResult(
|
|
537
466
|
`\u{1F91D} Connection request sent!
|
|
538
467
|
|
|
539
468
|
To: ${args.target_aid.slice(0, 8)}...
|
|
540
469
|
Message: ${truncate(args.message, 80)}
|
|
541
|
-
|
|
470
|
+
ID: ${result.message_id}
|
|
542
471
|
|
|
543
472
|
The target agent will see your name, capabilities, and message.`
|
|
544
473
|
);
|
|
@@ -561,40 +490,15 @@ function registerSendMessageTool(server, ctx) {
|
|
|
561
490
|
InputSchema5,
|
|
562
491
|
async (args) => {
|
|
563
492
|
try {
|
|
564
|
-
ctx.requireAuth();
|
|
493
|
+
const client = ctx.requireAuth();
|
|
565
494
|
const creds = ctx.credentials;
|
|
566
|
-
const loginKey = ctx.getLoginKey();
|
|
567
495
|
ctx.log("info", `Sending ${args.message_type} to: ${args.to.slice(0, 8)}...`);
|
|
568
496
|
const content = args.message_type === "text" ? args.content : `[${args.message_type.toUpperCase()}] ${args.content}`;
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
if (loginKey) {
|
|
573
|
-
headers["Authorization"] = `Bearer ${loginKey}`;
|
|
574
|
-
}
|
|
575
|
-
const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/message/send`, {
|
|
576
|
-
method: "POST",
|
|
577
|
-
headers,
|
|
578
|
-
body: JSON.stringify({
|
|
579
|
-
sender_aid: creds.aid,
|
|
580
|
-
recipient_aid: args.to,
|
|
581
|
-
content
|
|
582
|
-
})
|
|
497
|
+
const result = await client.message.send({
|
|
498
|
+
to: args.to,
|
|
499
|
+
content
|
|
583
500
|
});
|
|
584
|
-
|
|
585
|
-
const text = await res.text();
|
|
586
|
-
let msg = `Send failed (HTTP ${res.status})`;
|
|
587
|
-
try {
|
|
588
|
-
const err = JSON.parse(text);
|
|
589
|
-
if (err.message) msg = err.message;
|
|
590
|
-
} catch {
|
|
591
|
-
}
|
|
592
|
-
return textResult(`\u274C ${msg}`);
|
|
593
|
-
}
|
|
594
|
-
const result = await res.json();
|
|
595
|
-
const msgId = result.message_id ?? result.id ?? "sent";
|
|
596
|
-
const ts = result.created_at ?? result.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
597
|
-
ctx.log("info", `Message sent: ${msgId}`);
|
|
501
|
+
ctx.log("info", `Message sent: ${result.message_id}`);
|
|
598
502
|
return textResult(
|
|
599
503
|
`\u2709\uFE0F Message sent!
|
|
600
504
|
|
|
@@ -602,8 +506,7 @@ function registerSendMessageTool(server, ctx) {
|
|
|
602
506
|
To: ${args.to.slice(0, 8)}...
|
|
603
507
|
Type: ${args.message_type}
|
|
604
508
|
Preview: ${truncate(args.content, 80)}
|
|
605
|
-
|
|
606
|
-
ID: ${msgId}`
|
|
509
|
+
ID: ${result.message_id}`
|
|
607
510
|
);
|
|
608
511
|
} catch (err) {
|
|
609
512
|
ctx.log("error", `Send message failed: ${String(err)}`);
|
|
@@ -613,34 +516,49 @@ function registerSendMessageTool(server, ctx) {
|
|
|
613
516
|
);
|
|
614
517
|
}
|
|
615
518
|
var InputSchema6 = {
|
|
616
|
-
name: zod.z.string().min(1, "Group name is required").max(
|
|
519
|
+
name: zod.z.string().min(1, "Group name is required").max(64, "Group name must be 64 characters or less"),
|
|
617
520
|
description: zod.z.string().max(1024, "Description must be 1024 characters or less").optional()
|
|
618
521
|
};
|
|
619
522
|
function registerCreateGroupTool(server, ctx) {
|
|
620
523
|
server.tool(
|
|
621
524
|
"neiracore_create_group",
|
|
622
|
-
"Create a new
|
|
525
|
+
"Create a new group on the Neiracore network. You become the first member automatically. Other agents can join via the invite code.",
|
|
623
526
|
InputSchema6,
|
|
624
527
|
async (args) => {
|
|
625
528
|
try {
|
|
626
|
-
|
|
529
|
+
ctx.requireAuth();
|
|
530
|
+
const creds = ctx.credentials;
|
|
627
531
|
ctx.log("info", `Creating group: ${args.name}`);
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
532
|
+
const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/groups`, {
|
|
533
|
+
method: "POST",
|
|
534
|
+
headers: {
|
|
535
|
+
"Content-Type": "application/json",
|
|
536
|
+
Authorization: `Bearer ${creds.login_key}`
|
|
537
|
+
},
|
|
538
|
+
body: JSON.stringify({
|
|
539
|
+
aid: creds.aid,
|
|
540
|
+
name: args.name,
|
|
541
|
+
description: args.description ?? void 0
|
|
542
|
+
})
|
|
631
543
|
});
|
|
632
|
-
|
|
544
|
+
if (!res.ok) {
|
|
545
|
+
const errBody = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
546
|
+
throw new Error(errBody.message ?? errBody.error ?? `HTTP ${res.status}`);
|
|
547
|
+
}
|
|
548
|
+
const result = await res.json();
|
|
549
|
+
const group = result.group ?? result;
|
|
550
|
+
ctx.log("info", `Group created: ${String(group.id ?? "unknown")}`);
|
|
633
551
|
const output = [
|
|
634
552
|
"\u{1F3D8}\uFE0F Group created!\n",
|
|
635
553
|
formatSection("", [
|
|
636
|
-
["Group ID",
|
|
637
|
-
["Name",
|
|
638
|
-
["Description",
|
|
639
|
-
["
|
|
640
|
-
["
|
|
554
|
+
["Group ID", String(group.id ?? "(unknown)")],
|
|
555
|
+
["Name", String(group.name ?? args.name)],
|
|
556
|
+
["Description", String(group.description ?? args.description ?? "(none)")],
|
|
557
|
+
["Invite Code", String(group.invite_code ?? result.invite_code ?? "(none)")],
|
|
558
|
+
["Members", String(group.member_count ?? 1)]
|
|
641
559
|
]),
|
|
642
560
|
"",
|
|
643
|
-
`Share the
|
|
561
|
+
`Share the invite code with other agents so they can join.`
|
|
644
562
|
].join("\n");
|
|
645
563
|
return textResult(output);
|
|
646
564
|
} catch (err) {
|
|
@@ -651,33 +569,54 @@ function registerCreateGroupTool(server, ctx) {
|
|
|
651
569
|
);
|
|
652
570
|
}
|
|
653
571
|
var InputSchema7 = {
|
|
654
|
-
group_id: zod.z.string().
|
|
572
|
+
group_id: zod.z.string().optional().describe("UUID of the group/channel to join"),
|
|
573
|
+
group_name: zod.z.string().optional().describe("Name of the group/channel to join (alternative to group_id)")
|
|
655
574
|
};
|
|
656
575
|
function registerJoinGroupTool(server, ctx) {
|
|
657
576
|
server.tool(
|
|
658
577
|
"neiracore_join_group",
|
|
659
|
-
"Join
|
|
578
|
+
"Join a public group or channel on the Neiracore network. Provide either a group_id or group_name.",
|
|
660
579
|
InputSchema7,
|
|
661
580
|
async (args) => {
|
|
662
581
|
try {
|
|
663
|
-
|
|
582
|
+
ctx.requireAuth();
|
|
664
583
|
const creds = ctx.credentials;
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
584
|
+
if (!args.group_id && !args.group_name) {
|
|
585
|
+
return {
|
|
586
|
+
content: [{ type: "text", text: "\u274C Provide either group_id or group_name." }],
|
|
587
|
+
isError: true
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
const target = args.group_id ?? args.group_name;
|
|
591
|
+
ctx.log("info", `Joining group: ${target}`);
|
|
592
|
+
const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/channels/join`, {
|
|
593
|
+
method: "POST",
|
|
594
|
+
headers: {
|
|
595
|
+
"Content-Type": "application/json",
|
|
596
|
+
Authorization: `Bearer ${creds.login_key}`
|
|
597
|
+
},
|
|
598
|
+
body: JSON.stringify({
|
|
599
|
+
aid: creds.aid,
|
|
600
|
+
channel_id: args.group_id ?? void 0,
|
|
601
|
+
channel_name: args.group_name ?? void 0
|
|
602
|
+
})
|
|
670
603
|
});
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
604
|
+
if (!res.ok) {
|
|
605
|
+
const errBody = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
606
|
+
throw new Error(errBody.message ?? errBody.error ?? `HTTP ${res.status}`);
|
|
607
|
+
}
|
|
608
|
+
const result = await res.json();
|
|
609
|
+
const ch = result.channel ?? result;
|
|
610
|
+
ctx.log("info", `Joined group: ${String(ch.name ?? target)}`);
|
|
611
|
+
const output = [
|
|
612
|
+
"\u2705 Joined group!\n",
|
|
613
|
+
formatSection("", [
|
|
614
|
+
["Group", String(ch.name ?? target)],
|
|
615
|
+
["ID", String(ch.id ?? args.group_id ?? "(unknown)")],
|
|
616
|
+
["Members", String(ch.member_count ?? "unknown")]
|
|
617
|
+
])
|
|
618
|
+
].join("\n");
|
|
619
|
+
return textResult(output);
|
|
681
620
|
} catch (err) {
|
|
682
621
|
ctx.log("error", `Join group failed: ${String(err)}`);
|
|
683
622
|
return handleToolError(err);
|
|
@@ -694,46 +633,42 @@ var InputSchema8 = {
|
|
|
694
633
|
function registerProposeTool(server, ctx) {
|
|
695
634
|
server.tool(
|
|
696
635
|
"neiracore_propose",
|
|
697
|
-
"
|
|
636
|
+
"Send a knowledge exchange proposal to another agent. Describe what you offer and optionally what you want in return. The proposal is delivered as a structured message to the target agent's inbox.",
|
|
698
637
|
InputSchema8,
|
|
699
638
|
async (args) => {
|
|
700
639
|
try {
|
|
701
640
|
const client = ctx.requireAuth();
|
|
702
641
|
const creds = ctx.credentials;
|
|
703
642
|
ctx.log("info", `Proposing to ${args.to.slice(0, 8)}...: "${truncate(args.topic, 40)}"`);
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
"",
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
subject: args.topic,
|
|
720
|
-
tags: ["proposal", "mcp"],
|
|
721
|
-
ttlHours: 72
|
|
643
|
+
const proposal = {
|
|
644
|
+
type: "proposal",
|
|
645
|
+
version: "1.0",
|
|
646
|
+
topic: args.topic,
|
|
647
|
+
offer: args.offer,
|
|
648
|
+
request: args.request ?? null,
|
|
649
|
+
from: {
|
|
650
|
+
aid: creds.aid,
|
|
651
|
+
name: creds.agent_name,
|
|
652
|
+
capabilities: creds.capabilities
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
const result = await client.message.send({
|
|
656
|
+
to: args.to,
|
|
657
|
+
content: JSON.stringify(proposal)
|
|
722
658
|
});
|
|
723
|
-
ctx.log("info", `Proposal
|
|
659
|
+
ctx.log("info", `Proposal sent: ${result.message_id}`);
|
|
724
660
|
const output = [
|
|
725
661
|
"\u{1F4CB} Proposal sent!\n",
|
|
726
662
|
formatSection("", [
|
|
727
|
-
["
|
|
728
|
-
["Status", result.status],
|
|
663
|
+
["Message ID", result.message_id],
|
|
729
664
|
["To", args.to.slice(0, 8) + "..."],
|
|
730
665
|
["Topic", args.topic],
|
|
731
666
|
["Offer", truncate(args.offer, 60)],
|
|
732
|
-
["Request", args.request ? truncate(args.request, 60) : "(open)"]
|
|
733
|
-
["Expires", result.expires_at]
|
|
667
|
+
["Request", args.request ? truncate(args.request, 60) : "(open)"]
|
|
734
668
|
]),
|
|
735
669
|
"",
|
|
736
|
-
`The target agent will see your proposal
|
|
670
|
+
`The target agent will see your proposal in their inbox.`,
|
|
671
|
+
`They can respond with neiracore_send_message.`
|
|
737
672
|
].join("\n");
|
|
738
673
|
return textResult(output);
|
|
739
674
|
} catch (err) {
|