@bli-cockpit/mcp 0.1.112 → 0.1.113

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
@@ -109,7 +109,7 @@ about what an agent can reach.
109
109
 
110
110
  <!-- BEGIN GENERATED verb census — `npm run mcp:readme` -->
111
111
 
112
- **149 of 154 Tower verbs have an MCP twin.**
112
+ **150 of 155 Tower verbs have an MCP twin.**
113
113
  Each tool goes through the SAME door its CLI verb calls, with the same
114
114
  collector device token — never a second route and never a service-role
115
115
  reader. `src/verb-census.test.ts` fails when a verb is in none of the
@@ -194,6 +194,7 @@ three tables below.
194
194
  | `cockpit mail sync-status` | `mail_sync_status` | `GET /api/mail/sync-status` |
195
195
  | `cockpit memory consolidation` | `memory_consolidation` | `GET /api/memory/consolidation` |
196
196
  | `cockpit memory forget` | `forget_memory` (`bli-memory`) | `POST /api/memory/forget` |
197
+ | `cockpit memory knowledge` | `memory_knowledge` | `GET /api/memory/knowledge` |
197
198
  | `cockpit memory log` | `memory_experience` | `POST /api/memory/experience` |
198
199
  | `cockpit memory private` | `set_memory_visibility` (`bli-memory`) | `POST /api/memory/visibility` |
199
200
  | `cockpit memory profile` | `memory_profile` | `GET /api/memory/profile` |
@@ -2,24 +2,28 @@ import { z } from "zod";
2
2
  import { callAgentDoor } from "./agent-door.js";
3
3
  import { doorFailureText, errorResult, queryString, registrarFor, textResult, withSession } from "./tool-result.js";
4
4
  export function registerMemoryRulesTools(server, deps) {
5
- registrarFor(server)("memory_rules", {
6
- title: "Read BLI agent ground rules",
7
- description: "Standing instructions grouped by whose rule it is, with project and date. Reads only memories visible to you, over the same door as cockpit memory rules. Default 200, max 1000; capped means narrow the filters or increase the bound.",
8
- inputSchema: { person: z.string().min(1).optional().describe("Exact roster name, or unattributed for memories with no author."), project: z.string().min(1).optional().describe("Exact project label, for example Pearl Portal or BLI-wide."), limit: z.number().int().min(1).max(1000).optional().describe("Maximum rows, default 200, maximum 1000. A full page is marked capped.") },
9
- }, async (args) => withSession(deps, async (session) => {
10
- const params = new URLSearchParams();
11
- for (const key of ["person", "project", "limit"])
12
- if (args[key] !== undefined)
13
- params.set(key, String(args[key]));
14
- const response = await callAgentDoor(session, deps.fetchImpl, "GET", `/api/memory/rules${queryString(params)}`);
15
- if (!response.ok)
16
- return errorResult(doorFailureText("memory_rules", response));
17
- const body = response.body;
18
- const lines = body.groups.flatMap((group) => [group.owner, ...group.rules.map((rule) => `[${rule.created_at.slice(0, 10)}] ${rule.project ? `[${rule.project}] ` : ""}${rule.text}${group.owner === "unattributed" ? ` (space: ${rule.container})` : ""}`)]);
19
- if (!lines.length)
20
- lines.push("No ground rules matched.");
21
- if (body.capped)
22
- lines.push("Result capped; narrow by person/project or increase limit (max 1000).");
23
- return textResult(lines.join("\n"), response.body);
24
- }));
5
+ for (const action of ["rules", "knowledge"])
6
+ registrarFor(server)(`memory_${action}`, {
7
+ title: `Read BLI agent ${action}`,
8
+ description: `Memories grouped by project and topic, ranked by Jev importance, repetition, then recency. Reads only memories visible to you, over the same door as cockpit memory ${action}. Default 200 ideas, max 1000; capped means narrow the filters or increase the bound.`,
9
+ inputSchema: { person: z.string().min(1).optional().describe("Exact roster name, or unattributed for memories with no author."), project: z.string().min(1).optional().describe("Case-insensitive project name or canonical slug, for example Pearl Portal or pearl-portal."), limit: z.number().int().min(1).max(1000).optional().describe("Maximum ranked ideas, default 200, maximum 1000. Scan or output bounds are marked capped.") },
10
+ }, async (args) => withSession(deps, async (session) => {
11
+ const params = new URLSearchParams();
12
+ for (const key of ["person", "project", "limit"])
13
+ if (args[key] !== undefined)
14
+ params.set(key, String(args[key]));
15
+ const response = await callAgentDoor(session, deps.fetchImpl, "GET", `/api/memory/${action}${queryString(params)}`);
16
+ if (!response.ok)
17
+ return errorResult(doorFailureText(`memory_${action}`, response));
18
+ const body = response.body;
19
+ const lines = body.projectGroups ? body.projectGroups.flatMap(group => [
20
+ `${group.project} (${group.count}): ${group.headline.split("\n")[0]}`,
21
+ ...group.topics.flatMap(topic => [topic.title, ...topic.memories.map(memory => `${memory.text}${memory.repetition > 1 ? ` (said ${memory.repetition} times)` : ""}${memory.importance !== null ? ` [importance ${memory.importance}/100]` : ""}`)]),
22
+ ]) : (body.groups ?? []).flatMap((group) => [group.owner, ...group.rules.map((rule) => `[${rule.created_at.slice(0, 10)}] ${rule.project ? `[${rule.project}] ` : ""}${rule.text}${group.owner === "unattributed" ? ` (space: ${rule.container})` : ""}`)]);
23
+ if (!lines.length)
24
+ lines.push(`No ${action === "rules" ? "ground rules" : "project knowledge"} matched.`);
25
+ if (body.capped)
26
+ lines.push("Result capped; narrow by person/project or increase limit (max 1000).");
27
+ return textResult(lines.join("\n"), response.body);
28
+ }));
25
29
  }
