@nonbot/mcp 0.2.2 → 0.2.3
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
|
@@ -205,6 +205,14 @@ The supervisor surface: what the daemon and the fleet are doing, plus the three
|
|
|
205
205
|
| `run_snapshot_request` | Ask the operator's daemon to capture the last lines of a RUNNING run's terminal pane (secrets scrubbed, 16KB tail cap, stored server-side for 5 minutes only). | write | `runs:control` |
|
|
206
206
|
| `run_prompt_answer` | Answer a mid-run prompt on the operator's behalf — the daemon types the answer into the live pane. | destructive | `runs:respond` (explicit; a wildcard token does not satisfy it) |
|
|
207
207
|
| `run_stop_daemon` | The panic button — queue a remote shutdown for the operator's daemon (CLI ≥0.9.12). | destructive | `runs:control` |
|
|
208
|
+
|
|
209
|
+
### radBUGS (1)
|
|
210
|
+
|
|
211
|
+
File a bug straight into the radBUGS inbox, stamped as filed from MCP.
|
|
212
|
+
|
|
213
|
+
| Tool | What it does | Kind | PAT scope |
|
|
214
|
+
|---|---|---|---|
|
|
215
|
+
| `radbug_file` | File a bug report into the non.bot radBUGS inbox, stamped as filed from MCP. | write | `radbugs:write` |
|
|
208
216
|
<!-- tool-table:end -->
|
|
209
217
|
|
|
210
218
|
**Kind** is the tool's MCP annotation: *read* tools never change anything; *destructive* tools are confirm-gated (`portfolio_update` on large removals, `run_prompt_answer`, `run_stop_daemon`). `NON_BOT_MCP_READONLY=1` drops every non-read tool.
|
|
@@ -234,7 +242,7 @@ Safety rails on writes: `portfolio_update` pre-fetches the live version, backs t
|
|
|
234
242
|
- `core/http.ts` — token-bound fetch wrapper
|
|
235
243
|
- `core/validate.ts` — pre-flight graph validation
|
|
236
244
|
- `core/server.ts` — `registerAll(server, ctx)` (the transport-agnostic heart) + `createNonbotMcpServer(ctx)`
|
|
237
|
-
- `core/toolsets/{portfolio,whygraph,run,monitor,ip}.ts`, `core/resources.ts`, `core/prompts.ts`
|
|
245
|
+
- `core/toolsets/{portfolio,whygraph,run,monitor,ip,radbugs}.ts`, `core/resources.ts`, `core/prompts.ts`
|
|
238
246
|
- `src/stdio.ts` — the `nonbot-mcp` bin: env/CLI-auth token + filesystem backup hook
|
|
239
247
|
- `scripts/gen-tool-table.mjs` — prints the tool tables above from the live definitions (`--portfolio-mcp` does the same for the legacy server)
|
|
240
248
|
|
package/dist/core/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { ApiContext } from './config.js';
|
|
3
3
|
export declare const SERVER_NAME = "nonbot-mcp";
|
|
4
|
-
export declare const SERVER_VERSION = "0.2.
|
|
4
|
+
export declare const SERVER_VERSION = "0.2.3";
|
|
5
5
|
export declare const INSTRUCTIONS: string;
|
|
6
6
|
export declare function registerAll(server: McpServer, ctx: ApiContext): void;
|
|
7
7
|
export declare function createNonbotMcpServer(ctx: ApiContext): McpServer;
|
package/dist/core/server.js
CHANGED
|
@@ -5,10 +5,11 @@ import { registerBuildTools } from './toolsets/build.js';
|
|
|
5
5
|
import { registerWhygraphTools } from './toolsets/whygraph.js';
|
|
6
6
|
import { registerRunTools } from './toolsets/run.js';
|
|
7
7
|
import { registerMonitorTools } from './toolsets/monitor.js';
|
|
8
|
+
import { registerRadbugsTools } from './toolsets/radbugs.js';
|
|
8
9
|
import { registerResources } from './resources.js';
|
|
9
10
|
import { registerPrompts } from './prompts.js';
|
|
10
11
|
export const SERVER_NAME = 'nonbot-mcp';
|
|
11
|
-
export const SERVER_VERSION = '0.2.
|
|
12
|
+
export const SERVER_VERSION = '0.2.3';
|
|
12
13
|
export const INSTRUCTIONS = [
|
|
13
14
|
'non.bot MCP — work against the caller’s real product-management data, not a copy.',
|
|
14
15
|
'Two domains: PORTFOLIOS (the SAFe portfolio canvas — epics → features → stories) and',
|
|
@@ -28,6 +29,7 @@ export const INSTRUCTIONS = [
|
|
|
28
29
|
'tokens with the explicit runs:respond scope only).',
|
|
29
30
|
'IP NODES: ip_list / ip_get read a patent or trademark disclosure; ip_update edits it (op list + expected_version);',
|
|
30
31
|
'ip_evidence_add adds evidence the SERVER hashes, timestamps and numbers — never send a hash or a time.',
|
|
32
|
+
'RADBUGS: radbug_file files a bug into the non.bot radBUGS inbox (needs the radbugs:write scope).',
|
|
31
33
|
].join(' ');
|
|
32
34
|
export function registerAll(server, ctx) {
|
|
33
35
|
registerPortfolioTools(server, ctx);
|
|
@@ -36,6 +38,7 @@ export function registerAll(server, ctx) {
|
|
|
36
38
|
registerWhygraphTools(server, ctx);
|
|
37
39
|
registerRunTools(server, ctx);
|
|
38
40
|
registerMonitorTools(server, ctx);
|
|
41
|
+
registerRadbugsTools(server, ctx);
|
|
39
42
|
registerResources(server, ctx);
|
|
40
43
|
registerPrompts(server, ctx);
|
|
41
44
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { api, expectJson } from '../http.js';
|
|
3
|
+
const SCOPE_MESSAGE = 'This token needs the radbugs:write scope (or the account needs radBUGS access).';
|
|
4
|
+
async function forbiddenText(res) {
|
|
5
|
+
let reason = '';
|
|
6
|
+
try {
|
|
7
|
+
const j = (await res.json());
|
|
8
|
+
const m = j && typeof j === 'object' ? (j.message ?? j.error) : undefined;
|
|
9
|
+
if (typeof m === 'string' && m.trim())
|
|
10
|
+
reason = m.trim().slice(0, 300);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
}
|
|
14
|
+
return reason ? `${SCOPE_MESSAGE} Server said: ${reason}` : SCOPE_MESSAGE;
|
|
15
|
+
}
|
|
16
|
+
function textResult(data) {
|
|
17
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
18
|
+
}
|
|
19
|
+
export function registerRadbugsTools(server, ctx) {
|
|
20
|
+
if (ctx.readonly)
|
|
21
|
+
return;
|
|
22
|
+
server.registerTool('radbug_file', {
|
|
23
|
+
title: 'File a radBUG',
|
|
24
|
+
description: 'File a bug report into the non.bot radBUGS inbox, stamped as filed from MCP. Give a short title; add a description (steps, expected vs actual), the product area, a priority, and the page URL when known. Returns the created inbox item. Requires the radbugs:write scope and an account with radBUGS access.',
|
|
25
|
+
inputSchema: {
|
|
26
|
+
title: z.string().min(1).max(500).describe('Short summary of the bug.'),
|
|
27
|
+
description: z.string().max(20000).optional().describe('Steps to reproduce, expected vs actual, context.'),
|
|
28
|
+
area: z.string().max(80).optional().describe('Product area, e.g. "portfolio" or "radmeeting".'),
|
|
29
|
+
priority: z.enum(['low', 'med', 'high']).optional().describe('How urgent it is.'),
|
|
30
|
+
page_url: z.string().max(2048).optional().describe('The page the bug was seen on.'),
|
|
31
|
+
},
|
|
32
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true },
|
|
33
|
+
}, async (a) => {
|
|
34
|
+
const body = { title: a.title };
|
|
35
|
+
if (a.description !== undefined)
|
|
36
|
+
body.description = a.description;
|
|
37
|
+
if (a.area !== undefined)
|
|
38
|
+
body.area = a.area;
|
|
39
|
+
if (a.priority !== undefined)
|
|
40
|
+
body.priority = a.priority;
|
|
41
|
+
if (a.page_url !== undefined)
|
|
42
|
+
body.page_url = a.page_url;
|
|
43
|
+
body.client = 'mcp';
|
|
44
|
+
const res = await api(ctx, '/api/admin/radbugs', { method: 'POST', body: JSON.stringify(body) });
|
|
45
|
+
if (res.status === 403) {
|
|
46
|
+
return { content: [{ type: 'text', text: await forbiddenText(res) }], isError: true };
|
|
47
|
+
}
|
|
48
|
+
return textResult(await expectJson(res, 'POST /api/admin/radbugs'));
|
|
49
|
+
});
|
|
50
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nonbot/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The non.bot MCP server — one server for your portfolios, decision graph, and Runs. Runs over stdio (Claude Code, Cursor, VS Code) with a pat_ token. Built on MCP protocol 2025-11-25.",
|
|
6
6
|
"keywords": [
|