@cavelang/cli 0.27.14 → 0.29.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/Authors.md +5 -0
- package/License.md +6 -0
- package/README.md +122 -24
- package/dist/internal/act/action.d.ts +69 -0
- package/dist/internal/act/action.d.ts.map +1 -0
- package/dist/internal/act/action.js +201 -0
- package/dist/internal/act/action.js.map +1 -0
- package/dist/internal/act/declare.d.ts +102 -0
- package/dist/internal/act/declare.d.ts.map +1 -0
- package/dist/internal/act/declare.js +270 -0
- package/dist/internal/act/declare.js.map +1 -0
- package/dist/internal/act/engine.d.ts +103 -0
- package/dist/internal/act/engine.d.ts.map +1 -0
- package/dist/internal/act/engine.js +298 -0
- package/dist/internal/act/engine.js.map +1 -0
- package/dist/internal/act/index.d.ts +27 -0
- package/dist/internal/act/index.d.ts.map +1 -0
- package/dist/internal/act/index.js +25 -0
- package/dist/internal/act/index.js.map +1 -0
- package/dist/internal/automate/automation.d.ts +78 -0
- package/dist/internal/automate/automation.d.ts.map +1 -0
- package/dist/internal/automate/automation.js +135 -0
- package/dist/internal/automate/automation.js.map +1 -0
- package/dist/internal/automate/declare.d.ts +84 -0
- package/dist/internal/automate/declare.d.ts.map +1 -0
- package/dist/internal/automate/declare.js +233 -0
- package/dist/internal/automate/declare.js.map +1 -0
- package/dist/internal/automate/engine.d.ts +125 -0
- package/dist/internal/automate/engine.d.ts.map +1 -0
- package/dist/internal/automate/engine.js +388 -0
- package/dist/internal/automate/engine.js.map +1 -0
- package/dist/internal/automate/index.d.ts +28 -0
- package/dist/internal/automate/index.d.ts.map +1 -0
- package/dist/internal/automate/index.js +26 -0
- package/dist/internal/automate/index.js.map +1 -0
- package/dist/internal/automate/main.d.ts +26 -0
- package/dist/internal/automate/main.d.ts.map +1 -0
- package/dist/internal/automate/main.js +298 -0
- package/dist/internal/automate/main.js.map +1 -0
- package/dist/internal/connect/index.d.ts +26 -0
- package/dist/internal/connect/index.d.ts.map +1 -0
- package/dist/internal/connect/index.js +24 -0
- package/dist/internal/connect/index.js.map +1 -0
- package/dist/internal/connect/main.d.ts +23 -0
- package/dist/internal/connect/main.d.ts.map +1 -0
- package/dist/internal/connect/main.js +330 -0
- package/dist/internal/connect/main.js.map +1 -0
- package/dist/internal/connect/run.d.ts +85 -0
- package/dist/internal/connect/run.d.ts.map +1 -0
- package/dist/internal/connect/run.js +242 -0
- package/dist/internal/connect/run.js.map +1 -0
- package/dist/internal/connect/source.d.ts +44 -0
- package/dist/internal/connect/source.d.ts.map +1 -0
- package/dist/internal/connect/source.js +215 -0
- package/dist/internal/connect/source.js.map +1 -0
- package/dist/internal/connect/template.d.ts +69 -0
- package/dist/internal/connect/template.d.ts.map +1 -0
- package/dist/internal/connect/template.js +221 -0
- package/dist/internal/connect/template.js.map +1 -0
- package/dist/internal/eval/index.d.ts +28 -0
- package/dist/internal/eval/index.d.ts.map +1 -0
- package/dist/internal/eval/index.js +27 -0
- package/dist/internal/eval/index.js.map +1 -0
- package/dist/internal/eval/judge.d.ts +30 -0
- package/dist/internal/eval/judge.d.ts.map +1 -0
- package/dist/internal/eval/judge.js +101 -0
- package/dist/internal/eval/judge.js.map +1 -0
- package/dist/internal/eval/loop.d.ts +64 -0
- package/dist/internal/eval/loop.d.ts.map +1 -0
- package/dist/internal/eval/loop.js +123 -0
- package/dist/internal/eval/loop.js.map +1 -0
- package/dist/internal/eval/main.d.ts +17 -0
- package/dist/internal/eval/main.d.ts.map +1 -0
- package/dist/internal/eval/main.js +236 -0
- package/dist/internal/eval/main.js.map +1 -0
- package/dist/internal/eval/queries.d.ts +74 -0
- package/dist/internal/eval/queries.d.ts.map +1 -0
- package/dist/internal/eval/queries.js +161 -0
- package/dist/internal/eval/queries.js.map +1 -0
- package/dist/internal/eval/run.d.ts +143 -0
- package/dist/internal/eval/run.d.ts.map +1 -0
- package/dist/internal/eval/run.js +376 -0
- package/dist/internal/eval/run.js.map +1 -0
- package/dist/internal/eval/score.d.ts +81 -0
- package/dist/internal/eval/score.d.ts.map +1 -0
- package/dist/internal/eval/score.js +126 -0
- package/dist/internal/eval/score.js.map +1 -0
- package/dist/internal/eval/suite.d.ts +66 -0
- package/dist/internal/eval/suite.d.ts.map +1 -0
- package/dist/internal/eval/suite.js +130 -0
- package/dist/internal/eval/suite.js.map +1 -0
- package/dist/internal/ingest/context.d.ts +20 -0
- package/dist/internal/ingest/context.d.ts.map +1 -0
- package/dist/internal/ingest/context.js +59 -0
- package/dist/internal/ingest/context.js.map +1 -0
- package/dist/internal/ingest/files.d.ts +46 -0
- package/dist/internal/ingest/files.d.ts.map +1 -0
- package/dist/internal/ingest/files.js +115 -0
- package/dist/internal/ingest/files.js.map +1 -0
- package/dist/internal/ingest/index.d.ts +31 -0
- package/dist/internal/ingest/index.d.ts.map +1 -0
- package/dist/internal/ingest/index.js +29 -0
- package/dist/internal/ingest/index.js.map +1 -0
- package/dist/internal/ingest/main.d.ts +12 -0
- package/dist/internal/ingest/main.d.ts.map +1 -0
- package/dist/internal/ingest/main.js +180 -0
- package/dist/internal/ingest/main.js.map +1 -0
- package/dist/internal/ingest/prompt.d.ts +32 -0
- package/dist/internal/ingest/prompt.d.ts.map +1 -0
- package/dist/internal/ingest/prompt.js +75 -0
- package/dist/internal/ingest/prompt.js.map +1 -0
- package/dist/internal/ingest/run.d.ts +142 -0
- package/dist/internal/ingest/run.d.ts.map +1 -0
- package/dist/internal/ingest/run.js +350 -0
- package/dist/internal/ingest/run.js.map +1 -0
- package/dist/internal/ingest/web.d.ts +48 -0
- package/dist/internal/ingest/web.d.ts.map +1 -0
- package/dist/internal/ingest/web.js +140 -0
- package/dist/internal/ingest/web.js.map +1 -0
- package/dist/internal/loop/demo.d.ts +22 -0
- package/dist/internal/loop/demo.d.ts.map +1 -0
- package/dist/internal/loop/demo.js +67 -0
- package/dist/internal/loop/demo.js.map +1 -0
- package/dist/internal/loop/index.d.ts +20 -0
- package/dist/internal/loop/index.d.ts.map +1 -0
- package/dist/internal/loop/index.js +17 -0
- package/dist/internal/loop/index.js.map +1 -0
- package/dist/internal/loop/llm.d.ts +99 -0
- package/dist/internal/loop/llm.d.ts.map +1 -0
- package/dist/internal/loop/llm.js +231 -0
- package/dist/internal/loop/llm.js.map +1 -0
- package/dist/internal/loop/reconstruct.d.ts +87 -0
- package/dist/internal/loop/reconstruct.d.ts.map +1 -0
- package/dist/internal/loop/reconstruct.js +157 -0
- package/dist/internal/loop/reconstruct.js.map +1 -0
- package/dist/internal/loop/sqlite.d.ts +13 -0
- package/dist/internal/loop/sqlite.d.ts.map +1 -0
- package/dist/internal/loop/sqlite.js +33 -0
- package/dist/internal/loop/sqlite.js.map +1 -0
- package/dist/internal/loop/store.d.ts +50 -0
- package/dist/internal/loop/store.d.ts.map +1 -0
- package/dist/internal/loop/store.js +100 -0
- package/dist/internal/loop/store.js.map +1 -0
- package/dist/internal/mcp/bin.d.ts +7 -0
- package/dist/internal/mcp/bin.d.ts.map +1 -0
- package/dist/internal/mcp/bin.js +8 -0
- package/dist/internal/mcp/bin.js.map +1 -0
- package/dist/internal/mcp/index.d.ts +25 -0
- package/dist/internal/mcp/index.d.ts.map +1 -0
- package/dist/internal/mcp/index.js +23 -0
- package/dist/internal/mcp/index.js.map +1 -0
- package/dist/internal/mcp/main.d.ts +23 -0
- package/dist/internal/mcp/main.d.ts.map +1 -0
- package/dist/internal/mcp/main.js +156 -0
- package/dist/internal/mcp/main.js.map +1 -0
- package/dist/internal/mcp/server.d.ts +92 -0
- package/dist/internal/mcp/server.d.ts.map +1 -0
- package/dist/internal/mcp/server.js +251 -0
- package/dist/internal/mcp/server.js.map +1 -0
- package/dist/internal/mcp/tools.d.ts +91 -0
- package/dist/internal/mcp/tools.d.ts.map +1 -0
- package/dist/internal/mcp/tools.js +584 -0
- package/dist/internal/mcp/tools.js.map +1 -0
- package/dist/internal/rules/declare.d.ts +58 -0
- package/dist/internal/rules/declare.d.ts.map +1 -0
- package/dist/internal/rules/declare.js +152 -0
- package/dist/internal/rules/declare.js.map +1 -0
- package/dist/internal/rules/engine.d.ts +125 -0
- package/dist/internal/rules/engine.d.ts.map +1 -0
- package/dist/internal/rules/engine.js +575 -0
- package/dist/internal/rules/engine.js.map +1 -0
- package/dist/internal/rules/index.d.ts +23 -0
- package/dist/internal/rules/index.d.ts.map +1 -0
- package/dist/internal/rules/index.js +21 -0
- package/dist/internal/rules/index.js.map +1 -0
- package/dist/internal/rules/rule.d.ts +88 -0
- package/dist/internal/rules/rule.d.ts.map +1 -0
- package/dist/internal/rules/rule.js +221 -0
- package/dist/internal/rules/rule.js.map +1 -0
- package/dist/internal/shape/check.d.ts +118 -0
- package/dist/internal/shape/check.d.ts.map +1 -0
- package/dist/internal/shape/check.js +331 -0
- package/dist/internal/shape/check.js.map +1 -0
- package/dist/internal/shape/client.d.ts +31 -0
- package/dist/internal/shape/client.d.ts.map +1 -0
- package/dist/internal/shape/client.js +170 -0
- package/dist/internal/shape/client.js.map +1 -0
- package/dist/internal/shape/gate.d.ts +33 -0
- package/dist/internal/shape/gate.d.ts.map +1 -0
- package/dist/internal/shape/gate.js +0 -0
- package/dist/internal/shape/gate.js.map +1 -0
- package/dist/internal/shape/index.d.ts +27 -0
- package/dist/internal/shape/index.d.ts.map +1 -0
- package/dist/internal/shape/index.js +23 -0
- package/dist/internal/shape/index.js.map +1 -0
- package/dist/internal/shape/suggest.d.ts +82 -0
- package/dist/internal/shape/suggest.d.ts.map +1 -0
- package/dist/internal/shape/suggest.js +374 -0
- package/dist/internal/shape/suggest.js.map +1 -0
- package/dist/internal/sync/index.d.ts +22 -0
- package/dist/internal/sync/index.d.ts.map +1 -0
- package/dist/internal/sync/index.js +21 -0
- package/dist/internal/sync/index.js.map +1 -0
- package/dist/internal/sync/sync.d.ts +95 -0
- package/dist/internal/sync/sync.d.ts.map +1 -0
- package/dist/internal/sync/sync.js +342 -0
- package/dist/internal/sync/sync.js.map +1 -0
- package/dist/internal/view/api.d.ts +196 -0
- package/dist/internal/view/api.d.ts.map +1 -0
- package/dist/internal/view/api.js +189 -0
- package/dist/internal/view/api.js.map +1 -0
- package/dist/internal/view/index.d.ts +33 -0
- package/dist/internal/view/index.d.ts.map +1 -0
- package/dist/internal/view/index.js +30 -0
- package/dist/internal/view/index.js.map +1 -0
- package/dist/internal/view/main.d.ts +11 -0
- package/dist/internal/view/main.d.ts.map +1 -0
- package/dist/internal/view/main.js +98 -0
- package/dist/internal/view/main.js.map +1 -0
- package/dist/internal/view/page.d.ts +14 -0
- package/dist/internal/view/page.d.ts.map +1 -0
- package/dist/internal/view/page.js +370 -0
- package/dist/internal/view/page.js.map +1 -0
- package/dist/internal/view/report.d.ts +52 -0
- package/dist/internal/view/report.d.ts.map +1 -0
- package/dist/internal/view/report.js +367 -0
- package/dist/internal/view/report.js.map +1 -0
- package/dist/internal/view/scope.d.ts +11 -0
- package/dist/internal/view/scope.d.ts.map +1 -0
- package/dist/internal/view/scope.js +41 -0
- package/dist/internal/view/scope.js.map +1 -0
- package/dist/internal/view/server.d.ts +35 -0
- package/dist/internal/view/server.d.ts.map +1 -0
- package/dist/internal/view/server.js +141 -0
- package/dist/internal/view/server.js.map +1 -0
- package/dist/src/act.d.ts +3 -0
- package/dist/src/act.d.ts.map +1 -0
- package/dist/src/act.js +3 -0
- package/dist/src/act.js.map +1 -0
- package/dist/src/automate.d.ts +3 -0
- package/dist/src/automate.d.ts.map +1 -0
- package/dist/src/automate.js +3 -0
- package/dist/src/automate.js.map +1 -0
- package/dist/src/cli.d.ts +24 -17
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +408 -107
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands.d.ts +104 -0
- package/dist/src/commands.d.ts.map +1 -0
- package/dist/src/commands.js +33 -0
- package/dist/src/commands.js.map +1 -0
- package/dist/src/connect.d.ts +3 -0
- package/dist/src/connect.d.ts.map +1 -0
- package/dist/src/connect.js +3 -0
- package/dist/src/connect.js.map +1 -0
- package/dist/src/dispatch.d.ts +14 -0
- package/dist/src/dispatch.d.ts.map +1 -0
- package/dist/src/dispatch.js +116 -0
- package/dist/src/dispatch.js.map +1 -0
- package/dist/src/doctor.d.ts +45 -0
- package/dist/src/doctor.d.ts.map +1 -0
- package/dist/src/doctor.js +284 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/eval.d.ts +3 -0
- package/dist/src/eval.d.ts.map +1 -0
- package/dist/src/eval.js +3 -0
- package/dist/src/eval.js.map +1 -0
- package/dist/src/index.d.ts +9 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/ingest.d.ts +3 -0
- package/dist/src/ingest.d.ts.map +1 -0
- package/dist/src/ingest.js +3 -0
- package/dist/src/ingest.js.map +1 -0
- package/dist/src/loop.d.ts +3 -0
- package/dist/src/loop.d.ts.map +1 -0
- package/dist/src/loop.js +3 -0
- package/dist/src/loop.js.map +1 -0
- package/dist/src/main.d.ts +1 -1
- package/dist/src/main.d.ts.map +1 -1
- package/dist/src/main.js +3 -75
- package/dist/src/main.js.map +1 -1
- package/dist/src/mcp.d.ts +3 -0
- package/dist/src/mcp.d.ts.map +1 -0
- package/dist/src/mcp.js +3 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/rules.d.ts +3 -0
- package/dist/src/rules.d.ts.map +1 -0
- package/dist/src/rules.js +3 -0
- package/dist/src/rules.js.map +1 -0
- package/dist/src/shape.d.ts +3 -0
- package/dist/src/shape.d.ts.map +1 -0
- package/dist/src/shape.js +3 -0
- package/dist/src/shape.js.map +1 -0
- package/dist/src/sync.d.ts +3 -0
- package/dist/src/sync.d.ts.map +1 -0
- package/dist/src/sync.js +3 -0
- package/dist/src/sync.js.map +1 -0
- package/dist/src/view.d.ts +3 -0
- package/dist/src/view.d.ts.map +1 -0
- package/dist/src/view.js +3 -0
- package/dist/src/view.js.map +1 -0
- package/package.json +81 -21
- package/src/act.ts +2 -0
- package/src/automate.ts +2 -0
- package/src/cli.ts +416 -102
- package/src/commands.ts +48 -0
- package/src/connect.ts +2 -0
- package/src/dispatch.ts +141 -0
- package/src/doctor.ts +370 -0
- package/src/eval.ts +2 -0
- package/src/index.ts +9 -2
- package/src/ingest.ts +2 -0
- package/src/loop.ts +2 -0
- package/src/main.ts +3 -66
- package/src/mcp.ts +2 -0
- package/src/rules.ts +2 -0
- package/src/shape.ts +2 -0
- package/src/sync.ts +2 -0
- package/src/view.ts +2 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cave mcp` entry — opens the knowledge database and serves MCP on stdio
|
|
3
|
+
* until the client disconnects. Everything written to stdout is protocol;
|
|
4
|
+
* the startup banner goes to stderr.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
import { parseArgs } from 'node:util';
|
|
8
|
+
import { Registry } from '@cavelang/canonical';
|
|
9
|
+
import { defaultDbPath, open } from '@cavelang/store';
|
|
10
|
+
import { serve, serverInfo } from "./server.js";
|
|
11
|
+
import { scopedTools } from "./tools.js";
|
|
12
|
+
export const usage = `cave mcp — serve a CAVE knowledge database as an MCP server on stdio
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
cave mcp [--db <path>] [--no-prelude] [--read-only]
|
|
16
|
+
[--permissions <list>] [--tools <list>]
|
|
17
|
+
[--src <context>] [--no-src] [--hooks <file>]
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
--db <path> database file (default: $CAVE_DB, or cave.db)
|
|
21
|
+
--no-prelude open the store without the standard verb registry
|
|
22
|
+
--read-only serve only tools that never write (drops cave_add,
|
|
23
|
+
cave_derive and the generated act_<name> action tools)
|
|
24
|
+
--permissions serve only operation classes from read,evaluate,record,
|
|
25
|
+
action (comma-separated); evaluation is ephemeral,
|
|
26
|
+
recording is durable, and action may execute effects
|
|
27
|
+
--tools <list> serve only these tools (comma-separated); --read-only
|
|
28
|
+
still drops writing tools from the list; act_<name>
|
|
29
|
+
entries scope whichever actions exist at call time
|
|
30
|
+
--src <context> provenance stamp for appends, without the src: prefix
|
|
31
|
+
(default: agent/<client-name> from the MCP handshake)
|
|
32
|
+
--no-src do not stamp actor provenance on appends
|
|
33
|
+
--hooks <file> JSON file of out-of-band hook command templates for
|
|
34
|
+
action tools, name → shell template (spec §25.4);
|
|
35
|
+
default: $CAVE_HOOKS
|
|
36
|
+
|
|
37
|
+
Appended claims that carry no @src: context are stamped with the
|
|
38
|
+
connected client's source context (spec §9.5). Actions declared in the
|
|
39
|
+
store are served as generated act_<name> tools (spec §25.5) — the
|
|
40
|
+
governed write vocabulary — recomputed per tools/list. Tools outside the
|
|
41
|
+
served scope are absent from tools/list and unknown to tools/call. Runs
|
|
42
|
+
until the client disconnects; stdout is protocol, diagnostics go to
|
|
43
|
+
stderr.
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
cave mcp --db k.db
|
|
47
|
+
cave mcp --db k.db --read-only
|
|
48
|
+
cave mcp --db k.db --permissions read,evaluate
|
|
49
|
+
cave mcp --db k.db --permissions action --tools act_mark-deployed
|
|
50
|
+
cave mcp --db k.db --tools cave_query,cave_about,cave_search
|
|
51
|
+
cave mcp --db k.db --tools cave_query,act_mark-deployed
|
|
52
|
+
cave mcp --db k.db --hooks hooks.json
|
|
53
|
+
cave mcp --db k.db --src pipeline/nightly
|
|
54
|
+
claude mcp add cave -- cave mcp --db k.db`;
|
|
55
|
+
/**
|
|
56
|
+
* Loads a hooks configuration file (spec §25.4): a JSON object mapping
|
|
57
|
+
* hook names to shell command templates. Throws on anything else — a
|
|
58
|
+
* misconfigured side-effect surface must not come up at all.
|
|
59
|
+
*/
|
|
60
|
+
export const readHooks = (path) => {
|
|
61
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
62
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed) ||
|
|
63
|
+
Object.values(parsed).some(value => typeof value !== 'string')) {
|
|
64
|
+
throw new Error(`${path}: hooks must be a JSON object of name → shell template strings`);
|
|
65
|
+
}
|
|
66
|
+
return parsed;
|
|
67
|
+
};
|
|
68
|
+
/** Validates the single accepted `--src` spelling: a non-empty context token without `src:`. */
|
|
69
|
+
export const sourceFromOption = (value) => {
|
|
70
|
+
if (value === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
if (!/^[A-Za-z0-9._/:-]+$/.test(value)) {
|
|
73
|
+
throw new Error('--src must be a context token (letters, digits, . _ / : -)');
|
|
74
|
+
}
|
|
75
|
+
if (value.startsWith('src:')) {
|
|
76
|
+
throw new Error('--src must not include the src: prefix');
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
};
|
|
80
|
+
/** Runs the server; resolves with the process exit code. */
|
|
81
|
+
export const runMcp = async (argv, context = {}) => {
|
|
82
|
+
const stdin = context.stdin ?? process.stdin;
|
|
83
|
+
const stdout = context.stdout ?? process.stdout;
|
|
84
|
+
const stderr = context.stderr ?? process.stderr;
|
|
85
|
+
const { values } = parseArgs({
|
|
86
|
+
args: [...argv],
|
|
87
|
+
options: {
|
|
88
|
+
db: { type: 'string' },
|
|
89
|
+
'no-prelude': { type: 'boolean' },
|
|
90
|
+
'read-only': { type: 'boolean' },
|
|
91
|
+
permissions: { type: 'string' },
|
|
92
|
+
tools: { type: 'string' },
|
|
93
|
+
src: { type: 'string' },
|
|
94
|
+
'no-src': { type: 'boolean' },
|
|
95
|
+
hooks: { type: 'string' },
|
|
96
|
+
help: { type: 'boolean', short: 'h' }
|
|
97
|
+
},
|
|
98
|
+
allowPositionals: false
|
|
99
|
+
});
|
|
100
|
+
if (values.help === true) {
|
|
101
|
+
stdout.write(`${usage}\n`);
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
let sourceOverride;
|
|
105
|
+
try {
|
|
106
|
+
sourceOverride = sourceFromOption(values.src);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
stderr.write(`cave mcp: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
110
|
+
return 2;
|
|
111
|
+
}
|
|
112
|
+
const scope = {
|
|
113
|
+
...values['read-only'] === true ? { readOnly: true } : {},
|
|
114
|
+
...values.permissions === undefined ? {} : {
|
|
115
|
+
permissions: values.permissions.split(',').map(name => name.trim()).filter(name => name !== '')
|
|
116
|
+
},
|
|
117
|
+
...values.tools === undefined ? {} : {
|
|
118
|
+
tools: values.tools.split(',').map(name => name.trim()).filter(name => name !== '')
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
let hooks;
|
|
122
|
+
try {
|
|
123
|
+
// Validate the scope and hook configuration before touching the
|
|
124
|
+
// database or the protocol — a misconfigured permission boundary or
|
|
125
|
+
// side-effect surface must not come up at all.
|
|
126
|
+
scopedTools(scope);
|
|
127
|
+
const hooksPath = values.hooks ?? process.env['CAVE_HOOKS'];
|
|
128
|
+
hooks = hooksPath === undefined ? undefined : readHooks(hooksPath);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
stderr.write(`cave mcp: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
132
|
+
return 2;
|
|
133
|
+
}
|
|
134
|
+
const db = values.db ?? defaultDbPath();
|
|
135
|
+
const store = open(db, values['no-prelude'] === true ? { registry: Registry.empty } : {});
|
|
136
|
+
const scopeNote = [
|
|
137
|
+
...values['read-only'] === true ? ['read-only'] : [],
|
|
138
|
+
...scope.permissions === undefined ? [] : [`permissions ${scope.permissions.join(',')}`],
|
|
139
|
+
...scope.tools === undefined ? [] : [`tools ${scopedTools(scope).map(tool => tool.name).join(',')}`]
|
|
140
|
+
];
|
|
141
|
+
stderr.write(`${serverInfo.name} mcp server ${serverInfo.version} — db ${db}` +
|
|
142
|
+
`${scopeNote.length > 0 ? ` (${scopeNote.join('; ')})` : ''}\n`);
|
|
143
|
+
try {
|
|
144
|
+
await serve(store, stdin, stdout, {
|
|
145
|
+
...scope,
|
|
146
|
+
...values['no-src'] === true ? { source: false } : sourceOverride === undefined ? {} : { source: sourceOverride },
|
|
147
|
+
...hooks === undefined ? {} : { hooks },
|
|
148
|
+
...context.signal === undefined ? {} : { signal: context.signal }
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
store.close();
|
|
153
|
+
}
|
|
154
|
+
return 0;
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server over stdio — newline-delimited JSON-RPC 2.0.
|
|
3
|
+
*
|
|
4
|
+
* Implements the slice of the Model Context Protocol a tools-only server
|
|
5
|
+
* needs: `initialize` / `notifications/initialized`, `ping`, `tools/list`
|
|
6
|
+
* and `tools/call`. The dispatcher is a pure function from message to
|
|
7
|
+
* optional response, so it is testable without a process or a socket;
|
|
8
|
+
* `serve` wires it to stdin/stdout.
|
|
9
|
+
*
|
|
10
|
+
* Hand-rolled rather than pulling in an SDK: the protocol surface here is
|
|
11
|
+
* ~150 lines, the repo is otherwise dependency-free beyond
|
|
12
|
+
* `@prelude/parser`, and `@prelude/jsonrpc` targets WebSocket-style
|
|
13
|
+
* transports with numeric-only ids (MCP ids may be strings).
|
|
14
|
+
*/
|
|
15
|
+
import type { Store } from '@cavelang/store';
|
|
16
|
+
import { type Scope, type Tool } from './tools.ts';
|
|
17
|
+
export type ServerOptions = Scope & {
|
|
18
|
+
/**
|
|
19
|
+
* Actor provenance stamp for appends (spec §9.5), without the `src:`
|
|
20
|
+
* prefix. Default: `agent/<client-name>` from the initialize handshake,
|
|
21
|
+
* plain `agent` before or without one. `false` disables stamping.
|
|
22
|
+
*/
|
|
23
|
+
readonly source?: string | false;
|
|
24
|
+
/** Out-of-band hook command templates for action tools (spec §25.4). */
|
|
25
|
+
readonly hooks?: Readonly<Record<string, string>>;
|
|
26
|
+
/** Stop accepting protocol input and resolve after the current message. */
|
|
27
|
+
readonly signal?: AbortSignal;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* @returns `agent/<name>` source context from an MCP client name —
|
|
31
|
+
* lowercased, whitespace to `-`, restricted to context-safe characters;
|
|
32
|
+
* plain `agent` when no usable name is known (spec §9.5).
|
|
33
|
+
*/
|
|
34
|
+
export declare const agentSource: (clientName: undefined | string) => string;
|
|
35
|
+
/** The single MCP protocol revision this server implements. */
|
|
36
|
+
export declare const protocolVersion = "2025-06-18";
|
|
37
|
+
export declare const serverInfo: {
|
|
38
|
+
readonly name: "cave";
|
|
39
|
+
readonly version: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The spec §22 compact card — tool-agnostic CAVE writing knowledge,
|
|
43
|
+
* shared with `@cavelang/cli/ingest` prompts.
|
|
44
|
+
*/
|
|
45
|
+
export declare const specCard = "CAVE (Compressed Atomic Verb Expressions) persists knowledge as atomic claims:\n\n subject VERB [NOT] object [@context...] [#tag[:value]...] [@ N%] [!] [; comment]\n subject HAS attribute: value [+/- delta] [@context...] [#tag[:value]...] [@ N%] [!] [; comment]\n\nExamples:\n auth/middleware USES jwt @ 90%\n OpenAI HAS revenue: ~20B USD/yr +/- 2B USD/yr @2026-Q1\n server IS NOT compromised @ 90%\n memory-leak CAUSE app/crash @ 70% #topic:stability\n\nVerbs are UPPERCASE (IS, HAS, CAUSE, FIX, NEEDS, USES, YIELDS, ENABLES, BLOCKS,\nCONTAINS, PRECEDES, EXTENDS, ALIAS, LIKE, EXISTS, VS, BECOMES, EXCEEDS,\nIS-BELOW, IS-AT-LEAST, IS-AT-MOST, EQUALS, DIFFERS-FROM).\nEntities are kebab-case with / for scope (auth/middleware). @ctx = context\n(no space), @ 90% = confidence (space). Storage is append-only: update belief\nby adding the same claim with new confidence; retract with @ 0%.";
|
|
46
|
+
/**
|
|
47
|
+
* Server instructions for a served tool surface — the card plus tool
|
|
48
|
+
* guidance mentioning only tools actually served, so a connected model is
|
|
49
|
+
* never pointed at a tool the scope hides. A surface with no writing tool
|
|
50
|
+
* says so outright. `actions` marks a scope that (also) serves generated
|
|
51
|
+
* action tools (spec §25.5) — a write surface even when no static tool
|
|
52
|
+
* writes.
|
|
53
|
+
*/
|
|
54
|
+
export declare const instructionsFor: (served: readonly Tool[], options?: {
|
|
55
|
+
actions?: boolean;
|
|
56
|
+
}) => string;
|
|
57
|
+
/**
|
|
58
|
+
* Server instructions for the full default surface — every static tool
|
|
59
|
+
* plus generated action tools (spec §25.5) — so a connected model knows
|
|
60
|
+
* how to write CAVE without reading the full specification.
|
|
61
|
+
*/
|
|
62
|
+
export declare const instructions: string;
|
|
63
|
+
type Id = null | string | number;
|
|
64
|
+
type Response = {
|
|
65
|
+
jsonrpc: '2.0';
|
|
66
|
+
id: null | Id;
|
|
67
|
+
result?: unknown;
|
|
68
|
+
error?: {
|
|
69
|
+
code: number;
|
|
70
|
+
message: string;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
type Reply = Response | Response[];
|
|
74
|
+
/**
|
|
75
|
+
* @returns pure MCP dispatcher over an open store: message in, response
|
|
76
|
+
* out (`undefined` for notifications). The client name captured from
|
|
77
|
+
* `initialize` becomes the default `agent/<name>` provenance stamp on
|
|
78
|
+
* appends (spec §9.5). Serves the scoped tool surface — tools outside the
|
|
79
|
+
* scope are absent from `tools/list` and unknown to `tools/call`; throws
|
|
80
|
+
* when the scope names an unknown tool or serves none.
|
|
81
|
+
*/
|
|
82
|
+
export declare const createServer: (store: Store, options?: ServerOptions) => {
|
|
83
|
+
handle: (message: unknown) => undefined | Reply;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Serves MCP over newline-delimited JSON-RPC on the given streams until
|
|
87
|
+
* the input closes. Protocol traffic only on `output` — logs belong on
|
|
88
|
+
* stderr.
|
|
89
|
+
*/
|
|
90
|
+
export declare const serve: (store: Store, input: NodeJS.ReadableStream, output: NodeJS.WritableStream, options?: ServerOptions) => Promise<void>;
|
|
91
|
+
export {};
|
|
92
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAuE,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAEvH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG;IAClC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAChC,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACjD,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,YAAY,SAAS,GAAG,MAAM,KAAG,MAO5D,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,eAAe,eAAe,CAAA;AAE3C,eAAO,MAAM,UAAU;;;CAGb,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,QAAQ,i5BAgB4C,CAAA;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,IAAI,EAAE,EAAE,UAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,KAAG,MAiC9F,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAA4C,CAAA;AAErE,KAAK,EAAE,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;AAShC,KAAK,QAAQ,GAAG;IACd,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,EAAE,IAAI,GAAG,EAAE,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1C,CAAA;AAWD,KAAK,KAAK,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAA;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,EAAE,UAAS,aAAkB;sBAyF3C,OAAO,KAAG,SAAS,GAAG,KAAK;CAUrD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAChB,OAAO,KAAK,EACZ,OAAO,MAAM,CAAC,cAAc,EAC5B,QAAQ,MAAM,CAAC,cAAc,EAC7B,UAAS,aAAkB,KAC1B,OAAO,CAAC,IAAI,CA8Bd,CAAA"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server over stdio — newline-delimited JSON-RPC 2.0.
|
|
3
|
+
*
|
|
4
|
+
* Implements the slice of the Model Context Protocol a tools-only server
|
|
5
|
+
* needs: `initialize` / `notifications/initialized`, `ping`, `tools/list`
|
|
6
|
+
* and `tools/call`. The dispatcher is a pure function from message to
|
|
7
|
+
* optional response, so it is testable without a process or a socket;
|
|
8
|
+
* `serve` wires it to stdin/stdout.
|
|
9
|
+
*
|
|
10
|
+
* Hand-rolled rather than pulling in an SDK: the protocol surface here is
|
|
11
|
+
* ~150 lines, the repo is otherwise dependency-free beyond
|
|
12
|
+
* `@prelude/parser`, and `@prelude/jsonrpc` targets WebSocket-style
|
|
13
|
+
* transports with numeric-only ids (MCP ids may be strings).
|
|
14
|
+
*/
|
|
15
|
+
import { createInterface } from 'node:readline';
|
|
16
|
+
import { Version } from '@cavelang/core';
|
|
17
|
+
import { actToolPrefix, allowsActions, scopedActionTools, scopedTools, tools } from "./tools.js";
|
|
18
|
+
/**
|
|
19
|
+
* @returns `agent/<name>` source context from an MCP client name —
|
|
20
|
+
* lowercased, whitespace to `-`, restricted to context-safe characters;
|
|
21
|
+
* plain `agent` when no usable name is known (spec §9.5).
|
|
22
|
+
*/
|
|
23
|
+
export const agentSource = (clientName) => {
|
|
24
|
+
const name = (clientName ?? '')
|
|
25
|
+
.trim()
|
|
26
|
+
.toLowerCase()
|
|
27
|
+
.replace(/\s+/g, '-')
|
|
28
|
+
.replace(/[^a-z0-9._/-]/g, '');
|
|
29
|
+
return name === '' ? 'agent' : `agent/${name}`;
|
|
30
|
+
};
|
|
31
|
+
/** The single MCP protocol revision this server implements. */
|
|
32
|
+
export const protocolVersion = '2025-06-18';
|
|
33
|
+
export const serverInfo = {
|
|
34
|
+
name: 'cave',
|
|
35
|
+
version: Version.current()
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The spec §22 compact card — tool-agnostic CAVE writing knowledge,
|
|
39
|
+
* shared with `@cavelang/cli/ingest` prompts.
|
|
40
|
+
*/
|
|
41
|
+
export const specCard = `CAVE (Compressed Atomic Verb Expressions) persists knowledge as atomic claims:
|
|
42
|
+
|
|
43
|
+
subject VERB [NOT] object [@context...] [#tag[:value]...] [@ N%] [!] [; comment]
|
|
44
|
+
subject HAS attribute: value [+/- delta] [@context...] [#tag[:value]...] [@ N%] [!] [; comment]
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
auth/middleware USES jwt @ 90%
|
|
48
|
+
OpenAI HAS revenue: ~20B USD/yr +/- 2B USD/yr @2026-Q1
|
|
49
|
+
server IS NOT compromised @ 90%
|
|
50
|
+
memory-leak CAUSE app/crash @ 70% #topic:stability
|
|
51
|
+
|
|
52
|
+
Verbs are UPPERCASE (IS, HAS, CAUSE, FIX, NEEDS, USES, YIELDS, ENABLES, BLOCKS,
|
|
53
|
+
CONTAINS, PRECEDES, EXTENDS, ALIAS, LIKE, EXISTS, VS, BECOMES, EXCEEDS,
|
|
54
|
+
IS-BELOW, IS-AT-LEAST, IS-AT-MOST, EQUALS, DIFFERS-FROM).
|
|
55
|
+
Entities are kebab-case with / for scope (auth/middleware). @ctx = context
|
|
56
|
+
(no space), @ 90% = confidence (space). Storage is append-only: update belief
|
|
57
|
+
by adding the same claim with new confidence; retract with @ 0%.`;
|
|
58
|
+
/**
|
|
59
|
+
* Server instructions for a served tool surface — the card plus tool
|
|
60
|
+
* guidance mentioning only tools actually served, so a connected model is
|
|
61
|
+
* never pointed at a tool the scope hides. A surface with no writing tool
|
|
62
|
+
* says so outright. `actions` marks a scope that (also) serves generated
|
|
63
|
+
* action tools (spec §25.5) — a write surface even when no static tool
|
|
64
|
+
* writes.
|
|
65
|
+
*/
|
|
66
|
+
export const instructionsFor = (served, options = {}) => {
|
|
67
|
+
const has = (name) => served.some(tool => tool.name === name);
|
|
68
|
+
const explore = ['cave_about', 'cave_neighbors'].filter(has);
|
|
69
|
+
const clauses = [
|
|
70
|
+
...has('cave_add') ?
|
|
71
|
+
[`extract knowledge with one claim per line via cave_add${has('cave_lint') ? ' (validate with cave_lint first)' : ''}`] :
|
|
72
|
+
has('cave_lint') ? ['validate CAVE text with cave_lint'] : [],
|
|
73
|
+
...has('cave_query') ? ['ask questions with cave_query patterns (?x USES jwt)'] : [],
|
|
74
|
+
...has('cave_fuse') ? ['delegate combining numeric estimates to cave_fuse (Bayesian fusion) instead of averaging in tokens'] : [],
|
|
75
|
+
...explore.length > 0 ? [`explore with ${explore.join(' / ')}`] : [],
|
|
76
|
+
...has('cave_reconstruct') ? ['use cave_reconstruct to pull everything related to a symptom or task before reasoning about it'] : [],
|
|
77
|
+
...has('cave_derive') ? ['fire the stored rules with cave_derive so derived knowledge materializes with lineage'] : []
|
|
78
|
+
];
|
|
79
|
+
const last = clauses.length - 1;
|
|
80
|
+
const guidance = [
|
|
81
|
+
...clauses.length === 0 ? [] : [clauses
|
|
82
|
+
.map((clause, index) => index === 0 ? `${clause[0].toUpperCase()}${clause.slice(1)}` : index === last ? `and ${clause}` : clause)
|
|
83
|
+
.join(',\n') + '.'],
|
|
84
|
+
...has('cave_add') ? [
|
|
85
|
+
'Claims you add without a @src: context are stamped with your agent source\n' +
|
|
86
|
+
'context; to update or retract a claim that carries a different @src:,\n' +
|
|
87
|
+
'restate it with that exact context.'
|
|
88
|
+
] : [],
|
|
89
|
+
...options.actions === true ? [
|
|
90
|
+
'Actions declared in the knowledge database are served as act_<name>\n' +
|
|
91
|
+
'tools (spec §25) — a governed write vocabulary: parameters validated,\n' +
|
|
92
|
+
'preconditions checked against current belief, effects appended\n' +
|
|
93
|
+
`atomically with provenance. Prefer them over ${has('cave_add') ? 'cave_add' : 'freeform appends'} when one fits.`
|
|
94
|
+
] : [],
|
|
95
|
+
...(served.some(tool => tool.permission === 'record' || tool.permission === 'action') || options.actions === true ?
|
|
96
|
+
[] : ['This server is read-only: no tool writes to the knowledge database.'])
|
|
97
|
+
].join('\n');
|
|
98
|
+
return guidance === '' ? specCard : `${specCard}\n\n${guidance}`;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Server instructions for the full default surface — every static tool
|
|
102
|
+
* plus generated action tools (spec §25.5) — so a connected model knows
|
|
103
|
+
* how to write CAVE without reading the full specification.
|
|
104
|
+
*/
|
|
105
|
+
export const instructions = instructionsFor(tools, { actions: true });
|
|
106
|
+
const result = (id, value) => ({ jsonrpc: '2.0', id, result: value });
|
|
107
|
+
const failure = (id, code, message) => ({ jsonrpc: '2.0', id, error: { code, message } });
|
|
108
|
+
const isId = (value) => value === null || typeof value === 'string' || typeof value === 'number';
|
|
109
|
+
/**
|
|
110
|
+
* @returns pure MCP dispatcher over an open store: message in, response
|
|
111
|
+
* out (`undefined` for notifications). The client name captured from
|
|
112
|
+
* `initialize` becomes the default `agent/<name>` provenance stamp on
|
|
113
|
+
* appends (spec §9.5). Serves the scoped tool surface — tools outside the
|
|
114
|
+
* scope are absent from `tools/list` and unknown to `tools/call`; throws
|
|
115
|
+
* when the scope names an unknown tool or serves none.
|
|
116
|
+
*/
|
|
117
|
+
export const createServer = (store, options = {}) => {
|
|
118
|
+
const served = scopedTools(options);
|
|
119
|
+
const servedByName = new Map(served.map(tool => [tool.name, tool]));
|
|
120
|
+
// Action tools are generated from the store's current declarations per
|
|
121
|
+
// request (spec §25.5) — an action declared mid-session appears in the
|
|
122
|
+
// next tools/list without reconnecting.
|
|
123
|
+
const actionsPossible = allowsActions(options);
|
|
124
|
+
const actServed = () => actionsPossible ? scopedActionTools(store, options) : [];
|
|
125
|
+
const servedInstructions = instructionsFor(served, { actions: actionsPossible });
|
|
126
|
+
let clientName;
|
|
127
|
+
const source = () => options.source === false ? undefined : options.source ?? agentSource(clientName);
|
|
128
|
+
const dispatch = (message) => {
|
|
129
|
+
if (typeof message !== 'object' || message === null || Array.isArray(message)) {
|
|
130
|
+
return failure(null, -32600, 'Invalid request');
|
|
131
|
+
}
|
|
132
|
+
const { jsonrpc, id, method, params } = message;
|
|
133
|
+
const hasId = Object.hasOwn(message, 'id');
|
|
134
|
+
if (jsonrpc !== '2.0' || typeof method !== 'string' || (hasId && !isId(id))) {
|
|
135
|
+
return failure(isId(id) ? id : null, -32600, 'Invalid request');
|
|
136
|
+
}
|
|
137
|
+
if (!hasId) {
|
|
138
|
+
// Notifications (notifications/initialized, notifications/cancelled, …)
|
|
139
|
+
// require no response.
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
const requestId = id;
|
|
143
|
+
switch (method) {
|
|
144
|
+
case 'initialize': {
|
|
145
|
+
const requested = params?.protocolVersion;
|
|
146
|
+
if (requested !== protocolVersion) {
|
|
147
|
+
return failure(requestId, -32602, `Unsupported protocol version: ${String(requested)}; supported: ${protocolVersion}`);
|
|
148
|
+
}
|
|
149
|
+
const name = params?.clientInfo?.name;
|
|
150
|
+
if (typeof name === 'string') {
|
|
151
|
+
clientName = name;
|
|
152
|
+
}
|
|
153
|
+
return result(requestId, {
|
|
154
|
+
protocolVersion,
|
|
155
|
+
capabilities: { tools: {} },
|
|
156
|
+
serverInfo,
|
|
157
|
+
instructions: servedInstructions
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
case 'ping':
|
|
161
|
+
return result(requestId, {});
|
|
162
|
+
case 'tools/list':
|
|
163
|
+
return result(requestId, {
|
|
164
|
+
tools: [...served, ...actServed()].map(tool => ({
|
|
165
|
+
name: tool.name,
|
|
166
|
+
description: tool.description,
|
|
167
|
+
inputSchema: tool.inputSchema,
|
|
168
|
+
...(tool.permission === 'record' || tool.permission === 'action' ?
|
|
169
|
+
{} : { annotations: { readOnlyHint: true } })
|
|
170
|
+
}))
|
|
171
|
+
});
|
|
172
|
+
case 'tools/call': {
|
|
173
|
+
const call = (params ?? {});
|
|
174
|
+
const tool = typeof call.name === 'string' ?
|
|
175
|
+
servedByName.get(call.name) ??
|
|
176
|
+
(call.name.startsWith(actToolPrefix) ? actServed().find(candidate => candidate.name === call.name) : undefined) :
|
|
177
|
+
undefined;
|
|
178
|
+
if (tool === undefined) {
|
|
179
|
+
return failure(requestId, -32602, `Unknown tool: ${String(call.name)}`);
|
|
180
|
+
}
|
|
181
|
+
const args = typeof call.arguments === 'object' && call.arguments !== null ?
|
|
182
|
+
call.arguments :
|
|
183
|
+
{};
|
|
184
|
+
try {
|
|
185
|
+
const stamp = source();
|
|
186
|
+
const text = tool.run(store, args, {
|
|
187
|
+
...stamp === undefined ? {} : { source: stamp },
|
|
188
|
+
...options.hooks === undefined ? {} : { hooks: options.hooks }
|
|
189
|
+
});
|
|
190
|
+
return result(requestId, { content: [{ type: 'text', text }] });
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
194
|
+
return result(requestId, { content: [{ type: 'text', text }], isError: true });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
default:
|
|
198
|
+
return failure(requestId, -32601, `Method not found: ${method}`);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const handle = (message) => {
|
|
202
|
+
if (!Array.isArray(message))
|
|
203
|
+
return dispatch(message);
|
|
204
|
+
if (message.length === 0)
|
|
205
|
+
return failure(null, -32600, 'Invalid request');
|
|
206
|
+
const responses = message.flatMap(item => {
|
|
207
|
+
const response = dispatch(item);
|
|
208
|
+
return response === undefined ? [] : [response];
|
|
209
|
+
});
|
|
210
|
+
return responses.length === 0 ? undefined : responses;
|
|
211
|
+
};
|
|
212
|
+
return { handle };
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Serves MCP over newline-delimited JSON-RPC on the given streams until
|
|
216
|
+
* the input closes. Protocol traffic only on `output` — logs belong on
|
|
217
|
+
* stderr.
|
|
218
|
+
*/
|
|
219
|
+
export const serve = (store, input, output, options = {}) => {
|
|
220
|
+
const server = createServer(store, options);
|
|
221
|
+
return new Promise(resolve => {
|
|
222
|
+
const lines = createInterface({ input });
|
|
223
|
+
const abort = () => lines.close();
|
|
224
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
225
|
+
lines.on('line', line => {
|
|
226
|
+
if (line.trim() === '') {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
let message;
|
|
230
|
+
try {
|
|
231
|
+
message = JSON.parse(line);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
output.write(`${JSON.stringify(failure(null, -32700, 'Parse error'))}\n`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const response = server.handle(message);
|
|
238
|
+
if (response !== undefined) {
|
|
239
|
+
output.write(`${JSON.stringify(response)}\n`);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
lines.on('close', () => {
|
|
243
|
+
options.signal?.removeEventListener('abort', abort);
|
|
244
|
+
resolve();
|
|
245
|
+
});
|
|
246
|
+
if (options.signal?.aborted === true) {
|
|
247
|
+
lines.close();
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CAVE engine surface exposed as MCP tools, all operating on one open
|
|
3
|
+
* `@cavelang/store` database:
|
|
4
|
+
*
|
|
5
|
+
* | Tool | Purpose |
|
|
6
|
+
* |---|---|
|
|
7
|
+
* | `cave_add` | append CAVE text (extraction output) to the store |
|
|
8
|
+
* | `cave_query` | run a CAVE-Q pattern (spec §12) |
|
|
9
|
+
* | `cave_fuse` | Bayesian fusion of numeric estimates (§10.1) — named computation |
|
|
10
|
+
* | `cave_search` | full-text search over claims and comments |
|
|
11
|
+
* | `cave_about` | current claims about an entity, both directions |
|
|
12
|
+
* | `cave_neighbors` | named forward + inverse edges of an entity (§13.3) |
|
|
13
|
+
* | `cave_reconstruct` | cave-loop active reconstruction from seed cues (§18) |
|
|
14
|
+
* | `cave_derive` | fire the stored rules (§24) — named computation |
|
|
15
|
+
* | `cave_export` | canonical CAVE text of the store |
|
|
16
|
+
* | `cave_lint` | parse text and report diagnostics without storing |
|
|
17
|
+
*
|
|
18
|
+
* Results are text — canonical CAVE lines wherever claims are returned,
|
|
19
|
+
* because that is the notation the client model is instructed with.
|
|
20
|
+
*
|
|
21
|
+
* Every tool declares its permission class; `scopedTools` narrows the
|
|
22
|
+
* served surface to a `Scope` (`--read-only`, `--permissions`, `--tools`) —
|
|
23
|
+
* the minimum viable agent permission boundary.
|
|
24
|
+
*/
|
|
25
|
+
import type { Store } from '@cavelang/store';
|
|
26
|
+
/** Per-connection state the server threads into tool calls. */
|
|
27
|
+
export type ToolContext = {
|
|
28
|
+
/**
|
|
29
|
+
* Actor provenance stamp for appends (spec §9.5), without the `src:`
|
|
30
|
+
* prefix — e.g. `agent/claude-code`. `undefined` disables stamping.
|
|
31
|
+
*/
|
|
32
|
+
readonly source?: string;
|
|
33
|
+
/** Out-of-band hook command templates for action tools (spec §25.4). */
|
|
34
|
+
readonly hooks?: Readonly<Record<string, string>>;
|
|
35
|
+
};
|
|
36
|
+
export declare const permissions: readonly ["read", "evaluate", "record", "action"];
|
|
37
|
+
export type Permission = typeof permissions[number];
|
|
38
|
+
export type Tool = {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly description: string;
|
|
41
|
+
/** Evaluation is ephemeral, recording is durable, and action may cause effects. */
|
|
42
|
+
readonly permission: Permission;
|
|
43
|
+
readonly inputSchema: object;
|
|
44
|
+
readonly run: (store: Store, args: Record<string, unknown>, context: ToolContext) => string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Serving scope — which tools the server exposes (the minimum viable
|
|
48
|
+
* agent permission boundary). Tools outside the scope are absent from
|
|
49
|
+
* `tools/list` and indistinguishable from nonexistent in `tools/call`.
|
|
50
|
+
*/
|
|
51
|
+
export type Scope = {
|
|
52
|
+
/** Serve only tools that never write to the store (drops `cave_add`). */
|
|
53
|
+
readonly readOnly?: boolean;
|
|
54
|
+
/** Serve only these operation classes; `readOnly` removes record/action. */
|
|
55
|
+
readonly permissions?: readonly Permission[];
|
|
56
|
+
/**
|
|
57
|
+
* Serve only these tools, by name. `readOnly` narrows further: a
|
|
58
|
+
* writing tool listed here is still not served.
|
|
59
|
+
*/
|
|
60
|
+
readonly tools?: readonly string[];
|
|
61
|
+
};
|
|
62
|
+
export declare const tools: readonly Tool[];
|
|
63
|
+
export declare const byName: ReadonlyMap<string, Tool>;
|
|
64
|
+
/** Tool-name prefix of generated action tools (spec §25.5). */
|
|
65
|
+
export declare const actToolPrefix = "act_";
|
|
66
|
+
/**
|
|
67
|
+
* MCP tool name of an action: `act_` plus the action name with
|
|
68
|
+
* characters outside the MCP tool alphabet mapped to `_`
|
|
69
|
+
* (`team/promote` → `act_team_promote`).
|
|
70
|
+
*/
|
|
71
|
+
export declare const actToolName: (action: string) => string;
|
|
72
|
+
/**
|
|
73
|
+
* @returns the generated action tools of the store's current positive
|
|
74
|
+
* declarations (spec §25.5), computed per call so an action declared
|
|
75
|
+
* mid-session appears without reconnecting. Actions whose stored body
|
|
76
|
+
* does not parse are skipped, as are name collisions after MCP-alphabet
|
|
77
|
+
* mapping (first declaration wins).
|
|
78
|
+
*/
|
|
79
|
+
export declare const actionTools: (store: Store) => Tool[];
|
|
80
|
+
export declare const allowsActions: (scope?: Scope) => boolean;
|
|
81
|
+
export declare const scopedActionTools: (store: Store, scope?: Scope) => Tool[];
|
|
82
|
+
/**
|
|
83
|
+
* @returns the static tool surface actually served under a scope: `tools`
|
|
84
|
+
* (when given) narrowed by permission and by `readOnly`. Throws on
|
|
85
|
+
* names that exist nowhere and on a scope that serves nothing — a
|
|
86
|
+
* misconfigured permission boundary must fail loudly, not serve quietly.
|
|
87
|
+
* `act_`-prefixed names pass through: they scope generated action tools
|
|
88
|
+
* (spec §25.5), resolved against the store at call time.
|
|
89
|
+
*/
|
|
90
|
+
export declare const scopedTools: (scope?: Scope) => readonly Tool[];
|
|
91
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAO5C,+DAA+D;AAC/D,MAAM,MAAM,WAAW,GAAG;IACxB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAClD,CAAA;AAED,eAAO,MAAM,WAAW,mDAAoD,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC,MAAM,CAAC,CAAA;AAEnD,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,WAAW,KAAK,MAAM,CAAA;CAC5F,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC5C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC,CAAA;AA6GD,eAAO,MAAM,KAAK,EAAE,SAAS,IAAI,EA6UhC,CAAA;AAED,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CACE,CAAA;AAE/C,+DAA+D;AAC/D,eAAO,MAAM,aAAa,SAAS,CAAA;AAEnC;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,MACmB,CAAA;AAkDhE;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,IAAI,EAY9C,CAAA;AAiBD,eAAO,MAAM,aAAa,GAAI,QAAO,KAAU,KAAG,OAEuC,CAAA;AAEzF,eAAO,MAAM,iBAAiB,GAAI,OAAO,KAAK,EAAE,QAAO,KAAU,KAAG,IAAI,EAGlE,CAAA;AAEN;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,QAAO,KAAU,KAAG,SAAS,IAAI,EAkB5D,CAAA"}
|