@rackbops/plugin-mcp 0.3.3 → 0.4.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 CHANGED
@@ -4,7 +4,8 @@ The bridge plugin for the Discord delivery MCP ([`Rackbops/discord-mcp`](https:/
4
4
  [Rackbops/Tooling#742](https://github.com/Rackbops/Tooling/issues/742)). It implements the service
5
5
  side of that repo's `docs/bridge-protocol.md` under `/mcp/` on the bot's own HTTP listener
6
6
  (rackbops-discord-bot's host-owned router, ADR-0007) -- `GET /capabilities`,
7
- `POST /deliveries`, `GET /deliveries/{request_id}` and `GET /recipients` -- so the MCP service can
7
+ `POST /deliveries`, `GET /deliveries/{request_id}`, `GET /recipients` and
8
+ `GET /recipients/{user_id}` -- so the MCP service can
8
9
  hand it a message and get one Discord post, DM or edit out of it: a retry of a request that is
9
10
  delivered or in flight never delivers again (a retry of a failed or unknown one, and the restart
10
11
  re-drive, deliver at least once -- see below). It also owns Discord-side agent identity ([Rackbops/Tooling#743](https://github.com/Rackbops/Tooling/issues/743)):
@@ -90,6 +91,17 @@ most 100, each `display_name` truncated to 100 characters (same bearer auth; any
90
91
  200: {"items":[]}
91
92
  ```
92
93
 
94
+ `GET /recipients/{user_id}` -- one registered user, in the same shape as a `GET /recipients` item
95
+ and with the same display-name truncation, but with no cap: a user registered after the first 100
96
+ still finds their own entry here. `user_id` must be a snowflake (`[1-9][0-9]{16,19}`); a malformed
97
+ one falls through to the generic `404 {"error":"not found"}`. Same bearer auth; any other method is
98
+ `405`:
99
+
100
+ ```
101
+ 200: {"user_id":"123456789012345678","display_name":"Roshne"}
102
+ 404: {"error":"not registered"}
103
+ ```
104
+
93
105
  `GET /capabilities` now reflects the host's real `dm`/`edit` support:
94
106
 
95
107
  ```
package/dist/plugin.js CHANGED
@@ -257,9 +257,10 @@ function toWireState(stored) {
257
257
  }
258
258
  function recipientsResponse(entries) {
259
259
  const sorted = [...entries].sort((a, b) => a.registeredAt.localeCompare(b.registeredAt) || a.userId.localeCompare(b.userId));
260
- return {
261
- items: sorted.slice(0, RECIPIENTS_MAX).map((e) => ({ user_id: e.userId, display_name: e.displayName.slice(0, DISPLAY_NAME_MAX) }))
262
- };
260
+ return { items: sorted.slice(0, RECIPIENTS_MAX).map(recipientResponse) };
261
+ }
262
+ function recipientResponse(entry) {
263
+ return { user_id: entry.userId, display_name: entry.displayName.slice(0, DISPLAY_NAME_MAX) };
263
264
  }
264
265
 
265
266
  // plugins/mcp/src/drain.ts
@@ -549,8 +550,15 @@ async function handleGetRecipients(deps) {
549
550
  const entries = await deps.registry.listRecipients();
550
551
  return json(200, recipientsResponse(entries));
551
552
  }
553
+ async function handleGetRecipient(userId, deps) {
554
+ const entry = await deps.registry.recipientOf(userId);
555
+ if (entry === undefined)
556
+ return json(404, { error: "not registered" });
557
+ return json(200, recipientResponse(entry));
558
+ }
552
559
  var DELIVERY_ID_RE = /^\/deliveries\/([0-9a-f]{64})$/;
553
560
  var REGISTRATION_ID_RE = /^\/registration\/([1-9][0-9]{16,19})$/;
561
+ var RECIPIENT_ID_RE = /^\/recipients\/([1-9][0-9]{16,19})$/;
554
562
  async function handleMcpHttp(request, info, deps) {
555
563
  if (deps.token === undefined)
556
564
  return json(503, { error: "bridge not configured" });
@@ -593,6 +601,12 @@ async function handleMcpHttp(request, info, deps) {
593
601
  return json(405, { error: "method not allowed" });
594
602
  return handleGetRecipients(deps);
595
603
  }
604
+ const recipientMatch = RECIPIENT_ID_RE.exec(info.path);
605
+ if (recipientMatch) {
606
+ if (request.method !== "GET")
607
+ return json(405, { error: "method not allowed" });
608
+ return handleGetRecipient(recipientMatch[1], deps);
609
+ }
596
610
  return json(404, { error: "not found" });
597
611
  }
598
612
 
@@ -739,6 +753,13 @@ function createRegistryStore(dataDir, storage) {
739
753
  const entry = current.users[userId];
740
754
  return { userId, displayName: entry.displayName, registeredAt: entry.registeredAt };
741
755
  });
756
+ },
757
+ async recipientOf(userId) {
758
+ const current = normalizeRegistry(await storage.readJsonOrFresh(path, freshRegistry, "mcp-registry"));
759
+ const entry = entryOf(current, userId);
760
+ if (entry === undefined)
761
+ return;
762
+ return { userId, displayName: entry.displayName, registeredAt: entry.registeredAt };
742
763
  }
743
764
  };
744
765
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rackbops/plugin-mcp",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "Bridge plugin for the Discord delivery MCP (Rackbops/discord-mcp): the service side of docs/bridge-protocol.md, plus /agent registration and pairing",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",