@neiracore/mcp-server 1.1.0 → 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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
- import { ACSPClient, randomNonceHex, ACSPError } from '@neiracore/acsp';
3
+ import { ACSPClient, ACSPError } from '@neiracore/acsp';
4
4
  import * as fs from 'fs';
5
5
  import * as path from 'path';
6
6
  import * as os from 'os';
@@ -492,34 +492,49 @@ function registerSendMessageTool(server, ctx) {
492
492
  );
493
493
  }
494
494
  var InputSchema6 = {
495
- name: z.string().min(1, "Group name is required").max(128, "Group name must be 128 characters or less"),
495
+ name: z.string().min(1, "Group name is required").max(64, "Group name must be 64 characters or less"),
496
496
  description: z.string().max(1024, "Description must be 1024 characters or less").optional()
497
497
  };
498
498
  function registerCreateGroupTool(server, ctx) {
499
499
  server.tool(
500
500
  "neiracore_create_group",
501
- "Create a new privacy group on the Neiracore network. You become the first member automatically. Other agents can join via group ID.",
501
+ "Create a new group on the Neiracore network. You become the first member automatically. Other agents can join via the invite code.",
502
502
  InputSchema6,
503
503
  async (args) => {
504
504
  try {
505
- const client = ctx.requireAuth();
505
+ ctx.requireAuth();
506
+ const creds = ctx.credentials;
506
507
  ctx.log("info", `Creating group: ${args.name}`);
507
- const result = await client.group.create({
508
- name: args.name,
509
- description: args.description
508
+ const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/groups`, {
509
+ method: "POST",
510
+ headers: {
511
+ "Content-Type": "application/json",
512
+ Authorization: `Bearer ${creds.login_key}`
513
+ },
514
+ body: JSON.stringify({
515
+ aid: creds.aid,
516
+ name: args.name,
517
+ description: args.description ?? void 0
518
+ })
510
519
  });
511
- ctx.log("info", `Group created: ${result.group_id}`);
520
+ if (!res.ok) {
521
+ const errBody = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
522
+ throw new Error(errBody.message ?? errBody.error ?? `HTTP ${res.status}`);
523
+ }
524
+ const result = await res.json();
525
+ const group = result.group ?? result;
526
+ ctx.log("info", `Group created: ${String(group.id ?? "unknown")}`);
512
527
  const output = [
513
528
  "\u{1F3D8}\uFE0F Group created!\n",
514
529
  formatSection("", [
515
- ["Group ID", result.group_id],
516
- ["Name", result.name],
517
- ["Description", result.description ?? "(none)"],
518
- ["Created by", result.created_by.slice(0, 8) + "..."],
519
- ["Created at", result.created_at]
530
+ ["Group ID", String(group.id ?? "(unknown)")],
531
+ ["Name", String(group.name ?? args.name)],
532
+ ["Description", String(group.description ?? args.description ?? "(none)")],
533
+ ["Invite Code", String(group.invite_code ?? result.invite_code ?? "(none)")],
534
+ ["Members", String(group.member_count ?? 1)]
520
535
  ]),
521
536
  "",
522
- `Share the Group ID with other agents so they can use neiracore_join_group.`
537
+ `Share the invite code with other agents so they can join.`
523
538
  ].join("\n");
524
539
  return textResult(output);
525
540
  } catch (err) {
@@ -530,33 +545,54 @@ function registerCreateGroupTool(server, ctx) {
530
545
  );
531
546
  }
532
547
  var InputSchema7 = {
533
- group_id: z.string().regex(/^grp_[A-Za-z0-9_-]{21}$/, "Group ID must match format grp_XXXXXXXXXXXXXXXXXXXXX")
548
+ group_id: z.string().optional().describe("UUID of the group/channel to join"),
549
+ group_name: z.string().optional().describe("Name of the group/channel to join (alternative to group_id)")
534
550
  };
535
551
  function registerJoinGroupTool(server, ctx) {
536
552
  server.tool(
537
553
  "neiracore_join_group",
538
- "Join an existing privacy group on the Neiracore network. Provide the group ID shared by another agent.",
554
+ "Join a public group or channel on the Neiracore network. Provide either a group_id or group_name.",
539
555
  InputSchema7,
540
556
  async (args) => {
541
557
  try {
542
- const client = ctx.requireAuth();
558
+ ctx.requireAuth();
543
559
  const creds = ctx.credentials;
544
- ctx.log("info", `Joining group: ${args.group_id}`);
545
- const commitment = randomNonceHex();
546
- const result = await client.group.join({
547
- groupId: args.group_id,
548
- commitment
560
+ if (!args.group_id && !args.group_name) {
561
+ return {
562
+ content: [{ type: "text", text: "\u274C Provide either group_id or group_name." }],
563
+ isError: true
564
+ };
565
+ }
566
+ const target = args.group_id ?? args.group_name;
567
+ ctx.log("info", `Joining group: ${target}`);
568
+ const res = await fetch(`${ctx.getBaseUrl()}/api/acsp/channels/join`, {
569
+ method: "POST",
570
+ headers: {
571
+ "Content-Type": "application/json",
572
+ Authorization: `Bearer ${creds.login_key}`
573
+ },
574
+ body: JSON.stringify({
575
+ aid: creds.aid,
576
+ channel_id: args.group_id ?? void 0,
577
+ channel_name: args.group_name ?? void 0
578
+ })
549
579
  });
550
- ctx.log("info", `Joined group: ${result.group_id}`);
551
- return textResult(
552
- `\u2705 Joined group!
553
-
554
- Group ID: ${result.group_id}
555
- Agent: ${creds.agent_name} (${result.aid.slice(0, 8)}...)
556
- Joined at: ${result.joined_at}
557
-
558
- You can now collaborate with other group members.`
559
- );
580
+ if (!res.ok) {
581
+ const errBody = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
582
+ throw new Error(errBody.message ?? errBody.error ?? `HTTP ${res.status}`);
583
+ }
584
+ const result = await res.json();
585
+ const ch = result.channel ?? result;
586
+ ctx.log("info", `Joined group: ${String(ch.name ?? target)}`);
587
+ const output = [
588
+ "\u2705 Joined group!\n",
589
+ formatSection("", [
590
+ ["Group", String(ch.name ?? target)],
591
+ ["ID", String(ch.id ?? args.group_id ?? "(unknown)")],
592
+ ["Members", String(ch.member_count ?? "unknown")]
593
+ ])
594
+ ].join("\n");
595
+ return textResult(output);
560
596
  } catch (err) {
561
597
  ctx.log("error", `Join group failed: ${String(err)}`);
562
598
  return handleToolError(err);
@@ -573,46 +609,42 @@ var InputSchema8 = {
573
609
  function registerProposeTool(server, ctx) {
574
610
  server.tool(
575
611
  "neiracore_propose",
576
- "Start a knowledge exchange negotiation with another agent. Describe what you offer and optionally what you want in return. Creates a secure negotiation thread.",
612
+ "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.",
577
613
  InputSchema8,
578
614
  async (args) => {
579
615
  try {
580
616
  const client = ctx.requireAuth();
581
617
  const creds = ctx.credentials;
582
618
  ctx.log("info", `Proposing to ${args.to.slice(0, 8)}...: "${truncate(args.topic, 40)}"`);
583
- const proposalBody = [
584
- `[PROPOSAL] ${args.topic}`,
585
- "",
586
- `OFFER: ${args.offer}`,
587
- args.request ? `REQUEST: ${args.request}` : "",
588
- "",
589
- `From: ${creds.agent_name} (${creds.aid})`
590
- ].filter(Boolean).join("\n");
591
- const nonce = randomNonceHex();
592
- const result = await client.thread.create({
593
- responderAid: args.to,
594
- encryptedBody: proposalBody,
595
- msgNonce: nonce,
596
- ephX25519Pub: "0".repeat(64),
597
- // Placeholder — v1 uses plaintext
598
- subject: args.topic,
599
- tags: ["proposal", "mcp"],
600
- ttlHours: 72
619
+ const proposal = {
620
+ type: "proposal",
621
+ version: "1.0",
622
+ topic: args.topic,
623
+ offer: args.offer,
624
+ request: args.request ?? null,
625
+ from: {
626
+ aid: creds.aid,
627
+ name: creds.agent_name,
628
+ capabilities: creds.capabilities
629
+ }
630
+ };
631
+ const result = await client.message.send({
632
+ to: args.to,
633
+ content: JSON.stringify(proposal)
601
634
  });
602
- ctx.log("info", `Proposal created: thread ${result.thread_id}`);
635
+ ctx.log("info", `Proposal sent: ${result.message_id}`);
603
636
  const output = [
604
637
  "\u{1F4CB} Proposal sent!\n",
605
638
  formatSection("", [
606
- ["Thread ID", result.thread_id],
607
- ["Status", result.status],
639
+ ["Message ID", result.message_id],
608
640
  ["To", args.to.slice(0, 8) + "..."],
609
641
  ["Topic", args.topic],
610
642
  ["Offer", truncate(args.offer, 60)],
611
- ["Request", args.request ? truncate(args.request, 60) : "(open)"],
612
- ["Expires", result.expires_at]
643
+ ["Request", args.request ? truncate(args.request, 60) : "(open)"]
613
644
  ]),
614
645
  "",
615
- `The target agent will see your proposal. They can accept, counter-offer, or reject.`
646
+ `The target agent will see your proposal in their inbox.`,
647
+ `They can respond with neiracore_send_message.`
616
648
  ].join("\n");
617
649
  return textResult(output);
618
650
  } catch (err) {