@disusered/okf-cli 1.4.0 → 2.1.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.
Files changed (50) hide show
  1. package/README.md +63 -0
  2. package/dist/bin.js +17 -10
  3. package/dist/bin.js.map +1 -1
  4. package/dist/generate.d.ts.map +1 -1
  5. package/dist/generate.js +9 -1
  6. package/dist/generate.js.map +1 -1
  7. package/dist/help.d.ts +1 -1
  8. package/dist/help.d.ts.map +1 -1
  9. package/dist/help.js +3 -0
  10. package/dist/help.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +13 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/mcp/arguments.d.ts +32 -0
  16. package/dist/mcp/arguments.d.ts.map +1 -0
  17. package/dist/mcp/arguments.js +132 -0
  18. package/dist/mcp/arguments.js.map +1 -0
  19. package/dist/mcp/bundle.d.ts +22 -0
  20. package/dist/mcp/bundle.d.ts.map +1 -0
  21. package/dist/mcp/bundle.js +36 -0
  22. package/dist/mcp/bundle.js.map +1 -0
  23. package/dist/mcp/help.d.ts +2 -0
  24. package/dist/mcp/help.d.ts.map +1 -0
  25. package/dist/mcp/help.js +36 -0
  26. package/dist/mcp/help.js.map +1 -0
  27. package/dist/mcp/http.d.ts +34 -0
  28. package/dist/mcp/http.d.ts.map +1 -0
  29. package/dist/mcp/http.js +132 -0
  30. package/dist/mcp/http.js.map +1 -0
  31. package/dist/mcp/index.d.ts +8 -0
  32. package/dist/mcp/index.d.ts.map +1 -0
  33. package/dist/mcp/index.js +8 -0
  34. package/dist/mcp/index.js.map +1 -0
  35. package/dist/mcp/operations.d.ts +23 -0
  36. package/dist/mcp/operations.d.ts.map +1 -0
  37. package/dist/mcp/operations.js +117 -0
  38. package/dist/mcp/operations.js.map +1 -0
  39. package/dist/mcp/serve.d.ts +3 -0
  40. package/dist/mcp/serve.d.ts.map +1 -0
  41. package/dist/mcp/serve.js +66 -0
  42. package/dist/mcp/serve.js.map +1 -0
  43. package/dist/mcp/server.d.ts +42 -0
  44. package/dist/mcp/server.d.ts.map +1 -0
  45. package/dist/mcp/server.js +51 -0
  46. package/dist/mcp/server.js.map +1 -0
  47. package/dist/page/script.d.ts.map +1 -1
  48. package/dist/page/script.js +50 -1
  49. package/dist/page/script.js.map +1 -1
  50. package/package.json +8 -6
