@savvy-web/mcp 0.3.0 → 0.4.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 (41) hide show
  1. package/README.md +1 -0
  2. package/bin/savvy-mcp.js +40 -146
  3. package/package.json +42 -80
  4. package/{resources → public}/content/manifest.json +175 -250
  5. package/public/content/standards/turbo/best-practices.md +76 -0
  6. package/public/content/standards/turbo/boundaries.md +72 -0
  7. package/public/content/standards/turbo/ci.md +69 -0
  8. package/public/content/standards/turbo/environment.md +64 -0
  9. package/public/content/standards/turbo/filtering.md +72 -0
  10. package/public/content/standards/turbo/watch.md +64 -0
  11. package/{resources → public}/content/tags.json +3 -1
  12. package/547.js +0 -416
  13. package/index.d.ts +0 -126
  14. package/index.js +0 -3
  15. package/tsdoc-metadata.json +0 -11
  16. /package/{resources → public}/content/_templates/guides.md +0 -0
  17. /package/{resources → public}/content/_templates/packages.md +0 -0
  18. /package/{resources → public}/content/_templates/standards.md +0 -0
  19. /package/{resources → public}/content/guides/api-docs-from-api-extractor.md +0 -0
  20. /package/{resources → public}/content/guides/building-a-github-action.md +0 -0
  21. /package/{resources → public}/content/guides/choosing-a-builder.md +0 -0
  22. /package/{resources → public}/content/guides/llm-friendly-json-schemas.md +0 -0
  23. /package/{resources → public}/content/packages/cli/command-tree.md +0 -0
  24. /package/{resources → public}/content/packages/cli/init-and-check.md +0 -0
  25. /package/{resources → public}/content/packages/mcp/resource-taxonomy.md +0 -0
  26. /package/{resources → public}/content/packages/rslib-builder/overview.md +0 -0
  27. /package/{resources → public}/content/packages/silk/export-map.md +0 -0
  28. /package/{resources → public}/content/packages/silk/install-and-setup.md +0 -0
  29. /package/{resources → public}/content/packages/silk-effects/index.md +0 -0
  30. /package/{resources → public}/content/packages/silk-effects/managed-section.md +0 -0
  31. /package/{resources → public}/content/packages/silk-effects/platform-layers.md +0 -0
  32. /package/{resources → public}/content/standards/api-model-pipeline.md +0 -0
  33. /package/{resources → public}/content/standards/catalog-usage.md +0 -0
  34. /package/{resources → public}/content/standards/changeset-discipline.md +0 -0
  35. /package/{resources → public}/content/standards/changeset-format.md +0 -0
  36. /package/{resources → public}/content/standards/commit-contract.md +0 -0
  37. /package/{resources → public}/content/standards/dependency-conventions.md +0 -0
  38. /package/{resources → public}/content/standards/linting-conventions.md +0 -0
  39. /package/{resources → public}/content/standards/publishability.md +0 -0
  40. /package/{resources → public}/content/standards/semver.md +0 -0
  41. /package/{resources → public}/content/standards/test-classification.md +0 -0
package/README.md CHANGED
@@ -43,6 +43,7 @@ npx @modelcontextprotocol/inspector savvy-mcp .
43
43
 
44
44
  - `workspace_info` — returns a flat, structured projection of the workspace analysis: linked and fixed package groups as name arrays plus resolved registry targets. Backed by the same `silk-effects` analyzer the `savvy` CLI uses.
45
45
  - `silk_docs_search` — ranks documents in the corpus against a plain keyword or phrase query and returns hits with a normalized confidence score plus a high/medium/low label. It never returns empty: when nothing matches, it falls back to the priority-ordered top results.
46
+ - `turbo_inspect` — read-only Turborepo inspection over `turbo --dry`: diagnose a task's per-package cache hits, derive the task graph or list the packages affected by recent changes. It never runs a task. Backed by the same `silk-effects` `Turbo` inspector an agent would otherwise drive by hand.
46
47
 
47
48
  ## Resources
48
49
 
package/bin/savvy-mcp.js CHANGED
@@ -1,153 +1,47 @@
1
1
  #!/usr/bin/env node
