@bli-cockpit/mcp 0.1.21 → 0.1.22
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/models-tools.d.ts +25 -0
- package/dist/models-tools.js +73 -0
- package/dist/server.js +5 -0
- package/dist/verb-census.js +4 -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
|
+
**76 of 79 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
|
|
@@ -81,6 +81,8 @@ three tables below.
|
|
|
81
81
|
| `cockpit memory log` | `memory_experience` | `POST /api/memory/experience` |
|
|
82
82
|
| `cockpit model set` | `model_set` | `POST /api/settings/jarvis-model` |
|
|
83
83
|
| `cockpit model show` | `model_show` | `GET /api/settings/jarvis-model` |
|
|
84
|
+
| `cockpit models list` | `models_list` | `GET /api/models/cards` |
|
|
85
|
+
| `cockpit models show` | `models_card` | `GET /api/models/cards?id=` |
|
|
84
86
|
| `cockpit msg channels` | `msg_channels` | `GET /api/msg/channels` |
|
|
85
87
|
| `cockpit msg create` | `msg_create_channel` | `POST /api/msg/channels` |
|
|
86
88
|
| `cockpit msg dm` | `msg_dm` | `POST /api/msg/channels (dm)` |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `models_list` / `models_card` (BLI-3912) — the model-card shelf, for an
|
|
3
|
+
* agent, over the same `/api/models/cards` door `cockpit models` calls.
|
|
4
|
+
*
|
|
5
|
+
* These are the twins of `cockpit models list` and `cockpit models show`. They
|
|
6
|
+
* exist because "which model should I use for this, and what will it refuse"
|
|
7
|
+
* is a question an agent asks more often than a person does: the card carries
|
|
8
|
+
* the documented window, price, reasoning modes and tool support beside our own
|
|
9
|
+
* measured latency and probe verdicts, and a `stale:<field>` mark wherever the
|
|
10
|
+
* two disagree.
|
|
11
|
+
*
|
|
12
|
+
* The LINES come from the server, so the sentence an agent reads is the sentence
|
|
13
|
+
* a person reads in a terminal. Nothing is computed here beyond counting.
|
|
14
|
+
*
|
|
15
|
+
* Not to be confused with `model_show` / `model_set` next door, which are the
|
|
16
|
+
* ORG SETTING for which model a slot runs on. This is the shelf that setting
|
|
17
|
+
* picks from, and there is deliberately no write here: a card is changed by
|
|
18
|
+
* re-reading the provider (`npm run models:card add <id> --refresh`), never by
|
|
19
|
+
* an agent editing a number.
|
|
20
|
+
*/
|
|
21
|
+
import { type ToolDeps } from "./tool-result.js";
|
|
22
|
+
export type ModelsDeps = ToolDeps;
|
|
23
|
+
export declare function registerModelsTools(server: {
|
|
24
|
+
registerTool: (...args: never[]) => unknown;
|
|
25
|
+
}, deps: ModelsDeps): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `models_list` / `models_card` (BLI-3912) — the model-card shelf, for an
|
|
3
|
+
* agent, over the same `/api/models/cards` door `cockpit models` calls.
|
|
4
|
+
*
|
|
5
|
+
* These are the twins of `cockpit models list` and `cockpit models show`. They
|
|
6
|
+
* exist because "which model should I use for this, and what will it refuse"
|
|
7
|
+
* is a question an agent asks more often than a person does: the card carries
|
|
8
|
+
* the documented window, price, reasoning modes and tool support beside our own
|
|
9
|
+
* measured latency and probe verdicts, and a `stale:<field>` mark wherever the
|
|
10
|
+
* two disagree.
|
|
11
|
+
*
|
|
12
|
+
* The LINES come from the server, so the sentence an agent reads is the sentence
|
|
13
|
+
* a person reads in a terminal. Nothing is computed here beyond counting.
|
|
14
|
+
*
|
|
15
|
+
* Not to be confused with `model_show` / `model_set` next door, which are the
|
|
16
|
+
* ORG SETTING for which model a slot runs on. This is the shelf that setting
|
|
17
|
+
* picks from, and there is deliberately no write here: a card is changed by
|
|
18
|
+
* re-reading the provider (`npm run models:card add <id> --refresh`), never by
|
|
19
|
+
* an agent editing a number.
|
|
20
|
+
*/
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
import { callAgentDoor } from "./agent-door.js";
|
|
23
|
+
import { doorFailureText, errorResult, registrarFor, textResult, queryString, withSession, } from "./tool-result.js";
|
|
24
|
+
export function registerModelsTools(server, deps) {
|
|
25
|
+
const register = registrarFor(server);
|
|
26
|
+
register("models_list", {
|
|
27
|
+
title: "List the model cards",
|
|
28
|
+
description: "Every model Tower knows about: the provider's documented context window, price per million, reasoning "
|
|
29
|
+
+ "modes and tool support, beside our measured latency, observed tokens/s and last probe verdict. "
|
|
30
|
+
+ "`STALE:<field>` means a measurement contradicted the documentation, with the command that re-reads the "
|
|
31
|
+
+ "provider. Read-only.",
|
|
32
|
+
inputSchema: {},
|
|
33
|
+
}, async () => withSession(deps, async (session) => {
|
|
34
|
+
const response = await callAgentDoor(session, deps.fetchImpl, "GET", "/api/models/cards");
|
|
35
|
+
if (!response.ok)
|
|
36
|
+
return errorResult(doorFailureText("models_list", response));
|
|
37
|
+
const body = response.body;
|
|
38
|
+
const cards = (Array.isArray(body.cards) ? body.cards : []);
|
|
39
|
+
const lines = (Array.isArray(body.lines) ? body.lines : []);
|
|
40
|
+
const stale = cards.filter((card) => (card.stale?.length ?? 0) > 0).map((card) => card.id ?? "?");
|
|
41
|
+
const unreadable = (Array.isArray(body.unreadable) ? body.unreadable : []);
|
|
42
|
+
return textResult(`${cards.length} model card(s)`
|
|
43
|
+
+ `${stale.length > 0 ? `, ${stale.length} stale: ${stale.join(", ")}` : ", none stale"}`
|
|
44
|
+
+ `${unreadable.length > 0 ? `, ${unreadable.length} unreadable: ${unreadable.join(", ")}` : ""}`
|
|
45
|
+
+ `${lines.length > 0 ? `\n${lines.join("\n")}` : ""}`, { cards, stale, unreadable });
|
|
46
|
+
}));
|
|
47
|
+
register("models_card", {
|
|
48
|
+
title: "Read one model card",
|
|
49
|
+
description: "One model in full: every documented value with the provider page it was read from, the quirks quoted "
|
|
50
|
+
+ "verbatim, our measured latency and tokens/s, each probe verdict, and any stale mark. A field the "
|
|
51
|
+
+ "provider does not state reads unknown with the reason — never a guess.",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
id: z
|
|
54
|
+
.string()
|
|
55
|
+
.min(1)
|
|
56
|
+
.max(200)
|
|
57
|
+
.describe("The card id, `provider:model` (e.g. openai:gpt-5.6-terra), or one of its aliases."),
|
|
58
|
+
},
|
|
59
|
+
}, async (args) => withSession(deps, async (session) => {
|
|
60
|
+
const params = new URLSearchParams();
|
|
61
|
+
params.set("id", String(args.id));
|
|
62
|
+
const response = await callAgentDoor(session, deps.fetchImpl, "GET", `/api/models/cards${queryString(params)}`);
|
|
63
|
+
// A 404 here is the door's own sentence naming the id and the command
|
|
64
|
+
// that would add it, which is more useful than anything this file
|
|
65
|
+
// could compose.
|
|
66
|
+
if (!response.ok)
|
|
67
|
+
return errorResult(doorFailureText("models_card", response));
|
|
68
|
+
const body = response.body;
|
|
69
|
+
const card = (body.card ?? {});
|
|
70
|
+
const lines = (Array.isArray(body.lines) ? body.lines : []);
|
|
71
|
+
return textResult(lines.join("\n") || `Model card ${card.id ?? args.id}.`, { card });
|
|
72
|
+
}));
|
|
73
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -15,6 +15,7 @@ import { registerMailTools } from "./mail-tools.js";
|
|
|
15
15
|
import { registerNotesTools } from "./notes-tools.js";
|
|
16
16
|
import { registerNotesWriteTools } from "./notes-write-tools.js";
|
|
17
17
|
import { registerMemoryExperienceTools } from "./memory-experience-tools.js";
|
|
18
|
+
import { registerModelsTools } from "./models-tools.js";
|
|
18
19
|
import { registerOpsTools } from "./ops-tools.js";
|
|
19
20
|
import { registerPagesTools } from "./pages-tools.js";
|
|
20
21
|
import { registerSearchTool } from "./search-tool.js";
|
|
@@ -404,6 +405,10 @@ export function createServer(deps) {
|
|
|
404
405
|
// as the three families above, over the doors `cockpit jarvis` already
|
|
405
406
|
// calls. It is the last Tower surface that had a CLI door and no MCP one.
|
|
406
407
|
registerJarvisTools(server, { fetchImpl: deps.fetchImpl });
|
|
408
|
+
// BLI-3912: `models_*` — the model-card shelf, over the same door
|
|
409
|
+
// `cockpit models` calls. Read-only: a card is changed by re-reading the
|
|
410
|
+
// provider, never by an agent editing a number.
|
|
411
|
+
registerModelsTools(server, { fetchImpl: deps.fetchImpl });
|
|
407
412
|
// BLI-3756 batch 1: the READS the CLI already had and this server did not —
|
|
408
413
|
// the daily page, the meeting-notes library, the ops board, Slack coverage,
|
|
409
414
|
// settings/team/model, Scout and the workbook. Same doors, same device
|
package/dist/verb-census.js
CHANGED
|
@@ -237,6 +237,10 @@ export const MCP_TWINS = {
|
|
|
237
237
|
"team device-revoke": { tool: "team_device_revoke", door: "POST /api/ambient/devices/[deviceId]/revoke" },
|
|
238
238
|
"model show": { tool: "model_show", door: "GET /api/settings/jarvis-model" },
|
|
239
239
|
"model set": { tool: "model_set", door: "POST /api/settings/jarvis-model" },
|
|
240
|
+
// BLI-3912: the model-card shelf. `models` is the shelf; `model` next door is
|
|
241
|
+
// the org setting that picks from it.
|
|
242
|
+
"models list": { tool: "models_list", door: "GET /api/models/cards" },
|
|
243
|
+
"models show": { tool: "models_card", door: "GET /api/models/cards?id=" },
|
|
240
244
|
"scout board": { tool: "scout_board", door: "GET /api/cockpit/scout" },
|
|
241
245
|
"scout start": { tool: "scout_start", door: "POST /api/cockpit/scout (start)" },
|
|
242
246
|
"scout dismiss": { tool: "scout_dismiss", door: "POST /api/cockpit/scout (dismiss)" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "bli-tower \u2014 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",
|