@@ -0,0 +1,36 @@
1
+ import { OKF_V1_MCP_PATH } from "okf-contracts";
2
+ import { DEFAULT_HTTP_PORT, LOOPBACK_HOST } from "./arguments.js";
3
+ import { HEALTH_PATH } from "./http.js";
4
+ export const HELP = `okf mcp — serve one filesystem OKF bundle over MCP
5
+
6
+ Usage:
7
+ okf mcp <project-root> --bundle NAME [options]
8
+
9
+ Options:
10
+ --bundle NAME The manifest bundle to serve. Always required.
11
+ --profile-module PATH Trusted validation profile module, resolved against the
12
+ project root. It must export \`profile\`.
13
+ --today YYYY-MM-DD Date staleness is judged against. Never defaulted.
14
+ --http Serve loopback HTTP instead of stdio.
15
+ --port N HTTP port (default ${String(DEFAULT_HTTP_PORT)}). Requires --http.
16
+ --allowed-host HOST Accept HOST as the Host a tunnel or reverse proxy
17
+ forwards. Repeatable. Requires --http.
18
+ -h, --help Print this help.
19
+
20
+ Identity (what a client shows and a model reads first):
21
+ --name NAME Server name (default okf-<bundle>).
22
+ --title TEXT Human-readable title.
23
+ --description TEXT One or two sentences on what the server holds.
24
+ --website URL Where a person can learn more.
25
+ --icon URL Icon a client may show beside the server.
26
+ --purpose TEXT One sentence that opens the server instructions.
27
+
28
+ In stdio mode standard output carries protocol traffic only; diagnostics go to
29
+ standard error.
30
+
31
+ With --http the server binds ${LOOPBACK_HOST} only and serves ${OKF_V1_MCP_PATH}, plus
32
+ GET ${HEALTH_PATH}. It refuses any Host or Origin that is neither localhost nor an
33
+ --allowed-host. Publishing a loopback server is the job of the tunnel or proxy in
34
+ front of it, which also authenticates every caller.
35
+ `;
36
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/mcp/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;+CAW2B,MAAM,CAAC,iBAAiB,CAAC;;;;;;;;;;;;;;;;+BAgBzC,aAAa,oBAAoB,eAAe;MACzE,WAAW;;;CAGhB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type Server } from "node:http";
2
+ import { type McpServerFactory } from "@modelcontextprotocol/server";
3
+ export interface ServeHttpOptions {
4
+ /** 0 asks the operating system for an ephemeral port; the handle reports what it got. */
5
+ readonly port: number;
6
+ /**
7
+ * Public hostnames a tunnel or reverse proxy forwards to this loopback listener. Each is
8
+ * accepted as the hostname of `Host` and of `Origin`. Authentication for those names
9
+ * belongs to the proxy in front; this listener stays on loopback either way.
10
+ */
11
+ readonly allowedHosts?: readonly string[];
12
+ /** Named in `/healthz`. */
13
+ readonly service?: string;
14
+ readonly version?: string;
15
+ readonly onerror?: (error: Error) => void;
16
+ }
17
+ /** The liveness route. It reads nothing from the Bundle and needs no MCP session. */
18
+ export declare const HEALTH_PATH = "/healthz";
19
+ export interface HttpServerHandle {
20
+ readonly server: Server;
21
+ readonly port: number;
22
+ /** The exact endpoint to configure a client with. */
23
+ readonly url: string;
24
+ close(): Promise<void>;
25
+ }
26
+ /**
27
+ * Serve the MCP surface over loopback HTTP.
28
+ *
29
+ * The listener binds {@link LOOPBACK_HOST} only, and every request is checked against the
30
+ * localhost `Host` and `Origin` allowlists before it reaches the handler: a local server that
31
+ * reads a private corpus must not become reachable from a page the browser happens to load.
32
+ */
33
+ export declare function serveHttp(factory: McpServerFactory, options: ServeHttpOptions): Promise<HttpServerHandle>;
34
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/mcp/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAGjG,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,2BAA2B;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C;AAED,qFAAqF;AACrF,eAAO,MAAM,WAAW,aAAa,CAAC;AAEtC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAoDD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAgE3B"}
@@ -0,0 +1,132 @@
1
+ import { createServer } from "node:http";
2
+ import { createMcpHandler, hostHeaderValidationResponse, localhostAllowedHostnames, localhostAllowedOrigins, originValidationResponse, } from "@modelcontextprotocol/server";
3
+ import { OKF_V1_MCP_PATH } from "okf-contracts";
4
+ import { LOOPBACK_HOST } from "./arguments.js";
5
+ /** The liveness route. It reads nothing from the Bundle and needs no MCP session. */
6
+ export const HEALTH_PATH = "/healthz";
7
+ /** The exact bytes, so nothing here has to assume the request body is UTF-8 text. */
8
+ async function readBody(message) {
9
+ const chunks = [];
10
+ for await (const chunk of message) {
11
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
12
+ }
13
+ const merged = Buffer.concat(chunks);
14
+ return merged.buffer.slice(merged.byteOffset, merged.byteOffset + merged.byteLength);
15
+ }
16
+ function toRequest(message, body, port) {
17
+ const host = message.headers.host ?? `${LOOPBACK_HOST}:${String(port)}`;
18
+ const url = new URL(message.url ?? "/", `http://${host}`);
19
+ const headers = new Headers();
20
+ for (const [name, value] of Object.entries(message.headers)) {
21
+ if (value === undefined)
22
+ continue;
23
+ if (Array.isArray(value))
24
+ for (const item of value)
25
+ headers.append(name, item);
26
+ else
27
+ headers.set(name, value);
28
+ }
29
+ const method = message.method ?? "GET";
30
+ const hasBody = method !== "GET" && method !== "HEAD";
31
+ return new Request(url, { method, headers, ...(hasBody ? { body } : {}) });
32
+ }
33
+ async function send(response, target) {
34
+ const headers = {};
35
+ for (const [name, value] of response.headers)
36
+ headers[name] = value;
37
+ target.writeHead(response.status, headers);
38
+ if (response.body === null) {
39
+ target.end();
40
+ return;
41
+ }
42
+ // Streamed so a `text/event-stream` exchange reaches the client as it is produced rather
43
+ // than at the end of the response. A client that hangs up mid-stream cancels the reader,
44
+ // so the handler stops producing instead of writing into a dead socket.
45
+ const reader = response.body.getReader();
46
+ const cancel = () => { void reader.cancel(); };
47
+ target.once("close", cancel);
48
+ try {
49
+ while (!target.writableEnded) {
50
+ const { done, value } = await reader.read();
51
+ if (done)
52
+ break;
53
+ target.write(value);
54
+ }
55
+ }
56
+ finally {
57
+ target.removeListener("close", cancel);
58
+ }
59
+ target.end();
60
+ }
61
+ /**
62
+ * Serve the MCP surface over loopback HTTP.
63
+ *
64
+ * The listener binds {@link LOOPBACK_HOST} only, and every request is checked against the
65
+ * localhost `Host` and `Origin` allowlists before it reaches the handler: a local server that
66
+ * reads a private corpus must not become reachable from a page the browser happens to load.
67
+ */
68
+ export async function serveHttp(factory, options) {
69
+ const handler = createMcpHandler(factory, {
70
+ ...(options.onerror === undefined ? {} : { onerror: options.onerror }),
71
+ });
72
+ // Both allowlists hold hostnames: the SDK compares the hostname of `Host` and of `Origin`.
73
+ const forwarded = (options.allowedHosts ?? []).map((host) => host.replace(/:\d+$/, ""));
74
+ const allowedHosts = [...localhostAllowedHostnames(), ...forwarded];
75
+ const allowedOrigins = [...localhostAllowedOrigins(), ...forwarded];
76
+ const health = JSON.stringify({
77
+ status: "ok",
78
+ ...(options.service === undefined ? {} : { service: options.service }),
79
+ ...(options.version === undefined ? {} : { version: options.version }),
80
+ });
81
+ const server = createServer((message, target) => {
82
+ void (async () => {
83
+ try {
84
+ const body = await readBody(message);
85
+ const port = server.address()?.port ?? options.port;
86
+ const request = toRequest(message, body, port);
87
+ const refused = hostHeaderValidationResponse(request, allowedHosts)
88
+ ?? originValidationResponse(request, allowedOrigins);
89
+ if (refused) {
90
+ await send(refused, target);
91
+ return;
92
+ }
93
+ const { pathname } = new URL(request.url);
94
+ if (pathname === HEALTH_PATH && request.method === "GET") {
95
+ target.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" }).end(health);
96
+ return;
97
+ }
98
+ if (pathname !== OKF_V1_MCP_PATH) {
99
+ target.writeHead(404).end();
100
+ return;
101
+ }
102
+ await send(await handler.fetch(request), target);
103
+ }
104
+ catch (error) {
105
+ options.onerror?.(error instanceof Error ? error : new Error(String(error)));
106
+ if (!target.headersSent)
107
+ target.writeHead(500);
108
+ target.end();
109
+ }
110
+ })();
111
+ });
112
+ await new Promise((resolve, reject) => {
113
+ server.once("error", reject);
114
+ server.listen(options.port, LOOPBACK_HOST, () => {
115
+ server.removeListener("error", reject);
116
+ resolve();
117
+ });
118
+ });
119
+ const port = server.address().port;
120
+ return {
121
+ server,
122
+ port,
123
+ url: `http://${LOOPBACK_HOST}:${String(port)}${OKF_V1_MCP_PATH}`,
124
+ async close() {
125
+ await handler.close();
126
+ await new Promise((resolve, reject) => {
127
+ server.close((error) => (error ? reject(error) : resolve()));
128
+ });
129
+ },
130
+ };
131
+ }
132
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/mcp/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { DEFAULT_HTTP_PORT, LOOPBACK_HOST, parseServerArguments as parseMcpArguments, type ServerArguments as McpServerArguments, } from "./arguments.js";
2
+ export { bundleSettings, type BundleAccess, type BundleSettings } from "./bundle.js";
3
+ export { HELP as MCP_HELP } from "./help.js";
4
+ export { HEALTH_PATH, serveHttp, type HttpServerHandle, type ServeHttpOptions } from "./http.js";
5
+ export { runMcp } from "./serve.js";
6
+ export { createFilesystemOkfV1Operations, ReadOnlyBundleError, type FilesystemOkfV1OperationsOptions, } from "./operations.js";
7
+ export { createOkfLocalServer, SERVER_VERSION, type OkfLocalServer, type OkfLocalServerOptions, } from "./server.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,oBAAoB,IAAI,iBAAiB,EACzC,KAAK,eAAe,IAAI,kBAAkB,GAC3C,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,KAAK,gCAAgC,GACtC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { DEFAULT_HTTP_PORT, LOOPBACK_HOST, parseServerArguments as parseMcpArguments, } from "./arguments.js";
2
+ export { bundleSettings } from "./bundle.js";
3
+ export { HELP as MCP_HELP } from "./help.js";
4
+ export { HEALTH_PATH, serveHttp } from "./http.js";
5
+ export { runMcp } from "./serve.js";
6
+ export { createFilesystemOkfV1Operations, ReadOnlyBundleError, } from "./operations.js";
7
+ export { createOkfLocalServer, SERVER_VERSION, } from "./server.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,oBAAoB,IAAI,iBAAiB,GAE1C,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAA0C,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAgD,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,GAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,cAAc,GAGf,MAAM,aAAa,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type AnalyzeBundleOptions } from "okf-core";
2
+ import type { OkfV1Operations } from "okf-contracts";
3
+ import { type ResolvedBundleTarget } from "okf-node";
4
+ import type { BundleSettings } from "./bundle.js";
5
+ /** A writing operation reached a bundle whose manifest declares `access: read`. */
6
+ export declare class ReadOnlyBundleError extends Error {
7
+ readonly code = "OKF_BUNDLE_READ_ONLY";
8
+ constructor(bundle: string, operation: string);
9
+ }
10
+ export interface FilesystemOkfV1OperationsOptions {
11
+ readonly target: ResolvedBundleTarget;
12
+ readonly settings: BundleSettings;
13
+ readonly analysis?: AnalyzeBundleOptions;
14
+ /**
15
+ * Where `okf_v1_visualize` writes the generated page. A local client opens a file, not a
16
+ * URL served by this process, so the page has to land somewhere on disk. Defaults to a
17
+ * per-process temporary directory created on the first call.
18
+ */
19
+ readonly visualizationDirectory?: string;
20
+ }
21
+ /** Create all versioned MCP operations for one filesystem bundle. */
22
+ export declare function createFilesystemOkfV1Operations(options: FilesystemOkfV1OperationsOptions): OkfV1Operations;
23
+ //# sourceMappingURL=operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/mcp/operations.ts"],"names":[],"mappings":"AAMA,OAAO,EAA6E,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChI,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,mFAAmF;AACnF,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,0BAA0B;IAEvC,YAAY,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAG5C;CACF;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAMD,qEAAqE;AACrE,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,eAAe,CAgGjB"}
@@ -0,0 +1,117 @@
1
+ import { mkdtemp, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import { generateBundleIndexes, selectBundleIndex, listBundleEntries, searchBundle } from "okf-core";
6
+ import { applyChange, previewChange, readBundleContext, } from "okf-node";
7
+ import { generateVisualization } from "../generate.js";
8
+ /** A writing operation reached a bundle whose manifest declares `access: read`. */
9
+ export class ReadOnlyBundleError extends Error {
10
+ code = "OKF_BUNDLE_READ_ONLY";
11
+ constructor(bundle, operation) {
12
+ super(`bundle ${bundle} declares access: read; ${operation} is not available`);
13
+ this.name = "ReadOnlyBundleError";
14
+ }
15
+ }
16
+ function isNotFound(error) {
17
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
18
+ }
19
+ /** Create all versioned MCP operations for one filesystem bundle. */
20
+ export function createFilesystemOkfV1Operations(options) {
21
+ const bundle = options.settings.name;
22
+ // `FilesystemBundle.analyze` walks the root itself and threads what it finds that is not a
23
+ // document, so a contract path naming a query or an attester script still resolves.
24
+ const analyze = () => options.target.bundle.analyze(options.analysis ?? {});
25
+ let visualizationDirectory = options.visualizationDirectory;
26
+ const visualizationTarget = async () => {
27
+ visualizationDirectory ??= await mkdtemp(path.join(tmpdir(), "okf-mcp-viz-"));
28
+ return path.join(visualizationDirectory, `${bundle}.html`);
29
+ };
30
+ const writable = (operation) => {
31
+ if (options.settings.access === "read") {
32
+ throw new ReadOnlyBundleError(bundle, operation);
33
+ }
34
+ };
35
+ return {
36
+ async index({ path: requested }) {
37
+ return { bundle, ...selectBundleIndex(generateBundleIndexes(await analyze()), requested) };
38
+ },
39
+ async context() {
40
+ let index = null;
41
+ try {
42
+ index = await options.target.bundle.readDocument(options.settings.index);
43
+ }
44
+ catch (error) {
45
+ if (!isNotFound(error))
46
+ throw error;
47
+ }
48
+ return {
49
+ adapter: options.settings.adapter,
50
+ bundle,
51
+ audience: options.settings.audience,
52
+ access: options.settings.access,
53
+ instructions: await readBundleContext(options.target),
54
+ index,
55
+ navigation: selectBundleIndex(generateBundleIndexes(await analyze())),
56
+ };
57
+ },
58
+ async list({ path: requested, depth }) {
59
+ const paths = await options.target.bundle.listPaths();
60
+ return { bundle, path: requested, entries: listBundleEntries(paths, requested, depth) };
61
+ },
62
+ async search({ query, limit }) {
63
+ return { bundle, query, ...searchBundle(await analyze(), query, limit) };
64
+ },
65
+ async read({ path: requested }) {
66
+ return { bundle, ...await options.target.bundle.readDocument(requested) };
67
+ },
68
+ async links({ path: requested }) {
69
+ const analysis = await analyze();
70
+ const document = analysis.documents.find((entry) => entry.path === requested);
71
+ if (!document)
72
+ throw new Error(`path does not exist in bundle ${bundle}: ${requested}`);
73
+ const backlinks = analysis.documents.flatMap((entry) => entry.links
74
+ .filter((link) => link.resolvedPath === requested && entry.path !== requested)
75
+ .map((link) => ({ path: entry.path, href: link.href })));
76
+ return { bundle, path: requested, outgoing: document.links, backlinks };
77
+ },
78
+ async validate() {
79
+ const analysis = await analyze();
80
+ const diagnostics = [
81
+ ...analysis.diagnostics.core,
82
+ ...analysis.diagnostics.guidance,
83
+ ...analysis.diagnostics.profile,
84
+ ];
85
+ return {
86
+ bundle,
87
+ passed: diagnostics.every((diagnostic) => diagnostic.severity !== "error"),
88
+ diagnostics: analysis.diagnostics,
89
+ summary: analysis.summary,
90
+ };
91
+ },
92
+ async inspect() {
93
+ return { ...await analyze() };
94
+ },
95
+ async visualize() {
96
+ const analysis = await analyze();
97
+ const output = await visualizationTarget();
98
+ await writeFile(output, generateVisualization({
99
+ bundle,
100
+ analysis,
101
+ // The same explicit date the analysis used, or nothing. Never the system clock, or
102
+ // the page stops being reproducible from the bundle.
103
+ evaluatedAt: options.analysis?.today ?? null,
104
+ }), "utf8");
105
+ return { bundle, url: pathToFileURL(output).href, path: output };
106
+ },
107
+ async previewChange(change) {
108
+ writable("okf_v1_preview_change");
109
+ return previewChange(options.target.bundle, change, options.analysis ?? {});
110
+ },
111
+ async applyChange(request) {
112
+ writable("okf_v1_apply_change");
113
+ return applyChange(options.target.bundle, request, options.analysis ?? {});
114
+ },
115
+ };
116
+ }
117
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/mcp/operations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** `okf mcp`: serve one filesystem bundle over stdio, or loopback HTTP with `--http`. */
2
+ export declare function runMcp(argv: readonly string[]): Promise<number>;
3
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/mcp/serve.ts"],"names":[],"mappings":"AAeA,yFAAyF;AACzF,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDrE"}
@@ -0,0 +1,66 @@
1
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
2
+ import { parseServerArguments } from "./arguments.js";
3
+ import { HELP } from "./help.js";
4
+ import { serveHttp } from "./http.js";
5
+ import { createOkfLocalServer } from "./server.js";
6
+ /**
7
+ * Diagnostics never touch standard output. In stdio mode that stream is the protocol, and
8
+ * one stray line of prose ends the session.
9
+ */
10
+ function note(message) {
11
+ process.stderr.write(`okf mcp: ${message}\n`);
12
+ }
13
+ /** `okf mcp`: serve one filesystem bundle over stdio, or loopback HTTP with `--http`. */
14
+ export async function runMcp(argv) {
15
+ let arguments_;
16
+ try {
17
+ arguments_ = parseServerArguments(argv);
18
+ }
19
+ catch (error) {
20
+ note(error instanceof Error ? error.message : String(error));
21
+ return 2;
22
+ }
23
+ if (arguments_.help) {
24
+ process.stdout.write(HELP);
25
+ return 0;
26
+ }
27
+ let local;
28
+ try {
29
+ local = await createOkfLocalServer({
30
+ projectRoot: arguments_.projectRoot,
31
+ bundle: arguments_.bundle,
32
+ ...(arguments_.profileModule === undefined ? {} : { profileModule: arguments_.profileModule }),
33
+ ...(arguments_.today === undefined ? {} : { today: arguments_.today }),
34
+ ...(arguments_.name === undefined ? {} : { name: arguments_.name }),
35
+ identity: {
36
+ ...(arguments_.title === undefined ? {} : { title: arguments_.title }),
37
+ ...(arguments_.description === undefined ? {} : { description: arguments_.description }),
38
+ ...(arguments_.website === undefined ? {} : { websiteUrl: arguments_.website }),
39
+ ...(arguments_.icon === undefined ? {} : { icons: [{ src: arguments_.icon }] }),
40
+ ...(arguments_.purpose === undefined ? {} : { purpose: arguments_.purpose }),
41
+ },
42
+ cwd: process.cwd(),
43
+ });
44
+ }
45
+ catch (error) {
46
+ note(error instanceof Error ? error.message : String(error));
47
+ return 2;
48
+ }
49
+ const factory = () => local.createServer();
50
+ const served = `bundle ${local.settings.name} (${local.settings.access}) from ${local.target.bundle.root}`;
51
+ if (arguments_.http) {
52
+ const handle = await serveHttp(factory, {
53
+ port: arguments_.port,
54
+ allowedHosts: arguments_.allowedHosts,
55
+ service: arguments_.name ?? `okf-${local.settings.name}`,
56
+ onerror: (error) => note(error.message),
57
+ });
58
+ note(`serving ${served} at ${handle.url}`);
59
+ }
60
+ else {
61
+ serveStdio(factory, { onerror: (error) => note(error.message) });
62
+ note(`serving ${served} over stdio`);
63
+ }
64
+ return 0;
65
+ }
66
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/mcp/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { McpServer } from "@modelcontextprotocol/server";
2
+ import { type OkfV1Operations, type OkfV1ServerIdentity } from "okf-contracts";
3
+ import { type ResolvedBundleTarget } from "okf-node";
4
+ import { type BundleSettings } from "./bundle.js";
5
+ /**
6
+ * The version this server reports to a client. It is a constant rather than a read of
7
+ * `package.json`, which does not sit under `rootDir`; `test/version.test.ts` keeps the two
8
+ * from drifting.
9
+ */
10
+ export declare const SERVER_VERSION = "2.1.0";
11
+ export interface OkfLocalServerOptions {
12
+ /** Absolute or relative project root. Relative paths resolve against `cwd`. */
13
+ readonly projectRoot: string;
14
+ readonly bundle: string;
15
+ /** Trusted module specifier, resolved against the bundle's project root. */
16
+ readonly profileModule?: string;
17
+ readonly today?: string;
18
+ /** Only used to resolve a relative `projectRoot`. Defaults to the process cwd. */
19
+ readonly cwd?: string;
20
+ readonly visualizationDirectory?: string;
21
+ /** The server name a client sees. Defaults to `okf-<bundle>`. */
22
+ readonly name?: string;
23
+ /** The deployment's own version. Defaults to {@link SERVER_VERSION}. */
24
+ readonly version?: string;
25
+ /** Title, description, website, icons, and the one-sentence purpose that opens the instructions. */
26
+ readonly identity?: OkfV1ServerIdentity;
27
+ }
28
+ export interface OkfLocalServer {
29
+ readonly target: ResolvedBundleTarget;
30
+ readonly settings: BundleSettings;
31
+ readonly operations: OkfV1Operations;
32
+ /** One MCP server instance. The stdio and HTTP entries call this per connection. */
33
+ createServer(): McpServer;
34
+ }
35
+ /**
36
+ * Resolve one manifest bundle off the filesystem and build the MCP surface over it.
37
+ *
38
+ * Every failure a deployment can fix — an unknown bundle name, an unreadable profile, an
39
+ * `access` value nothing defines — happens here, at startup, rather than on a tool call.
40
+ */
41
+ export declare function createOkfLocalServer(options: OkfLocalServerOptions): Promise<OkfLocalServer>;
42
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAwB,KAAK,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAA8C,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAEjG,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlE;;;;GAIG;AACH,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,oGAAoG;IACpG,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,oFAAoF;IACpF,YAAY,IAAI,SAAS,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAmClG"}
@@ -0,0 +1,51 @@
1
+ import path from "node:path";
2
+ import { createOkfV1McpServer } from "okf-contracts";
3
+ import { loadValidationProfile, resolveBundleTarget } from "okf-node";
4
+ import { bundleSettings } from "./bundle.js";
5
+ import { createFilesystemOkfV1Operations } from "./operations.js";
6
+ /**
7
+ * The version this server reports to a client. It is a constant rather than a read of
8
+ * `package.json`, which does not sit under `rootDir`; `test/version.test.ts` keeps the two
9
+ * from drifting.
10
+ */
11
+ export const SERVER_VERSION = "2.1.0";
12
+ /**
13
+ * Resolve one manifest bundle off the filesystem and build the MCP surface over it.
14
+ *
15
+ * Every failure a deployment can fix — an unknown bundle name, an unreadable profile, an
16
+ * `access` value nothing defines — happens here, at startup, rather than on a tool call.
17
+ */
18
+ export async function createOkfLocalServer(options) {
19
+ const projectRoot = path.resolve(options.cwd ?? process.cwd(), options.projectRoot);
20
+ const target = await resolveBundleTarget(projectRoot, options.bundle);
21
+ const settings = bundleSettings(target);
22
+ const analysis = {
23
+ ...(options.today === undefined ? {} : { today: options.today }),
24
+ // Resolved against the bundle's own project root, so `.agents/okf-private-profile.mjs`
25
+ // means the same thing here as it does in the repository's npm scripts.
26
+ ...(options.profileModule === undefined
27
+ ? {}
28
+ : { profile: await loadValidationProfile(target.projectRoot, options.profileModule) }),
29
+ };
30
+ const operations = createFilesystemOkfV1Operations({
31
+ target,
32
+ settings,
33
+ analysis,
34
+ ...(options.visualizationDirectory === undefined
35
+ ? {}
36
+ : { visualizationDirectory: options.visualizationDirectory }),
37
+ });
38
+ return {
39
+ target,
40
+ settings,
41
+ operations,
42
+ createServer: () => createOkfV1McpServer({
43
+ ...options.identity,
44
+ name: options.name ?? `okf-${settings.name}`,
45
+ version: options.version ?? SERVER_VERSION,
46
+ bundle: settings.name,
47
+ operations,
48
+ }),
49
+ };
50
+ }
51
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,oBAAoB,EAAkD,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAA6B,MAAM,UAAU,CAAC;AAEjG,OAAO,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AA4BtC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAA8B;IACvE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAExC,MAAM,QAAQ,GAAyB;QACrC,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAChE,uFAAuF;QACvF,wEAAwE;QACxE,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;YACrC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;KACzF,CAAC;IAEF,MAAM,UAAU,GAAG,+BAA+B,CAAC;QACjD,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,GAAG,CAAC,OAAO,CAAC,sBAAsB,KAAK,SAAS;YAC9C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,sBAAsB,EAAE,OAAO,CAAC,sBAAsB,EAAE,CAAC;KAChE,CAAC,CAAC;IAEH,OAAO;QACL,MAAM;QACN,QAAQ;QACR,UAAU;QACV,YAAY,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC;YACvC,GAAG,OAAO,CAAC,QAAQ;YACnB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,EAAE;YAC5C,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,cAAc;YAC1C,MAAM,EAAE,QAAQ,CAAC,IAAI;YACrB,UAAU;SACX,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../src/page/script.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,QA04BvB,CAAC"}
1
+ {"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../src/page/script.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,QA27BvB,CAAC"}