2
- import { NodeContext } from "@effect/platform-node";
2
+ import { SilkRuntimeLive } from "../runtime.js";
3
+ import { loadManifest, readDocBody, resolveContentRoot } from "../resources/load.js";
4
+ import { startMcpServer } from "../server.js";
5
+ import { DocIndex } from "../resources/doc-index.js";
3
6
  import { Layer, ManagedRuntime } from "effect";
4
- import fuse_0 from "fuse.js";
5
- import { loadManifest, readDocBody, resolveContentRoot, startMcpServer, SilkRuntimeLive } from "../547.js";
6
- const STOP_WORDS = new Set([
7
- "how",
8
- "do",
9
- "i",
10
- "the",
11
- "a",
12
- "an",
13
- "to",
14
- "of",
15
- "in",
16
- "for",
17
- "is",
18
- "what",
19
- "when",
20
- "use"
21
- ]);
22
- const FUSE_THRESHOLD = 0.6;
23
- const confidenceLabel = (confidence)=>confidence >= 0.6 ? "high" : confidence >= 0.4 ? "medium" : "low";
24
- const toRanked = (item, score, matches)=>({
25
- item,
26
- confidence: 1 - (score ?? 1),
27
- matchedOn: matches.map((m)=>m.key ?? "")
28
- });
29
- class DocIndex {
30
- fuse;
31
- entries;
32
- byUri;
33
- constructor(fuse, entries, byUri){
34
- this.fuse = fuse;
35
- this.entries = entries;
36
- this.byUri = byUri;
37
- }
38
- static fromManifest(manifest, bodies) {
39
- const entries = manifest.entries.filter((e)=>"deprecated" !== e.status).map((e)=>({
40
- ...e,
41
- body: bodies[e.uri] ?? ""
42
- }));
43
- const fuse = new fuse_0(entries, {
44
- useExtendedSearch: true,
45
- ignoreLocation: true,
46
- includeScore: true,
47
- includeMatches: true,
48
- minMatchCharLength: 2,
49
- threshold: FUSE_THRESHOLD,
50
- keys: [
51
- {
52
- name: "title",
53
- weight: 0.55
54
- },
55
- {
56
- name: "tags",
57
- weight: 0.3
58
- },
59
- {
60
- name: "summary",
61
- weight: 0.12
62
- },
63
- {
64
- name: "body",
65
- weight: 0.03
66
- }
67
- ]
68
- });
69
- const byUri = new Map(entries.map((e)=>[
70
- e.uri,
71
- e
72
- ]));
73
- return new DocIndex(fuse, entries, byUri);
74
- }
75
- search(query, opts = {}) {
76
- const limit = opts.limit ?? 10;
77
- const tokens = query.toLowerCase().split(/\s+/).filter((t)=>t.length >= 2 && !STOP_WORDS.has(t));
78
- const raw = tokens.length > 0 ? this.fuse.search(tokens.map((t)=>`'${t}`).join(" | ")) : [];
79
- const filteredByTier = opts.tier ? raw.filter((r)=>r.item.tier === opts.tier) : raw;
80
- const ranked = filteredByTier.length > 0 ? filteredByTier.map((r)=>toRanked(r.item, r.score, r.matches ?? [])) : this.fallback(opts.tier);
81
- ranked.sort((a, b)=>b.confidence - a.confidence || (b.item.priority ?? 0.5) - (a.item.priority ?? 0.5));
82
- const present = new Set(ranked.map((r)=>r.item.uri));
83
- const seeAlso = [];
84
- for (const r of ranked.slice(0, 3))for (const rel of r.item.related){
85
- const uri = rel.startsWith("silk://") ? rel : `silk://${rel}`;
86
- if (present.has(uri)) continue;
87
- const neighbor = this.byUri.get(uri);
88
- if (neighbor) {
89
- present.add(uri);
90
- seeAlso.push({
91
- item: neighbor,
92
- confidence: 0,
93
- matchedOn: [
94
- "related"
95
- ]
96
- });
97
- }
98
- }
99
- return [
100
- ...ranked,
101
- ...seeAlso
102
- ].slice(0, limit).map(({ item, confidence, matchedOn })=>({
103
- uri: item.uri,
104
- title: item.title,
105
- summary: item.summary,
106
- tags: item.tags,
107
- tier: item.tier,
108
- confidence: Number(confidence.toFixed(3)),
109
- confidenceLabel: confidenceLabel(confidence),
110
- matchedOn: [
111
- ...new Set(matchedOn)
112
- ].filter(Boolean),
113
- related: item.related
114
- }));
115
- }
116
- fallback(tier) {
117
- return this.entries.filter((e)=>tier ? e.tier === tier : true).slice().sort((a, b)=>(b.priority ?? 0.5) - (a.priority ?? 0.5)).slice(0, 5).map((item)=>({
118
- item,
119
- confidence: 0,
120
- matchedOn: []
121
- }));
122
- }
123
- }
7
+ import { NodeContext } from "@effect/platform-node";
8
+
9
+ //#region src/bin.ts
10
+ /**
11
+ * Binary entrypoint for the `savvy-mcp` server.
12
+ *
13
+ * Resolves the project working directory, builds the long-lived runtime, and
14
+ * starts the MCP server over stdio.
15
+ *
16
+ * @internal
17
+ */
18
+ /* v8 ignore start -- process bootstrap; covered by server.smoke.test.ts */
124
19
  function resolveProjectDir() {
125
- const argv = process.argv[2];
126
- const fromArgv = void 0 !== argv && argv.trim().length > 0 && !(argv.startsWith("${") && argv.endsWith("}")) ? argv.trim() : void 0;
127
- return fromArgv ?? process.env.SAVVY_MCP_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
20
+ const argv = process.argv[2];
21
+ return (argv !== void 0 && argv.trim().length > 0 && !(argv.startsWith("${") && argv.endsWith("}")) ? argv.trim() : void 0) ?? process.env.SAVVY_MCP_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
128
22
  }