@@ -10,7 +10,7 @@
10
10
  * from `src/` under Node's type stripping, so it may import nothing.
11
11
  */
12
12
  /** Tools that change nothing. The smoke calls every one. */
13
- export declare const READ_TOOLS: readonly ["get_ticket_timeline", "get_active_tickets", "docs_list", "docs_tree", "docs_read", "docs_sync_status", "msg_channels", "msg_read", "msg_thread", "work_list_issues", "work_get_issue", "work_issue_history", "work_list_projects", "careers_list", "careers_show", "careers_resume_url", "careers_takehome_show", "careers_settings_show", "rename_pending", "github_pr", "setup_read", "speed_read", "speed_seen", "usage_people", "usage_sessions", "mail_accounts", "mail_inbox", "mail_read", "mail_search", "mail_attachment", "mail_sync_status", "cal_today", "cal_week", "cal_next", "cal_find", "cal_calendars", "cal_sync_status", "jarvis_ask", "jarvis_trace", "jarvis_check", "models_list", "models_card", "models_compare", "brief_read", "brief_history", "brief_status", "brief_missed", "notes_folders", "notes_list", "glossary_list", "notes_show", "notes_shelf", "notes_shelves", "notes_place", "notes_accounts", "notes_recordings", "notes_recording", "notes_sync_status", "notes_granola_status", "notes_bot_upcoming", "ops_status", "slack_coverage", "slack_connect", "slack_disconnect", "slack_read", "memory_rules", "memory_profile", "memory_consolidation", "settings_show", "settings_list", "model_show", "team_members", "team_device_list", "scout_board", "workbook_read", "tower_search", "sources_check", "logs_digest", "brain_status"];
13
+ export declare const READ_TOOLS: readonly ["get_ticket_timeline", "get_active_tickets", "docs_list", "docs_tree", "docs_read", "docs_sync_status", "msg_channels", "msg_read", "msg_thread", "work_list_issues", "work_get_issue", "work_issue_history", "work_list_projects", "careers_list", "careers_show", "careers_resume_url", "careers_takehome_show", "careers_settings_show", "rename_pending", "github_pr", "setup_read", "speed_read", "speed_seen", "usage_people", "usage_sessions", "mail_accounts", "mail_inbox", "mail_read", "mail_search", "mail_attachment", "mail_sync_status", "cal_today", "cal_week", "cal_next", "cal_find", "cal_calendars", "cal_sync_status", "jarvis_ask", "jarvis_trace", "jarvis_check", "models_list", "models_card", "models_compare", "brief_read", "brief_history", "brief_status", "brief_missed", "notes_folders", "notes_list", "glossary_list", "notes_show", "notes_shelf", "notes_shelves", "notes_place", "notes_accounts", "notes_recordings", "notes_recording", "notes_sync_status", "notes_granola_status", "notes_bot_upcoming", "ops_status", "slack_coverage", "slack_connect", "slack_disconnect", "slack_read", "memory_rules", "memory_knowledge", "memory_profile", "memory_consolidation", "settings_show", "settings_list", "model_show", "team_members", "team_device_list", "scout_board", "workbook_read", "tower_search", "sources_check", "logs_digest", "brain_status"];
14
14
  /**
15
15
  * Tools that write, but answer a dry run that writes nothing. The smoke calls
16
16
  * each one ONLY with its dry-run flag set (`scripts/smoke.ts` says which).
@@ -78,6 +78,7 @@ export const READ_TOOLS = [
78
78
  "slack_disconnect",
79
79
  "slack_read",
80
80
  "memory_rules",
81
+ "memory_knowledge",
81
82
  "memory_profile",
82
83
  "memory_consolidation",
83
84
  "settings_show",
@@ -342,6 +342,7 @@ export const MCP_TWINS = {
342
342
  // BLI-4533: the compiled one-page profile. Its twin is on `bli-tower`, not
343
343
  // `bli-memory`: that server's four tools are the vendor-compatible set the
344
344
  // Claude Code plugin expects, and this page is ours.
345
+ "memory knowledge": { tool: "memory_knowledge", door: "GET /api/memory/knowledge" },
345
346
  "memory rules": { tool: "memory_rules", door: "GET /api/memory/rules" },
346
347
  "memory profile": { tool: "memory_profile", door: "GET /api/memory/profile" },
347
348
  // BLI-4534: the nightly consolidation receipts. This twin lives on
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/mcp",
3
- "version": "0.1.112",
3
+ "version": "0.1.113",
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",