@savvy-web/mcp 3.4.18 → 3.4.20
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/index.js +1 -1
- package/package.json +10 -10
- package/server.js +30 -9
- package/tools/biome-check.js +5 -15
- package/version.js +1 -1
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BiomeFailed, EngineError, McpToolError, WorkspaceNotFound } from "./errors.js";
|
|
2
2
|
import { makeSilkRuntimeLayer } from "./runtime.js";
|
|
3
|
+
import { ServerLayer } from "./server.js";
|
|
3
4
|
import { SilkToolkit, ToolsLayer } from "./toolkit.js";
|
|
4
5
|
import { CURRENT_MCP_VERSION } from "./version.js";
|
|
5
|
-
import { ServerLayer } from "./server.js";
|
|
6
6
|
|
|
7
7
|
export { BiomeFailed, CURRENT_MCP_VERSION, EngineError, McpToolError, ServerLayer, SilkToolkit, ToolsLayer, WorkspaceNotFound, makeSilkRuntimeLayer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/mcp",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.20",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The savvy MCP server — Silk Suite tooling and library knowledge for coding agents",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/systems/tree/main/packages/mcp",
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"savvy-mcp": "bin/savvy-mcp.js"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@effect/platform-node": "
|
|
40
|
-
"@effected/commands": "^0.
|
|
41
|
-
"@effected/engine": "^0.
|
|
42
|
-
"@effected/git": "^0.
|
|
43
|
-
"@effected/mcp": "^0.
|
|
44
|
-
"@effected/templates": "^0.
|
|
45
|
-
"@effected/workspaces": "^0.
|
|
46
|
-
"@savvy-web/silk-effects": "^
|
|
47
|
-
"effect": "
|
|
39
|
+
"@effect/platform-node": "~4.1.1",
|
|
40
|
+
"@effected/commands": "^0.19.0",
|
|
41
|
+
"@effected/engine": "^0.11.0",
|
|
42
|
+
"@effected/git": "^0.29.0",
|
|
43
|
+
"@effected/mcp": "^0.12.0",
|
|
44
|
+
"@effected/templates": "^0.16.0",
|
|
45
|
+
"@effected/workspaces": "^0.41.0",
|
|
46
|
+
"@savvy-web/silk-effects": "^11.0.0",
|
|
47
|
+
"effect": "~4.1.1"
|
|
48
48
|
}
|
|
49
49
|
}
|
package/server.js
CHANGED
|
@@ -2,8 +2,9 @@ import { makeSilkRuntimeLayer } from "./runtime.js";
|
|
|
2
2
|
import { SilkToolkit, ToolsLayer } from "./toolkit.js";
|
|
3
3
|
import { CURRENT_MCP_VERSION } from "./version.js";
|
|
4
4
|
import { McpStdio, McpToolkit } from "@effected/mcp";
|
|
5
|
-
import { Layer, Option } from "effect";
|
|
5
|
+
import { Effect, Layer, Option } from "effect";
|
|
6
6
|
import { distributionSuffix } from "@effected/engine";
|
|
7
|
+
import { McpServer } from "effect/ai";
|
|
7
8
|
|
|
8
9
|
// src/server.ts
|
|
9
10
|
/**
|
|
@@ -26,12 +27,31 @@ const SERVER_INSTRUCTIONS = [
|
|
|
26
27
|
"Every successful result is a typed object in structuredContent (content[0].text carries the same object as JSON). A failure is an isError result whose content[0].text carries the message and remediation, with no structuredContent. Every tool takes an optional cwd; omit it to use the server's project directory."
|
|
27
28
|
].join("\n");
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* Discharges every tool's declared `dependencies`. Since effect 4.1 a service a
|
|
31
|
+
* tool lists in `dependencies` is a per-request `McpRequest<"Requires", S>`
|
|
32
|
+
* requirement that only MCP middleware or the transport can meet;
|
|
33
|
+
* `Layer.provide` no longer does. The silk runtime is built ONCE (it holds the
|
|
34
|
+
* process-lifetime `ConfigInspector`, #229), so the middleware captures its
|
|
35
|
+
* context when the layer is built and provides that same context to every
|
|
36
|
+
* request.
|
|
37
|
+
*
|
|
38
|
+
* `Effect.context` captures the whole layer-build context, not only
|
|
39
|
+
* `McpServices` (also `Scope`, `Clock`, `Console`, `McpServer`, the memo map),
|
|
40
|
+
* and `Effect.provideContext` merges it OVER the request's context. Probed on
|
|
41
|
+
* 4.1.1: a handler finalizer still runs at the end of its own request, and no
|
|
42
|
+
* request-scoped key (`McpRequestContext`, log level, parent span) is in the
|
|
43
|
+
* build context today. Core's own registration capture filters those keys
|
|
44
|
+
* (`omitRequestServices`); this capture does not, so do not build this layer
|
|
45
|
+
* inside a span or under a request-level reference.
|
|
46
|
+
*/
|
|
47
|
+
const RuntimeMiddleware = McpServer.middleware()(Effect.map(Effect.context(), (context) => (effect) => Effect.provideContext(effect, context)));
|
|
48
|
+
/**
|
|
49
|
+
* The toolkit registration as a layer: `McpToolkit.layer` with the handlers
|
|
50
|
+
* bound to `cwd` and {@link RuntimeMiddleware} meeting their request-level
|
|
51
|
+
* dependencies. Passed to `McpStdio.layer` as `registrations`, so it builds
|
|
52
|
+
* before the first request.
|
|
33
53
|
*/
|
|
34
|
-
const SilkToolsLayer = (cwd) => McpToolkit.layer(SilkToolkit, { strict: "annotated" }).pipe(Layer.provide(ToolsLayer(cwd)));
|
|
54
|
+
const SilkToolsLayer = (cwd) => McpToolkit.layer(SilkToolkit, { strict: "annotated" }).pipe(Layer.provide(ToolsLayer(cwd)), Layer.provide(RuntimeMiddleware.layer));
|
|
35
55
|
/**
|
|
36
56
|
* The whole server as one layer: the ten-tool toolkit, the silk-effects
|
|
37
57
|
* runtime discharging its dependencies, over `@effected/mcp`'s
|
|
@@ -44,11 +64,12 @@ const SilkToolsLayer = (cwd) => McpToolkit.layer(SilkToolkit, { strict: "annotat
|
|
|
44
64
|
*
|
|
45
65
|
* @public
|
|
46
66
|
*/
|
|
47
|
-
const ServerLayer = (cwd, options = {}) =>
|
|
67
|
+
const ServerLayer = (cwd, options = {}) => McpStdio.layer({
|
|
48
68
|
name: "savvy-mcp",
|
|
49
69
|
version: `${CURRENT_MCP_VERSION}${distributionSuffix(Option.fromNullishOr(options.distribution))}`,
|
|
50
70
|
description: "Structured Silk Suite workspace tools: workspace, turbo, biome, changesets and vendored repos.",
|
|
51
|
-
instructions: SERVER_INSTRUCTIONS
|
|
52
|
-
|
|
71
|
+
instructions: SERVER_INSTRUCTIONS,
|
|
72
|
+
registrations: SilkToolsLayer(cwd)
|
|
73
|
+
}).pipe(Layer.provide(makeSilkRuntimeLayer(cwd)));
|
|
53
74
|
|
|
54
75
|
export { SERVER_INSTRUCTIONS, ServerLayer };
|
package/tools/biome-check.js
CHANGED
|
@@ -71,8 +71,8 @@ const GitlabDiagnostic = Schema.Struct({
|
|
|
71
71
|
lines: Schema.Struct({ begin: Schema.Number })
|
|
72
72
|
})
|
|
73
73
|
});
|
|
74
|
-
|
|
75
|
-
const decodeGitlab = Schema.
|
|
74
|
+
/** Biome's gitlab stdout, parsed and decoded in one step; `None` for non-JSON or a shape mismatch. */
|
|
75
|
+
const decodeGitlab = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Array(GitlabDiagnostic)));
|
|
76
76
|
/**
|
|
77
77
|
* Map a gitlab severity back onto the Biome severity it was produced from.
|
|
78
78
|
*
|
|
@@ -91,19 +91,9 @@ const mapSeverity = (s) => s === "info" || s === "minor" ? "info" : s === "major
|
|
|
91
91
|
const parseBiomeGitlab = (stdout) => {
|
|
92
92
|
const trimmed = stdout.trim();
|
|
93
93
|
if (!trimmed) return [];
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
} catch {
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
let decoded;
|
|
101
|
-
try {
|
|
102
|
-
decoded = decodeGitlab(raw);
|
|
103
|
-
} catch {
|
|
104
|
-
return [];
|
|
105
|
-
}
|
|
106
|
-
return decoded.map((d) => ({
|
|
94
|
+
const decoded = decodeGitlab(trimmed);
|
|
95
|
+
if (Option.isNone(decoded)) return [];
|
|
96
|
+
return decoded.value.map((d) => ({
|
|
107
97
|
file: d.location.path,
|
|
108
98
|
line: d.location.lines.begin,
|
|
109
99
|
severity: mapSeverity(d.severity),
|