129
23
  async function main() {
130
- const cwd = resolveProjectDir();
131
- const appLayer = SilkRuntimeLive.pipe(Layer.provide(NodeContext.layer));
132
- const runtime = ManagedRuntime.make(appLayer);
133
- const contentRoot = resolveContentRoot();
134
- const manifest = loadManifest(contentRoot);
135
- const bodies = Object.fromEntries(manifest.entries.map((e)=>[
136
- e.uri,
137
- readDocBody(contentRoot, e.uri.replace(/^silk:\/\//, ""))
138
- ]));
139
- const docIndex = DocIndex.fromManifest(manifest, bodies);
140
- const ctx = {
141
- runtime,
142
- cwd,
143
- docIndex,
144
- manifest,
145
- contentRoot
146
- };
147
- process.stderr.write(`[savvy-mcp] starting in ${cwd}\n`);
148
- await startMcpServer(ctx);
24
+ const cwd = resolveProjectDir();
25
+ const appLayer = SilkRuntimeLive.pipe(Layer.provide(NodeContext.layer));
26
+ const runtime = ManagedRuntime.make(appLayer);
27
+ const contentRoot = resolveContentRoot();
28
+ const manifest = loadManifest(contentRoot);
29
+ const bodies = Object.fromEntries(manifest.entries.map((e) => [e.uri, readDocBody(contentRoot, e.uri.replace(/^silk:\/\//, ""))]));
30
+ const ctx = {
31
+ runtime,
32
+ cwd,
33
+ docIndex: DocIndex.fromManifest(manifest, bodies),
34
+ manifest,
35
+ contentRoot
36
+ };
37
+ process.stderr.write(`[savvy-mcp] starting in ${cwd}\n`);
38
+ await startMcpServer(ctx);
149
39
  }
150
- main().catch((err)=>{
151
- process.stderr.write(`savvy-mcp: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
152
- process.exit(1);
40
+ main().catch((err) => {
41
+ process.stderr.write(`savvy-mcp: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
42
+ process.exit(1);
153
43
  });
44
+ /* v8 ignore stop */
45
+
46
+ //#endregion
47
+ export { };
package/package.json CHANGED
@@ -1,82 +1,44 @@
1
1
  {
2
- "name": "@savvy-web/mcp",
3
- "version": "0.3.0",
4
- "private": false,
5
- "description": "The savvy MCP server — Silk Suite tooling and library knowledge for coding agents",
6
- "homepage": "https://github.com/savvy-web/systems/tree/main/packages/mcp",
7
- "bugs": {
8
- "url": "https://github.com/savvy-web/systems/issues"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/savvy-web/systems.git",
13
- "directory": "packages/mcp"
14
- },
15
- "license": "MIT",
16
- "author": {
17
- "name": "C. Spencer Beggs",
18
- "email": "spencer@savvyweb.systems",
19
- "url": "https://savvyweb.systems"
20
- },
21
- "type": "module",
22
- "exports": {
23
- ".": {
24
- "types": "./index.d.ts",
25
- "import": "./index.js"
26
- }
27
- },
28
- "bin": {
29
- "savvy-mcp": "bin/savvy-mcp.js"
30
- },
31
- "files": [
32
- "!mcp.api.json",
33
- "!tsconfig.json",
34
- "!tsdoc.json",
35
- "547.js",
36
- "README.md",
37
- "bin/savvy-mcp.js",
38
- "index.d.ts",
39
- "index.js",
40
- "package.json",
41
- "resources",
42
- "resources/content/_templates/guides.md",
43
- "resources/content/_templates/packages.md",
44
- "resources/content/_templates/standards.md",
45
- "resources/content/guides/api-docs-from-api-extractor.md",
46
- "resources/content/guides/building-a-github-action.md",
47
- "resources/content/guides/choosing-a-builder.md",
48
- "resources/content/guides/llm-friendly-json-schemas.md",
49
- "resources/content/manifest.json",
50
- "resources/content/packages/cli/command-tree.md",
51
- "resources/content/packages/cli/init-and-check.md",
52
- "resources/content/packages/mcp/resource-taxonomy.md",
53
- "resources/content/packages/rslib-builder/overview.md",
54
- "resources/content/packages/silk-effects/index.md",
55
- "resources/content/packages/silk-effects/managed-section.md",
56
- "resources/content/packages/silk-effects/platform-layers.md",
57
- "resources/content/packages/silk/export-map.md",
58
- "resources/content/packages/silk/install-and-setup.md",
59
- "resources/content/standards/api-model-pipeline.md",
60
- "resources/content/standards/catalog-usage.md",
61
- "resources/content/standards/changeset-discipline.md",
62
- "resources/content/standards/changeset-format.md",
63
- "resources/content/standards/commit-contract.md",
64
- "resources/content/standards/dependency-conventions.md",
65
- "resources/content/standards/linting-conventions.md",
66
- "resources/content/standards/publishability.md",
67
- "resources/content/standards/semver.md",
68
- "resources/content/standards/test-classification.md",
69
- "resources/content/tags.json",
70
- "tsdoc-metadata.json"
71
- ],
72
- "dependencies": {
73
- "@effect/platform": "^0.96.1",
74
- "@effect/platform-node": "^0.106.0",
75
- "@modelcontextprotocol/sdk": "^1.29.0",
76
- "@savvy-web/silk-effects": "0.6.0",
77
- "effect": "^3.21.2",
78
- "fuse.js": "^7.4.0",
79
- "workspaces-effect": "^1.1.0",
80
- "zod": "^4.4.3"
81
- }
2
+ "name": "@savvy-web/mcp",
3
+ "version": "0.4.0",
4
+ "private": false,
5
+ "description": "The savvy MCP server — Silk Suite tooling and library knowledge for coding agents",
6
+ "homepage": "https://github.com/savvy-web/systems/tree/main/packages/mcp",
7
+ "bugs": {
8
+ "url": "https://github.com/savvy-web/systems/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/savvy-web/systems.git",
13
+ "directory": "packages/mcp"
14
+ },
15
+ "license": "MIT",
16
+ "author": {
17
+ "name": "C. Spencer Beggs",
18
+ "email": "spencer@savvyweb.systems",
19
+ "url": "https://savvyweb.systems"
20
+ },
21
+ "type": "module",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./index.d.ts",
25
+ "import": "./index.js"
26
+ }
27
+ },
28
+ "bin": {
29
+ "savvy-mcp": "bin/savvy-mcp.js"
30
+ },
31
+ "files": [
32
+ "public"
33
+ ],
34
+ "dependencies": {
35
+ "@effect/platform": "^0.96.1",
36
+ "@effect/platform-node": "^0.106.0",
37
+ "@modelcontextprotocol/sdk": "^1.29.0",
38
+ "@savvy-web/silk-effects": "1.0.0",
39
+ "effect": "^3.21.2",
40
+ "fuse.js": "^7.4.0",
41
+ "workspaces-effect": "^1.1.0",
42
+ "zod": "^4.4.3"
43
+ }
82
44
  }