@bli-cockpit/mcp 0.1.54 → 0.1.57
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 +3 -1
- package/dist/memory-consolidation-tools.d.ts +19 -0
- package/dist/memory-consolidation-tools.js +53 -0
- package/dist/memory-profile-tools.d.ts +23 -0
- package/dist/memory-profile-tools.js +65 -0
- package/dist/server.js +7 -0
- package/dist/settings-write-tools.js +4 -1
- package/dist/verb-census.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ about what an agent can reach.
|
|
|
34
34
|
|
|
35
35
|
<!-- BEGIN GENERATED verb census — `npm run mcp:readme` -->
|
|
36
36
|
|
|
37
|
-
**
|
|
37
|
+
**106 of 111 Tower verbs have an MCP twin.**
|
|
38
38
|
Each tool goes through the SAME door its CLI verb calls, with the same
|
|
39
39
|
collector device token — never a second route and never a service-role
|
|
40
40
|
reader. `src/verb-census.test.ts` fails when a verb is in none of the
|
|
@@ -91,8 +91,10 @@ three tables below.
|
|
|
91
91
|
| `cockpit mail search` | `mail_search` | `GET /api/mail/search` |
|
|
92
92
|
| `cockpit mail send` | `mail_send` | `POST /api/mail/send` |
|
|
93
93
|
| `cockpit mail sync` | `mail_sync` | `POST /api/mail/accounts/[id]/sync` |
|
|
94
|
+
| `cockpit memory consolidation` | `memory_consolidation` | `GET /api/memory/consolidation` |
|
|
94
95
|
| `cockpit memory forget` | `forget_memory` (`bli-memory`) | `POST /api/memory/forget` |
|
|
95
96
|
| `cockpit memory log` | `memory_experience` | `POST /api/memory/experience` |
|
|
97
|
+
| `cockpit memory profile` | `memory_profile` | `GET /api/memory/profile` |
|
|
96
98
|
| `cockpit memory save` | `save_memory` (`bli-memory`) | `POST /api/memory/save` |
|
|
97
99
|
| `cockpit memory search` | `search_memory` (`bli-memory`) | `POST /api/memory/search` |
|
|
98
100
|
| `cockpit memory update` | `update_memory` (`bli-memory`) | `POST /api/memory/update` |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `memory_consolidation` — the MCP twin of `cockpit memory consolidation`
|
|
3
|
+
* (BLI-4534).
|
|
4
|
+
*
|
|
5
|
+
* Same door, same device token, same answer: `GET /api/memory/consolidation`.
|
|
6
|
+
* It reads what the nightly BLI Memory tidy-up pass did — clusters looked at,
|
|
7
|
+
* edits by verb, refusals by reason, cost — and it cannot start, stop or
|
|
8
|
+
* change a pass. The pass itself is a Railway cron.
|
|
9
|
+
*
|
|
10
|
+
* It lives on `bli-tower` rather than on the `bli-memory` server that carries
|
|
11
|
+
* `search_memory`/`save_memory`/`update_memory`/`forget_memory`, because this
|
|
12
|
+
* is a read of a JOB's counts rather than a read or a write of the store.
|
|
13
|
+
*
|
|
14
|
+
* No memory text crosses this tool. The door does not send any.
|
|
15
|
+
*/
|
|
16
|
+
import { type ToolDeps } from "./tool-result.js";
|
|
17
|
+
export declare function registerMemoryConsolidationTools(server: {
|
|
18
|
+
registerTool: (...args: never[]) => unknown;
|
|
19
|
+
}, deps: ToolDeps): void;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `memory_consolidation` — the MCP twin of `cockpit memory consolidation`
|
|
3
|
+
* (BLI-4534).
|
|
4
|
+
*
|
|
5
|
+
* Same door, same device token, same answer: `GET /api/memory/consolidation`.
|
|
6
|
+
* It reads what the nightly BLI Memory tidy-up pass did — clusters looked at,
|
|
7
|
+
* edits by verb, refusals by reason, cost — and it cannot start, stop or
|
|
8
|
+
* change a pass. The pass itself is a Railway cron.
|
|
9
|
+
*
|
|
10
|
+
* It lives on `bli-tower` rather than on the `bli-memory` server that carries
|
|
11
|
+
* `search_memory`/`save_memory`/`update_memory`/`forget_memory`, because this
|
|
12
|
+
* is a read of a JOB's counts rather than a read or a write of the store.
|
|
13
|
+
*
|
|
14
|
+
* No memory text crosses this tool. The door does not send any.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { callAgentDoor } from "./agent-door.js";
|
|
18
|
+
import { doorFailureText, errorResult, queryString, registrarFor, textResult, withSession, } from "./tool-result.js";
|
|
19
|
+
export function registerMemoryConsolidationTools(server, deps) {
|
|
20
|
+
registrarFor(server)("memory_consolidation", {
|
|
21
|
+
title: "Read the nightly memory consolidation runs",
|
|
22
|
+
description: "What the nightly BLI Memory consolidation pass did: clusters, merges/rewrites/dated corrections by verb, refusals by reason, model and cost. With a container tag it answers that space's recent runs; without one, the newest run per container. Read-only — the pass never deletes a memory and this tool never starts one. An empty list means no run is visible to this account (the receipts are super_admin-readable), not an outage.",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
container: z
|
|
25
|
+
.string()
|
|
26
|
+
.min(1)
|
|
27
|
+
.max(128)
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("One container tag. Omit for the newest run per container."),
|
|
30
|
+
limit: z
|
|
31
|
+
.number()
|
|
32
|
+
.int()
|
|
33
|
+
.min(1)
|
|
34
|
+
.max(200)
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("How many run rows to read. Default 50."),
|
|
37
|
+
},
|
|
38
|
+
}, async (args) => withSession(deps, async (session) => {
|
|
39
|
+
const params = new URLSearchParams();
|
|
40
|
+
if (args.container)
|
|
41
|
+
params.set("container", String(args.container));
|
|
42
|
+
if (args.limit !== undefined)
|
|
43
|
+
params.set("limit", String(args.limit));
|
|
44
|
+
const response = await callAgentDoor(session, deps.fetchImpl, "GET", `/api/memory/consolidation${queryString(params)}`);
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
return errorResult(doorFailureText("memory_consolidation", response));
|
|
47
|
+
const runs = Array.isArray(response.body.runs) ? response.body.runs : [];
|
|
48
|
+
const reason = typeof response.body.reason === "string" ? response.body.reason : "runs_read";
|
|
49
|
+
return textResult(runs.length === 0
|
|
50
|
+
? `No consolidation runs are visible (${reason}). The pass is a nightly cron and its receipts are readable by a super_admin; this is the access rule answering, not an outage.`
|
|
51
|
+
: `${runs.length} consolidation run${runs.length === 1 ? "" : "s"}. report = proposals only, nothing on the shelf changed; apply = accepted edits written as supersessions, which never delete anything.`, response.body);
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `memory_profile` (BLI-4533) — the compiled one-page briefing for a memory
|
|
3
|
+
* space, over the same `GET /api/memory/profile` door `cockpit memory profile`
|
|
4
|
+
* calls.
|
|
5
|
+
*
|
|
6
|
+
* Every session already opens with this page injected by the session-start
|
|
7
|
+
* hook. This tool exists for the turn AFTER that: an agent that wants to know
|
|
8
|
+
* what a DIFFERENT project's memory says about itself, or one that wants to
|
|
9
|
+
* re-read its own briefing without trusting a context window that has since
|
|
10
|
+
* been compacted.
|
|
11
|
+
*
|
|
12
|
+
* It lives on `bli-tower` rather than on `bli-memory` for one reason: the four
|
|
13
|
+
* store tools on that server are the vendor-compatible set the Claude Code
|
|
14
|
+
* plugin expects, and this is ours. The DOOR is the same either way.
|
|
15
|
+
*
|
|
16
|
+
* Read-only, and there is no compile argument on purpose. The page is written
|
|
17
|
+
* once a day by the `memory-profile` Railway service; a tool that could trigger
|
|
18
|
+
* a compile would put a paid model call behind a sentence an agent types.
|
|
19
|
+
*/
|
|
20
|
+
import { type ToolDeps } from "./tool-result.js";
|
|
21
|
+
export declare function registerMemoryProfileTools(server: {
|
|
22
|
+
registerTool: (...args: never[]) => unknown;
|
|
23
|
+
}, deps: ToolDeps): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `memory_profile` (BLI-4533) — the compiled one-page briefing for a memory
|
|
3
|
+
* space, over the same `GET /api/memory/profile` door `cockpit memory profile`
|
|
4
|
+
* calls.
|
|
5
|
+
*
|
|
6
|
+
* Every session already opens with this page injected by the session-start
|
|
7
|
+
* hook. This tool exists for the turn AFTER that: an agent that wants to know
|
|
8
|
+
* what a DIFFERENT project's memory says about itself, or one that wants to
|
|
9
|
+
* re-read its own briefing without trusting a context window that has since
|
|
10
|
+
* been compacted.
|
|
11
|
+
*
|
|
12
|
+
* It lives on `bli-tower` rather than on `bli-memory` for one reason: the four
|
|
13
|
+
* store tools on that server are the vendor-compatible set the Claude Code
|
|
14
|
+
* plugin expects, and this is ours. The DOOR is the same either way.
|
|
15
|
+
*
|
|
16
|
+
* Read-only, and there is no compile argument on purpose. The page is written
|
|
17
|
+
* once a day by the `memory-profile` Railway service; a tool that could trigger
|
|
18
|
+
* a compile would put a paid model call behind a sentence an agent types.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
import { callAgentDoor } from "./agent-door.js";
|
|
22
|
+
import { doorFailureText, errorResult, queryString, registrarFor, textResult, withSession, } from "./tool-result.js";
|
|
23
|
+
export function registerMemoryProfileTools(server, deps) {
|
|
24
|
+
registrarFor(server)("memory_profile", {
|
|
25
|
+
title: "Read a memory space's compiled profile",
|
|
26
|
+
description: "The one-page briefing BLI Memory compiles daily for a container: who works here, what is going on now, "
|
|
27
|
+
+ "standing rules and preferences, how to communicate. The same page a session start injects. Read-only — "
|
|
28
|
+
+ "the compile runs on a cron, never on demand. A container with no page yet answers `not_compiled_yet`, "
|
|
29
|
+
+ "which means nothing has been compiled, NOT that the store is down.",
|
|
30
|
+
inputSchema: {
|
|
31
|
+
container: z
|
|
32
|
+
.string()
|
|
33
|
+
.min(1)
|
|
34
|
+
.max(128)
|
|
35
|
+
.describe("The container tag, e.g. repo_bli_cockpit__12e241cdbc00adfd."),
|
|
36
|
+
},
|
|
37
|
+
}, async (args) => withSession(deps, async (session) => {
|
|
38
|
+
const container = String(args.container);
|
|
39
|
+
const response = await callAgentDoor(session, deps.fetchImpl, "GET", `/api/memory/profile${queryString(new URLSearchParams({ container }))}`);
|
|
40
|
+
if (!response.ok)
|
|
41
|
+
return errorResult(doorFailureText("memory_profile", response));
|
|
42
|
+
const body = response.body;
|
|
43
|
+
const profile = body.profile ?? null;
|
|
44
|
+
const lines = profile?.lines ?? [];
|
|
45
|
+
if (lines.length === 0) {
|
|
46
|
+
// Named, not blank: the difference between "not compiled yet" and an
|
|
47
|
+
// empty page is the whole reason the door returns a reason at all.
|
|
48
|
+
return textResult(`No profile is compiled for ${container} yet (${String(body.reason ?? "unknown")}). `
|
|
49
|
+
+ "The daily compile writes one once this space has memories.", { ok: true, containerTag: container, reason: body.reason ?? "unknown", lines: 0 });
|
|
50
|
+
}
|
|
51
|
+
return textResult([
|
|
52
|
+
...lines,
|
|
53
|
+
"",
|
|
54
|
+
`Compiled ${String(profile?.compiledAt ?? "—")} from ${String(profile?.sourceRows ?? 0)} memories by ${String(profile?.model ?? "—")}.`,
|
|
55
|
+
].join("\n"), {
|
|
56
|
+
ok: true,
|
|
57
|
+
containerTag: container,
|
|
58
|
+
reason: body.reason ?? "profile_read",
|
|
59
|
+
lines: lines.length,
|
|
60
|
+
compiledAt: profile?.compiledAt ?? null,
|
|
61
|
+
sourceRows: profile?.sourceRows ?? 0,
|
|
62
|
+
model: profile?.model ?? null,
|
|
63
|
+
});
|
|
64
|
+
}));
|
|
65
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -15,7 +15,9 @@ import { registerMailTools } from "./mail-tools.js";
|
|
|
15
15
|
import { registerNotesAccountTools } from "./notes-account-tools.js";
|
|
16
16
|
import { registerNotesTools } from "./notes-tools.js";
|
|
17
17
|
import { registerNotesWriteTools } from "./notes-write-tools.js";
|
|
18
|
+
import { registerMemoryConsolidationTools } from "./memory-consolidation-tools.js";
|
|
18
19
|
import { registerMemoryExperienceTools } from "./memory-experience-tools.js";
|
|
20
|
+
import { registerMemoryProfileTools } from "./memory-profile-tools.js";
|
|
19
21
|
import { registerModelsTools } from "./models-tools.js";
|
|
20
22
|
import { registerOpsTools } from "./ops-tools.js";
|
|
21
23
|
import { registerPagesTools } from "./pages-tools.js";
|
|
@@ -423,6 +425,11 @@ export function createServer(deps) {
|
|
|
423
425
|
registerNotesTools(server, { fetchImpl: deps.fetchImpl });
|
|
424
426
|
registerOpsTools(server, { fetchImpl: deps.fetchImpl });
|
|
425
427
|
registerMemoryExperienceTools(server, { fetchImpl: deps.fetchImpl });
|
|
428
|
+
// BLI-4533: the compiled one-page profile, the twin of `cockpit memory profile`.
|
|
429
|
+
registerMemoryProfileTools(server, { fetchImpl: deps.fetchImpl });
|
|
430
|
+
// BLI-4534: the nightly consolidation receipts, twin of `cockpit memory
|
|
431
|
+
// consolidation`. Read-only, and the pass it reports on never deletes.
|
|
432
|
+
registerMemoryConsolidationTools(server, { fetchImpl: deps.fetchImpl });
|
|
426
433
|
registerSettingsTools(server, { fetchImpl: deps.fetchImpl });
|
|
427
434
|
registerPagesTools(server, { fetchImpl: deps.fetchImpl });
|
|
428
435
|
// BLI-3756 batch 2: the WRITES. Same doors, same device token, same refusal
|
|
@@ -65,6 +65,7 @@ export function registerSettingsWriteTools(server, deps) {
|
|
|
65
65
|
chat_model: z.string().min(3).max(200).optional().describe("personal/models: provider:model."),
|
|
66
66
|
brief_model: z.string().min(3).max(200).optional().describe("personal: provider:model."),
|
|
67
67
|
memory_model: z.string().min(1).max(200).optional().describe("models: the memory compiler's model id."),
|
|
68
|
+
note_reader_model: z.string().min(3).max(200).optional().describe("models: the meeting-note reader, provider:model from its allowlist."),
|
|
68
69
|
key: z.string().min(1).max(200).optional().describe("switches: which switch."),
|
|
69
70
|
value: z.string().min(1).max(200).optional().describe("switches: its new value."),
|
|
70
71
|
version: z.string().min(1).max(50).optional().describe("cli-floor: the version every collector is pulled to."),
|
|
@@ -113,8 +114,10 @@ export function registerSettingsWriteTools(server, deps) {
|
|
|
113
114
|
}
|
|
114
115
|
if (args.memory_model)
|
|
115
116
|
body.memoryModel = String(args.memory_model);
|
|
117
|
+
if (args.note_reader_model)
|
|
118
|
+
body.noteReaderModel = String(args.note_reader_model);
|
|
116
119
|
if (Object.keys(body).length === 0) {
|
|
117
|
-
return errorResult("Refused (nothing_to_set): name chat_model or
|
|
120
|
+
return errorResult("Refused (nothing_to_set): name chat_model, memory_model or note_reader_model. Nothing was changed.");
|
|
118
121
|
}
|
|
119
122
|
return write(deps, session, "settings_set", "POST", "/api/settings/model-routing", body, (answer) => {
|
|
120
123
|
const saved = Array.isArray(answer.saved) ? answer.saved.join(", ") : "";
|
package/dist/verb-census.js
CHANGED
|
@@ -300,6 +300,14 @@ export const MCP_TWINS = {
|
|
|
300
300
|
"memory save": { tool: "save_memory", door: "POST /api/memory/save", server: "bli-memory" },
|
|
301
301
|
"memory update": { tool: "update_memory", door: "POST /api/memory/update", server: "bli-memory" },
|
|
302
302
|
"memory forget": { tool: "forget_memory", door: "POST /api/memory/forget", server: "bli-memory" },
|
|
303
|
+
// BLI-4533: the compiled one-page profile. Its twin is on `bli-tower`, not
|
|
304
|
+
// `bli-memory`: that server's four tools are the vendor-compatible set the
|
|
305
|
+
// Claude Code plugin expects, and this page is ours.
|
|
306
|
+
"memory profile": { tool: "memory_profile", door: "GET /api/memory/profile" },
|
|
307
|
+
// BLI-4534: the nightly consolidation receipts. This twin lives on
|
|
308
|
+
// `bli-tower` rather than `bli-memory`, because it is a read of a JOB s
|
|
309
|
+
// counts and not a read or write of the store itself.
|
|
310
|
+
"memory consolidation": { tool: "memory_consolidation", door: "GET /api/memory/consolidation" },
|
|
303
311
|
"ops status": { tool: "ops_status", door: "GET /api/ops/status" },
|
|
304
312
|
"ops recompile": { tool: "ops_recompile", door: "POST /api/ops/recompile" },
|
|
305
313
|
"slack coverage": { tool: "slack_coverage", door: "GET /api/ops/slack/coverage" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.57",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "bli-tower: an MCP server over BLI Cockpit's agent doors: JARVIS (jarvis_*), documents (docs_*), channels (msg_*), issues (work_*), the daily page (brief_*), meeting notes (notes_*), the ops board (ops_status/slack_*), settings/team/model, Scout and the workbook, plus the legacy event-stream tools (emit_event, get_ticket_timeline, get_active_tickets).",
|
|
6
6
|
"type": "module",
|