@okfit/mcp 0.2.0 → 0.3.1
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/bin/okfit-mcp.js +3 -27
- package/index.d.ts +6 -6
- package/internal/toolContext.js +1 -1
- package/main.d.ts +20 -0
- package/main.js +45 -0
- package/package.json +9 -4
- package/schema/tools.js +1 -1
- package/tools/describeVocabulary.js +1 -1
- package/tools/validateBundle.js +10 -6
- package/version.js +3 -5
- package/package.js +0 -5
package/README.md
CHANGED
|
@@ -9,7 +9,9 @@ Model Context Protocol server for [okfit](https://github.com/spencerbeggs/okfit)
|
|
|
9
9
|
`@okfit/mcp` speaks MCP over stdio for one OKF bundle. It is read-only: no
|
|
10
10
|
tool or resource ever writes to the bundle, the config, or anywhere else.
|
|
11
11
|
`validate_bundle` spawns read-only `git log`/`git show` calls for one lint
|
|
12
|
-
(`generated-at-drift`)
|
|
12
|
+
(`generated-at-drift`), and only for a concept that records no
|
|
13
|
+
`generated.body_sha256` — a bundle stamped with digests needs no git at
|
|
14
|
+
all; a read is not a write, and the promise stands. Six
|
|
13
15
|
tools cover orientation, discovery, and validation; the bundle index plus
|
|
14
16
|
one resource per concept expose the bundle's own markdown to a client's
|
|
15
17
|
@-mention UI.
|
package/bin/okfit-mcp.js
CHANGED
|
@@ -1,37 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { main } from "../main.js";
|
|
3
|
+
|
|
2
4
|
//#region src/bin.ts
|
|
3
5
|
/**
|
|
4
6
|
* MCP server entry point for okfit.
|
|
5
7
|
*
|
|
6
8
|
* @packageDocumentation
|
|
7
9
|
*/
|
|
8
|
-
|
|
9
|
-
const describe = (error) => {
|
|
10
|
-
try {
|
|
11
|
-
if (error instanceof Error) return error.stack ?? error.message;
|
|
12
|
-
return String(error);
|
|
13
|
-
} catch {
|
|
14
|
-
return FATAL_FALLBACK;
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
const fatal = (label, error) => {
|
|
18
|
-
process.stderr.write(`okfit-mcp: ${label}: ${describe(error)}\n`);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
};
|
|
21
|
-
process.on("uncaughtException", (error) => fatal("uncaught exception", error));
|
|
22
|
-
process.on("unhandledRejection", (reason) => fatal("unhandled rejection", reason));
|
|
23
|
-
await (async () => {
|
|
24
|
-
const NodeRuntime = await import("@effect/platform-node/NodeRuntime");
|
|
25
|
-
const NodeServices = await import("@effect/platform-node/NodeServices");
|
|
26
|
-
const { AppDirs, Xdg } = await import("@effected/xdg");
|
|
27
|
-
const { Cause, Exit, Layer, Logger, Runtime } = await import("effect");
|
|
28
|
-
const { resolveMcpProjectRoot } = await import("../internal/projectRoot.js");
|
|
29
|
-
const { ServerLayer } = await import("../server.js");
|
|
30
|
-
const PlatformLayer = Layer.mergeAll(Xdg.layer, AppDirs.layer({ namespace: "okfit" }).pipe(Layer.provide(Xdg.layer))).pipe(Layer.provideMerge(NodeServices.layer));
|
|
31
|
-
const projectRoot = resolveMcpProjectRoot(process.env);
|
|
32
|
-
const program = Layer.launch(ServerLayer(projectRoot).pipe(Layer.provide(PlatformLayer), Layer.provide(Logger.layer([Logger.consolePretty()])), Layer.provide(Layer.succeed(Logger.LogToStderr, true))));
|
|
33
|
-
NodeRuntime.runMain(program, { teardown: (exit, onExit) => Exit.isSuccess(exit) || Cause.hasInterruptsOnly(exit.cause) ? onExit(0) : Runtime.defaultTeardown(exit, onExit) });
|
|
34
|
-
})();
|
|
10
|
+
await main();
|
|
35
11
|
|
|
36
12
|
//#endregion
|
|
37
13
|
export { };
|
package/index.d.ts
CHANGED
|
@@ -361,9 +361,9 @@ export type ValidateBundleParams = typeof ValidateBundleParams.Type;
|
|
|
361
361
|
* discharged right here, below, by `Layer.mergeAll(Git.layer, GitHistory.layer)`
|
|
362
362
|
* — both need only `ChildProcessSpawner` (`GitHistory.layer` itself provides
|
|
363
363
|
* `Git.layer` internally, `packages/profiles/src/GitHistory.ts:136`), which
|
|
364
|
-
* `
|
|
364
|
+
* `@okfit/engine`'s `OkfitPlatform` already supplies via
|
|
365
365
|
* `NodeServices.layer`. This type widening is the only thing that changes
|
|
366
|
-
* at that boundary
|
|
366
|
+
* at that boundary.
|
|
367
367
|
*
|
|
368
368
|
* @public
|
|
369
369
|
*/
|
|
@@ -553,7 +553,7 @@ export declare const OkfitToolkit: Toolkit.Toolkit<{
|
|
|
553
553
|
}>;
|
|
554
554
|
readonly failure: import("effect/Schema").Union<readonly [typeof ConfigError, typeof BundleNotFound, typeof ConceptNotFound, typeof UnknownVocabulary, typeof InvalidArgument]>;
|
|
555
555
|
readonly failureMode: "error";
|
|
556
|
-
}, import("@effected/xdg").AppDirs | import("effect/FileSystem").FileSystem | import("@effected/git").Git | import("@okfit/profiles").GitHistory | import("effect/Path").Path | import("@effected/xdg").Xdg>;
|
|
556
|
+
}, import("@effected/xdg").AppDirs | import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("@effected/git").Git | import("@okfit/profiles").GitHistory | import("effect/Path").Path | import("@effected/xdg").Xdg>;
|
|
557
557
|
}>;
|
|
558
558
|
/**
|
|
559
559
|
* The handler layer. `projectRoot` is closed over from the bin (N-21);
|
|
@@ -719,13 +719,13 @@ export declare const ToolsLayer: (projectRoot: string) => import("effect/Layer")
|
|
|
719
719
|
}>;
|
|
720
720
|
readonly failure: import("effect/Schema").Union<readonly [typeof ConfigError, typeof BundleNotFound, typeof ConceptNotFound, typeof UnknownVocabulary, typeof InvalidArgument]>;
|
|
721
721
|
readonly failureMode: "error";
|
|
722
|
-
}, import("@effected/xdg").AppDirs | import("effect/FileSystem").FileSystem | import("@effected/git").Git | import("@okfit/profiles").GitHistory | import("effect/Path").Path | import("@effected/xdg").Xdg>;
|
|
722
|
+
}, import("@effected/xdg").AppDirs | import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("@effected/git").Git | import("@okfit/profiles").GitHistory | import("effect/Path").Path | import("@effected/xdg").Xdg>;
|
|
723
723
|
}>, never, never>;
|
|
724
724
|
//#endregion
|
|
725
725
|
//#region src/version.d.ts
|
|
726
726
|
/**
|
|
727
|
-
* The version this server reports in `initialize
|
|
728
|
-
*
|
|
727
|
+
* The version this server reports in `initialize`. Injected by
|
|
728
|
+
* `@savvy-web/bundler` at build time (K-32); `"0.0.0"` in unbuilt source.
|
|
729
729
|
*
|
|
730
730
|
* @public
|
|
731
731
|
*/
|
package/internal/toolContext.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BundleNotFound, ConfigError, composeRemediatedMessage } from "../errors.js";
|
|
2
2
|
import { Effect, Option } from "effect";
|
|
3
3
|
import { Bundle } from "@okfit/core";
|
|
4
|
-
import { provideConfig, resolveProjectConfig } from "@okfit/
|
|
4
|
+
import { provideConfig, resolveProjectConfig } from "@okfit/engine";
|
|
5
5
|
|
|
6
6
|
//#region src/internal/toolContext.ts
|
|
7
7
|
/**
|
package/main.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/main.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The assembled okfit MCP server program.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Run the okfit MCP server over stdio. Owns the process.
|
|
9
|
+
*
|
|
10
|
+
* This module deliberately carries NO static imports of the server graph:
|
|
11
|
+
* the `uncaughtException` and `unhandledRejection` handlers are registered
|
|
12
|
+
* before `NodeRuntime`, the logger and `ServerLayer` are ever evaluated, so
|
|
13
|
+
* a throw during module evaluation is still reported on stderr rather than
|
|
14
|
+
* crashing silently. Adding a static import here would defeat that.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare const main: () => Promise<void>;
|
|
19
|
+
//#endregion
|
|
20
|
+
//# sourceMappingURL=main.d.ts.map
|
package/main.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/main.ts
|
|
2
|
+
/**
|
|
3
|
+
* The assembled okfit MCP server program.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
const FATAL_FALLBACK = "okfit-mcp: a fatal error occurred and could not be described.";
|
|
8
|
+
const describe = (error) => {
|
|
9
|
+
try {
|
|
10
|
+
if (error instanceof Error) return error.stack ?? error.message;
|
|
11
|
+
return String(error);
|
|
12
|
+
} catch {
|
|
13
|
+
return FATAL_FALLBACK;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const fatal = (label, error) => {
|
|
17
|
+
process.stderr.write(`okfit-mcp: ${label}: ${describe(error)}\n`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Run the okfit MCP server over stdio. Owns the process.
|
|
22
|
+
*
|
|
23
|
+
* This module deliberately carries NO static imports of the server graph:
|
|
24
|
+
* the `uncaughtException` and `unhandledRejection` handlers are registered
|
|
25
|
+
* before `NodeRuntime`, the logger and `ServerLayer` are ever evaluated, so
|
|
26
|
+
* a throw during module evaluation is still reported on stderr rather than
|
|
27
|
+
* crashing silently. Adding a static import here would defeat that.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
const main = async () => {
|
|
32
|
+
process.on("uncaughtException", (error) => fatal("uncaught exception", error));
|
|
33
|
+
process.on("unhandledRejection", (reason) => fatal("unhandled rejection", reason));
|
|
34
|
+
const NodeRuntime = await import("@effect/platform-node/NodeRuntime");
|
|
35
|
+
const { OkfitPlatform } = await import("@okfit/engine");
|
|
36
|
+
const { Cause, Exit, Layer, Logger, Runtime } = await import("effect");
|
|
37
|
+
const { resolveMcpProjectRoot } = await import("./internal/projectRoot.js");
|
|
38
|
+
const { ServerLayer } = await import("./server.js");
|
|
39
|
+
const projectRoot = resolveMcpProjectRoot(process.env);
|
|
40
|
+
const program = Layer.launch(ServerLayer(projectRoot).pipe(Layer.provide(OkfitPlatform), Layer.provide(Logger.layer([Logger.consolePretty()])), Layer.provide(Layer.succeed(Logger.LogToStderr, true))));
|
|
41
|
+
NodeRuntime.runMain(program, { teardown: (exit, onExit) => Exit.isSuccess(exit) || Cause.hasInterruptsOnly(exit.cause) ? onExit(0) : Runtime.defaultTeardown(exit, onExit) });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { main };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@okfit/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Model Context Protocol server for okfit: query and understand Open Knowledge Format (OKF) bundles from an agent.",
|
|
6
6
|
"keywords": [
|
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
"import": "./index.js",
|
|
34
34
|
"default": "./index.js"
|
|
35
35
|
},
|
|
36
|
+
"./main": {
|
|
37
|
+
"types": "./main.d.ts",
|
|
38
|
+
"import": "./main.js",
|
|
39
|
+
"default": "./main.js"
|
|
40
|
+
},
|
|
36
41
|
"./package.json": "./package.json"
|
|
37
42
|
},
|
|
38
43
|
"bin": {
|
|
@@ -42,9 +47,9 @@
|
|
|
42
47
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
43
48
|
"@effected/git": "^0.12.0",
|
|
44
49
|
"@effected/xdg": "^0.4.1",
|
|
45
|
-
"@okfit/
|
|
46
|
-
"@okfit/
|
|
47
|
-
"@okfit/profiles": "0.
|
|
50
|
+
"@okfit/core": "0.3.0",
|
|
51
|
+
"@okfit/engine": "0.2.0",
|
|
52
|
+
"@okfit/profiles": "0.3.0",
|
|
48
53
|
"effect": "4.0.0-rc.112"
|
|
49
54
|
},
|
|
50
55
|
"engines": {
|
package/schema/tools.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConceptSummary } from "./ConceptSummary.js";
|
|
2
2
|
import { Schema } from "effect";
|
|
3
3
|
import { GraphNodeKind, Status } from "@okfit/core";
|
|
4
|
-
import { ContextTag, ContextType } from "@okfit/
|
|
4
|
+
import { ContextTag, ContextType } from "@okfit/engine";
|
|
5
5
|
|
|
6
6
|
//#region src/schema/tools.ts
|
|
7
7
|
/** `describe_vocabulary`'s result (§5.2). @public */
|
|
@@ -3,7 +3,7 @@ import { resolveConfigOnly } from "../internal/toolContext.js";
|
|
|
3
3
|
import { DescribeVocabularySuccess } from "../schema/tools.js";
|
|
4
4
|
import { Effect, FileSystem, Option, Path } from "effect";
|
|
5
5
|
import { Tool } from "effect/unstable/ai";
|
|
6
|
-
import { contextEnvelope } from "@okfit/
|
|
6
|
+
import { contextEnvelope } from "@okfit/engine";
|
|
7
7
|
import { AppDirs, Xdg } from "@effected/xdg";
|
|
8
8
|
|
|
9
9
|
//#region src/tools/describeVocabulary.ts
|
package/tools/validateBundle.js
CHANGED
|
@@ -3,10 +3,10 @@ import { resolveConfigOnly } from "../internal/toolContext.js";
|
|
|
3
3
|
import { ValidateBundleParams } from "../schema/tools.js";
|
|
4
4
|
import { resolveNow } from "../internal/resolveNow.js";
|
|
5
5
|
import { MCP_VERSION } from "../version.js";
|
|
6
|
-
import { Effect, FileSystem, Option, Path } from "effect";
|
|
6
|
+
import { Crypto, Effect, FileSystem, Option, Path } from "effect";
|
|
7
7
|
import { OKF_SPEC_VERSION } from "@okfit/core";
|
|
8
8
|
import { Tool } from "effect/unstable/ai";
|
|
9
|
-
import { JsonEnvelope, collect, forDiagnostics, json, run } from "@okfit/
|
|
9
|
+
import { JsonEnvelope, collect, forDiagnostics, json, run } from "@okfit/engine";
|
|
10
10
|
import { Git } from "@effected/git";
|
|
11
11
|
import { GitHistory } from "@okfit/profiles";
|
|
12
12
|
import { AppDirs, Xdg } from "@effected/xdg";
|
|
@@ -25,7 +25,10 @@ const DESCRIPTION = "Runs the same conformance and lint checks as `okfit validat
|
|
|
25
25
|
* GitHistory` so it can run `Provenance.lint`'s `generated-at-drift`
|
|
26
26
|
* check (S-8, S-16). Both are provided by `server.ts`'s `ServerLayer`,
|
|
27
27
|
* which needs only `ChildProcessSpawner` to build them — already
|
|
28
|
-
* supplied by `
|
|
28
|
+
* supplied by `@okfit/engine`'s `OkfitPlatform` (S-16). `Crypto` joined the
|
|
29
|
+
* same channel for issue #19's body-digest tier of `Provenance.lint`, and
|
|
30
|
+
* is provided the same way -- `OkfitPlatform`'s `NodeServices.layer` bundles
|
|
31
|
+
* it alongside `FileSystem`/`Path`.
|
|
29
32
|
*
|
|
30
33
|
* @public
|
|
31
34
|
*/
|
|
@@ -40,15 +43,16 @@ const validateBundle = Tool.make("validate_bundle", {
|
|
|
40
43
|
AppDirs,
|
|
41
44
|
Xdg,
|
|
42
45
|
Git,
|
|
43
|
-
GitHistory
|
|
46
|
+
GitHistory,
|
|
47
|
+
Crypto.Crypto
|
|
44
48
|
]
|
|
45
49
|
}).annotate(Tool.Title, "Validate the bundle").annotate(Tool.Readonly, true).annotate(Tool.Idempotent, true).annotate(Tool.OpenWorld, false);
|
|
46
50
|
/**
|
|
47
51
|
* This tool does not call `loadToolContext`: `run()` calls `Bundle.load`
|
|
48
|
-
* itself (`packages/
|
|
52
|
+
* itself (`packages/engine/src/validate/run.ts:52-56`), so routing through
|
|
49
53
|
* `loadToolContext` would load the bundle twice. It uses `resolveConfigOnly`
|
|
50
54
|
* and keeps `bundleRoot`, `config` **and** `profile` — `run()` needs the
|
|
51
|
-
* profile. `success` is `JsonEnvelope`, imported from `@okfit/
|
|
55
|
+
* profile. `success` is `JsonEnvelope`, imported from `@okfit/engine` and used
|
|
52
56
|
* verbatim (N-35's own carve-out: data reuse, not envelope reuse);
|
|
53
57
|
* `JsonErrorEnvelope` is never returned — that is the CLI's stdout
|
|
54
58
|
* convention for an exit-3 infrastructure failure, and here that failure is
|
package/version.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { version } from "./package.js";
|
|
2
|
-
|
|
3
1
|
//#region src/version.ts
|
|
4
2
|
/**
|
|
5
|
-
* The version this server reports in `initialize
|
|
6
|
-
*
|
|
3
|
+
* The version this server reports in `initialize`. Injected by
|
|
4
|
+
* `@savvy-web/bundler` at build time (K-32); `"0.0.0"` in unbuilt source.
|
|
7
5
|
*
|
|
8
6
|
* @public
|
|
9
7
|
*/
|
|
10
|
-
const MCP_VERSION =
|
|
8
|
+
const MCP_VERSION = "0.3.1";
|
|
11
9
|
|
|
12
10
|
//#endregion
|
|
13
11
|
export { MCP_VERSION };
|