@shrkcrft/mcp-server 0.1.0-alpha.2 → 0.1.0-alpha.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.
Files changed (189) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -0
  4. package/dist/server/columnar-format.d.ts +34 -0
  5. package/dist/server/columnar-format.d.ts.map +1 -0
  6. package/dist/server/columnar-format.js +95 -0
  7. package/dist/server/create-mcp-server.d.ts +3 -0
  8. package/dist/server/create-mcp-server.d.ts.map +1 -1
  9. package/dist/server/create-mcp-server.js +24 -9
  10. package/dist/server/fit-array-to-budget.d.ts +24 -0
  11. package/dist/server/fit-array-to-budget.d.ts.map +1 -0
  12. package/dist/server/fit-array-to-budget.js +60 -0
  13. package/dist/server/serialize-tool-data.d.ts +15 -0
  14. package/dist/server/serialize-tool-data.d.ts.map +1 -0
  15. package/dist/server/serialize-tool-data.js +22 -0
  16. package/dist/server/tool-definition.d.ts +15 -0
  17. package/dist/server/tool-definition.d.ts.map +1 -1
  18. package/dist/server/tool-input-validators.d.ts.map +1 -1
  19. package/dist/server/tool-input-validators.js +43 -0
  20. package/dist/tools/agent-brief.tool.d.ts.map +1 -1
  21. package/dist/tools/agent-brief.tool.js +20 -0
  22. package/dist/tools/align-cache.tool.d.ts +11 -0
  23. package/dist/tools/align-cache.tool.d.ts.map +1 -0
  24. package/dist/tools/align-cache.tool.js +76 -0
  25. package/dist/tools/all-tools.d.ts.map +1 -1
  26. package/dist/tools/all-tools.js +72 -7
  27. package/dist/tools/architecture-map.tool.d.ts.map +1 -1
  28. package/dist/tools/architecture-map.tool.js +4 -2
  29. package/dist/tools/code-find-usages.tool.d.ts +16 -0
  30. package/dist/tools/code-find-usages.tool.d.ts.map +1 -0
  31. package/dist/tools/code-find-usages.tool.js +180 -0
  32. package/dist/tools/command-catalog.tool.d.ts.map +1 -1
  33. package/dist/tools/command-catalog.tool.js +11 -7
  34. package/dist/tools/compress-context.tool.d.ts +8 -0
  35. package/dist/tools/compress-context.tool.d.ts.map +1 -0
  36. package/dist/tools/compress-context.tool.js +81 -0
  37. package/dist/tools/dashboard-summary.tool.d.ts.map +1 -1
  38. package/dist/tools/dashboard-summary.tool.js +2 -4
  39. package/dist/tools/delegate-task.tool.d.ts +3 -0
  40. package/dist/tools/delegate-task.tool.d.ts.map +1 -0
  41. package/dist/tools/delegate-task.tool.js +94 -0
  42. package/dist/tools/deps-audit.tool.d.ts +10 -0
  43. package/dist/tools/deps-audit.tool.d.ts.map +1 -0
  44. package/dist/tools/deps-audit.tool.js +251 -0
  45. package/dist/tools/diff-check.tool.d.ts +15 -0
  46. package/dist/tools/diff-check.tool.d.ts.map +1 -0
  47. package/dist/tools/diff-check.tool.js +157 -0
  48. package/dist/tools/file-advice.tool.d.ts +22 -0
  49. package/dist/tools/file-advice.tool.d.ts.map +1 -0
  50. package/dist/tools/file-advice.tool.js +88 -0
  51. package/dist/tools/get-api-surface-diff.tool.d.ts +3 -0
  52. package/dist/tools/get-api-surface-diff.tool.d.ts.map +1 -0
  53. package/dist/tools/get-api-surface-diff.tool.js +60 -0
  54. package/dist/tools/get-arch-violations.tool.d.ts +3 -0
  55. package/dist/tools/get-arch-violations.tool.d.ts.map +1 -0
  56. package/dist/tools/get-arch-violations.tool.js +30 -0
  57. package/dist/tools/get-code-intelligence-state.tool.d.ts +11 -0
  58. package/dist/tools/get-code-intelligence-state.tool.d.ts.map +1 -0
  59. package/dist/tools/get-code-intelligence-state.tool.js +60 -0
  60. package/dist/tools/get-context-pack.tool.d.ts +3 -0
  61. package/dist/tools/get-context-pack.tool.d.ts.map +1 -0
  62. package/dist/tools/get-context-pack.tool.js +40 -0
  63. package/dist/tools/get-framework-entities.tool.d.ts +3 -0
  64. package/dist/tools/get-framework-entities.tool.d.ts.map +1 -0
  65. package/dist/tools/get-framework-entities.tool.js +68 -0
  66. package/dist/tools/get-graph-callers.tool.d.ts +3 -0
  67. package/dist/tools/get-graph-callers.tool.d.ts.map +1 -0
  68. package/dist/tools/get-graph-callers.tool.js +94 -0
  69. package/dist/tools/get-graph-context.tool.d.ts +3 -0
  70. package/dist/tools/get-graph-context.tool.d.ts.map +1 -0
  71. package/dist/tools/get-graph-context.tool.js +125 -0
  72. package/dist/tools/get-graph-cycles.tool.d.ts +10 -0
  73. package/dist/tools/get-graph-cycles.tool.d.ts.map +1 -0
  74. package/dist/tools/get-graph-cycles.tool.js +58 -0
  75. package/dist/tools/get-graph-deps.tool.d.ts +12 -0
  76. package/dist/tools/get-graph-deps.tool.d.ts.map +1 -0
  77. package/dist/tools/get-graph-deps.tool.js +80 -0
  78. package/dist/tools/get-graph-hubs.tool.d.ts +3 -0
  79. package/dist/tools/get-graph-hubs.tool.d.ts.map +1 -0
  80. package/dist/tools/get-graph-hubs.tool.js +61 -0
  81. package/dist/tools/get-graph-impact-analysis.tool.d.ts +3 -0
  82. package/dist/tools/get-graph-impact-analysis.tool.d.ts.map +1 -0
  83. package/dist/tools/get-graph-impact-analysis.tool.js +44 -0
  84. package/dist/tools/get-graph-impact.tool.d.ts +3 -0
  85. package/dist/tools/get-graph-impact.tool.d.ts.map +1 -0
  86. package/dist/tools/get-graph-impact.tool.js +150 -0
  87. package/dist/tools/get-graph-path.tool.d.ts +3 -0
  88. package/dist/tools/get-graph-path.tool.d.ts.map +1 -0
  89. package/dist/tools/get-graph-path.tool.js +144 -0
  90. package/dist/tools/get-graph-search.tool.d.ts +3 -0
  91. package/dist/tools/get-graph-search.tool.d.ts.map +1 -0
  92. package/dist/tools/get-graph-search.tool.js +95 -0
  93. package/dist/tools/get-graph-status.tool.d.ts +11 -0
  94. package/dist/tools/get-graph-status.tool.d.ts.map +1 -0
  95. package/dist/tools/get-graph-status.tool.js +55 -0
  96. package/dist/tools/get-graph-unresolved.tool.d.ts +11 -0
  97. package/dist/tools/get-graph-unresolved.tool.d.ts.map +1 -0
  98. package/dist/tools/get-graph-unresolved.tool.js +85 -0
  99. package/dist/tools/get-impact-baseline.tool.d.ts +9 -0
  100. package/dist/tools/get-impact-baseline.tool.d.ts.map +1 -0
  101. package/dist/tools/get-impact-baseline.tool.js +65 -0
  102. package/dist/tools/get-intent-benchmark-run.tool.d.ts +12 -0
  103. package/dist/tools/get-intent-benchmark-run.tool.d.ts.map +1 -0
  104. package/dist/tools/get-intent-benchmark-run.tool.js +55 -0
  105. package/dist/tools/get-knowledge-graph.tool.d.ts +7 -0
  106. package/dist/tools/get-knowledge-graph.tool.d.ts.map +1 -1
  107. package/dist/tools/get-knowledge-graph.tool.js +62 -3
  108. package/dist/tools/get-migrations.tool.d.ts +3 -0
  109. package/dist/tools/get-migrations.tool.d.ts.map +1 -0
  110. package/dist/tools/get-migrations.tool.js +70 -0
  111. package/dist/tools/get-pattern-registry.tool.d.ts +8 -0
  112. package/dist/tools/get-pattern-registry.tool.d.ts.map +1 -0
  113. package/dist/tools/get-pattern-registry.tool.js +40 -0
  114. package/dist/tools/get-quality-gate.tool.d.ts +3 -0
  115. package/dist/tools/get-quality-gate.tool.d.ts.map +1 -0
  116. package/dist/tools/get-quality-gate.tool.js +27 -0
  117. package/dist/tools/get-relevant-context.tool.d.ts.map +1 -1
  118. package/dist/tools/get-relevant-context.tool.js +30 -6
  119. package/dist/tools/get-rules-for-file.tool.d.ts +3 -0
  120. package/dist/tools/get-rules-for-file.tool.d.ts.map +1 -0
  121. package/dist/tools/get-rules-for-file.tool.js +54 -0
  122. package/dist/tools/get-structural-rewrite-plan.tool.d.ts +3 -0
  123. package/dist/tools/get-structural-rewrite-plan.tool.d.ts.map +1 -0
  124. package/dist/tools/get-structural-rewrite-plan.tool.js +46 -0
  125. package/dist/tools/get-structural-search.tool.d.ts +3 -0
  126. package/dist/tools/get-structural-search.tool.d.ts.map +1 -0
  127. package/dist/tools/get-structural-search.tool.js +35 -0
  128. package/dist/tools/get-task-packet.tool.d.ts.map +1 -1
  129. package/dist/tools/get-task-packet.tool.js +26 -22
  130. package/dist/tools/graph-staleness.d.ts +34 -0
  131. package/dist/tools/graph-staleness.d.ts.map +1 -0
  132. package/dist/tools/graph-staleness.js +36 -0
  133. package/dist/tools/list-boundary-rules.tool.d.ts.map +1 -1
  134. package/dist/tools/list-boundary-rules.tool.js +20 -16
  135. package/dist/tools/list-knowledge.tool.d.ts.map +1 -1
  136. package/dist/tools/list-knowledge.tool.js +14 -13
  137. package/dist/tools/list-packs.tool.d.ts.map +1 -1
  138. package/dist/tools/list-packs.tool.js +19 -15
  139. package/dist/tools/list-path-conventions.tool.d.ts.map +1 -1
  140. package/dist/tools/list-path-conventions.tool.js +19 -15
  141. package/dist/tools/list-pipelines.tool.d.ts.map +1 -1
  142. package/dist/tools/list-pipelines.tool.js +18 -14
  143. package/dist/tools/list-presets.tool.d.ts.map +1 -1
  144. package/dist/tools/list-presets.tool.js +25 -21
  145. package/dist/tools/list-rules.tool.d.ts.map +1 -1
  146. package/dist/tools/list-rules.tool.js +18 -14
  147. package/dist/tools/list-templates.tool.d.ts.map +1 -1
  148. package/dist/tools/list-templates.tool.js +18 -14
  149. package/dist/tools/plan-quality-review.tool.d.ts +21 -0
  150. package/dist/tools/plan-quality-review.tool.d.ts.map +1 -0
  151. package/dist/tools/plan-quality-review.tool.js +294 -0
  152. package/dist/tools/primary-tools.d.ts +24 -0
  153. package/dist/tools/primary-tools.d.ts.map +1 -0
  154. package/dist/tools/primary-tools.js +86 -0
  155. package/dist/tools/r19-extras.tool.js +1 -1
  156. package/dist/tools/r32-profiles.tool.d.ts +0 -3
  157. package/dist/tools/r32-profiles.tool.d.ts.map +1 -1
  158. package/dist/tools/r32-profiles.tool.js +3 -54
  159. package/dist/tools/retrieve-original.tool.d.ts +9 -0
  160. package/dist/tools/retrieve-original.tool.d.ts.map +1 -0
  161. package/dist/tools/retrieve-original.tool.js +47 -0
  162. package/dist/tools/runtime-reports.tool.d.ts.map +1 -1
  163. package/dist/tools/runtime-reports.tool.js +1 -3
  164. package/dist/tools/safety-audit.tool.d.ts.map +1 -1
  165. package/dist/tools/safety-audit.tool.js +1 -4
  166. package/dist/tools/search-knowledge.tool.d.ts.map +1 -1
  167. package/dist/tools/search-knowledge.tool.js +17 -13
  168. package/dist/tools/search.tool.d.ts.map +1 -1
  169. package/dist/tools/search.tool.js +11 -8
  170. package/dist/tools/smart-context-bundle.tool.d.ts +17 -0
  171. package/dist/tools/smart-context-bundle.tool.d.ts.map +1 -0
  172. package/dist/tools/smart-context-bundle.tool.js +110 -0
  173. package/dist/tools/smart-context-feed.tool.d.ts +17 -0
  174. package/dist/tools/smart-context-feed.tool.d.ts.map +1 -0
  175. package/dist/tools/smart-context-feed.tool.js +138 -0
  176. package/dist/tools/start-here.tool.js +2 -2
  177. package/package.json +28 -16
  178. package/dist/tools/r22-extras.tool.d.ts +0 -4
  179. package/dist/tools/r22-extras.tool.d.ts.map +0 -1
  180. package/dist/tools/r22-extras.tool.js +0 -42
  181. package/dist/tools/r26-ingest.tool.d.ts +0 -10
  182. package/dist/tools/r26-ingest.tool.d.ts.map +0 -1
  183. package/dist/tools/r26-ingest.tool.js +0 -174
  184. package/dist/tools/r28-plugin-lifecycle.tool.d.ts +0 -4
  185. package/dist/tools/r28-plugin-lifecycle.tool.d.ts.map +0 -1
  186. package/dist/tools/r28-plugin-lifecycle.tool.js +0 -94
  187. package/dist/tools/r34-search-unified.tool.d.ts +0 -3
  188. package/dist/tools/r34-search-unified.tool.d.ts.map +0 -1
  189. package/dist/tools/r34-search-unified.tool.js +0 -38
package/dist/index.d.ts CHANGED
@@ -5,4 +5,8 @@ export { ALL_TOOLS } from './tools/index.js';
5
5
  export type { IToolDefinition, IToolResponse, IToolContext, IMcpGateDecision, McpGateResolver, } from './server/tool-definition.js';
6
6
  export { MCP_PROTOCOL_VERSION, MCP_SERVER_NAME, MCP_SERVER_VERSION, } from './server/mcp-server-config.js';
7
7
  export { buildResourceList, readResource, parseResourceUri, knowledgeUri, templateUri, docUri, OVERVIEW_URI, AGENT_INSTRUCTIONS_URI, URI_SCHEME, } from './resources/index.js';
8
+ export { getRelevantContextTool } from './tools/get-relevant-context.tool.js';
9
+ export { getTaskPacketTool } from './tools/get-task-packet.tool.js';
10
+ export { prepareAgentTaskTool } from './tools/r33-agent-task-prep.tool.js';
11
+ export { COMMAND_CATALOG_EXPORT } from './tools/command-catalog.tool.js';
8
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,GACnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C,YAAY,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,MAAM,EACN,YAAY,EACZ,sBAAsB,EACtB,UAAU,GACX,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,GACnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C,YAAY,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,MAAM,EACN,YAAY,EACZ,sBAAsB,EACtB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC"}
package/dist/index.js CHANGED
@@ -4,3 +4,7 @@ export { startSharkcraftWatcher } from "./server/sharkcraft-watcher.js";
4
4
  export { ALL_TOOLS } from "./tools/index.js";
5
5
  export { MCP_PROTOCOL_VERSION, MCP_SERVER_NAME, MCP_SERVER_VERSION, } from "./server/mcp-server-config.js";
6
6
  export { buildResourceList, readResource, parseResourceUri, knowledgeUri, templateUri, docUri, OVERVIEW_URI, AGENT_INSTRUCTIONS_URI, URI_SCHEME, } from "./resources/index.js";
7
+ export { getRelevantContextTool } from "./tools/get-relevant-context.tool.js";
8
+ export { getTaskPacketTool } from "./tools/get-task-packet.tool.js";
9
+ export { prepareAgentTaskTool } from "./tools/r33-agent-task-prep.tool.js";
10
+ export { COMMAND_CATALOG_EXPORT } from "./tools/command-catalog.tool.js";
@@ -0,0 +1,34 @@
1
+ /**
2
+ * One-line explainer shipped alongside a columnar payload so an agent can decode
3
+ * it. Kept terse on purpose: this string is paid once per columnar response, so
4
+ * a shorter legend is a real per-response token saving — and a smaller fixed
5
+ * cost means the net-loss guard keeps `table` form on more (smaller) payloads.
6
+ */
7
+ export declare const COLUMNAR_LEGEND = "_table: rows[i] are values in cols order; absent=[row,col] keys to skip when rebuilding objects. If _table.dict[col] exists, that column\u2019s cells are integer indices into dict[col].";
8
+ /** Shared `format` input fragment for list tools that support columnar output. */
9
+ export declare const FORMAT_INPUT_PROPERTY: {
10
+ format: {
11
+ type: "string";
12
+ enum: readonly ["json", "table"];
13
+ description: string;
14
+ };
15
+ };
16
+ /** Whether a tool should emit columnar for this request. */
17
+ export declare function wantsTable(input: Record<string, unknown>): boolean;
18
+ /**
19
+ * Shape a list tool's homogeneous rows for output. `format:"table"` returns a
20
+ * columnar envelope (`{ format, legend, items }`) — still valid JSON but with
21
+ * the schema hoisted out of every row. Any other value returns the bare array
22
+ * unchanged (back-compat). If the rows don't qualify for compaction, the bare
23
+ * array is returned so callers always get valid data.
24
+ */
25
+ export declare function formatRows(rows: ReadonlyArray<Record<string, unknown>>, input: Record<string, unknown>): unknown;
26
+ /**
27
+ * Columnar-compact the top-level array fields of a result OBJECT (e.g. a graph
28
+ * query's `{ directDependents: [...], transitiveDependents: [...] }`) when the
29
+ * caller asked for `format:"table"`. Each compactable array becomes a columnar
30
+ * envelope; scalars, small arrays, and heterogeneous arrays are left as-is.
31
+ * Returns the original object unchanged when nothing compacted (back-compat).
32
+ */
33
+ export declare function formatObjectArrays(data: unknown, input: Record<string, unknown>): unknown;
34
+ //# sourceMappingURL=columnar-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"columnar-format.d.ts","sourceRoot":"","sources":["../../src/server/columnar-format.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,eAAO,MAAM,eAAe,8LAC4J,CAAC;AAEzL,kFAAkF;AAClF,eAAO,MAAM,qBAAqB;;;;;;CAOjC,CAAC;AAiBF,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAIlE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAQT;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CA0BzF"}
@@ -0,0 +1,95 @@
1
+ import { compactArrayToColumnar, estimateTokens, EContentType } from '@shrkcrft/compress';
2
+ /** Token cost of a value as minified JSON — the shape the wire serializes. */
3
+ function jsonTokens(value) {
4
+ return estimateTokens(JSON.stringify(value) ?? 'null', EContentType.Json);
5
+ }
6
+ /**
7
+ * One-line explainer shipped alongside a columnar payload so an agent can decode
8
+ * it. Kept terse on purpose: this string is paid once per columnar response, so
9
+ * a shorter legend is a real per-response token saving — and a smaller fixed
10
+ * cost means the net-loss guard keeps `table` form on more (smaller) payloads.
11
+ */
12
+ export const COLUMNAR_LEGEND = '_table: rows[i] are values in cols order; absent=[row,col] keys to skip when rebuilding objects. If _table.dict[col] exists, that column’s cells are integer indices into dict[col].';
13
+ /** Shared `format` input fragment for list tools that support columnar output. */
14
+ export const FORMAT_INPUT_PROPERTY = {
15
+ format: {
16
+ type: 'string',
17
+ enum: ['json', 'table'],
18
+ description: 'json: explicit object array. table: token-efficient columnar encoding (still valid JSON, schema hoisted, keys deduped) — recommended for large lists. Default is table; set SHRK_MCP_TABLE=0 on the server (or pass format:"json") for the explicit array.',
19
+ },
20
+ };
21
+ /** Deployment toggle: whether columnar `table` is the default wire shape.
22
+ * Default ON — every columnar-capable tool emits `table` so agents get the
23
+ * token savings without asking. Set `SHRK_MCP_TABLE=0` (or `false`/`no`/`off`)
24
+ * to opt out fleet-wide and restore the explicit-array shape for clients that
25
+ * need it. `format:"json"` always forces the explicit array per call,
26
+ * `format:"table"` always forces columnar — both override this default.
27
+ *
28
+ * Compaction itself is conservative: `compactArrayToColumnar` returns null for
29
+ * small / heterogeneous arrays, so default-on only reshapes payloads where the
30
+ * columnar form is an actual win; everything else stays a bare array. */
31
+ function tableIsDefault() {
32
+ const v = (process.env.SHRK_MCP_TABLE ?? '').toLowerCase();
33
+ return v !== '0' && v !== 'false' && v !== 'no' && v !== 'off';
34
+ }
35
+ /** Whether a tool should emit columnar for this request. */
36
+ export function wantsTable(input) {
37
+ if (input.format === 'table')
38
+ return true;
39
+ if (input.format === 'json')
40
+ return false;
41
+ return tableIsDefault();
42
+ }
43
+ /**
44
+ * Shape a list tool's homogeneous rows for output. `format:"table"` returns a
45
+ * columnar envelope (`{ format, legend, items }`) — still valid JSON but with
46
+ * the schema hoisted out of every row. Any other value returns the bare array
47
+ * unchanged (back-compat). If the rows don't qualify for compaction, the bare
48
+ * array is returned so callers always get valid data.
49
+ */
50
+ export function formatRows(rows, input) {
51
+ if (!wantsTable(input))
52
+ return rows;
53
+ const columnar = compactArrayToColumnar(rows);
54
+ if (!columnar)
55
+ return rows;
56
+ const candidate = { format: 'table', legend: COLUMNAR_LEGEND, items: columnar };
57
+ // Net-loss guard: the legend + envelope can exceed the bare array on a small
58
+ // list. Ship whichever is smaller so `format:"table"` never inflates a payload.
59
+ return jsonTokens(candidate) < jsonTokens(rows) ? candidate : rows;
60
+ }
61
+ /**
62
+ * Columnar-compact the top-level array fields of a result OBJECT (e.g. a graph
63
+ * query's `{ directDependents: [...], transitiveDependents: [...] }`) when the
64
+ * caller asked for `format:"table"`. Each compactable array becomes a columnar
65
+ * envelope; scalars, small arrays, and heterogeneous arrays are left as-is.
66
+ * Returns the original object unchanged when nothing compacted (back-compat).
67
+ */
68
+ export function formatObjectArrays(data, input) {
69
+ if (!wantsTable(input) || data === null || typeof data !== 'object' || Array.isArray(data)) {
70
+ return data;
71
+ }
72
+ const src = data;
73
+ const out = {};
74
+ let compacted = false;
75
+ for (const [key, value] of Object.entries(src)) {
76
+ if (Array.isArray(value)) {
77
+ const table = compactArrayToColumnar(value);
78
+ // Per-array net-loss guard: only hoist an array whose columnar form is
79
+ // actually smaller — a tiny array loses to its own hoisted schema header.
80
+ if (table && jsonTokens(table) < jsonTokens(value)) {
81
+ out[key] = table;
82
+ compacted = true;
83
+ continue;
84
+ }
85
+ }
86
+ out[key] = value;
87
+ }
88
+ if (!compacted)
89
+ return data;
90
+ const candidate = { _format: 'table', _legend: COLUMNAR_LEGEND, ...out };
91
+ // Overall net-loss guard: the shared legend must not push the whole payload
92
+ // above the bare object — table mode never inflates (the "never a negative
93
+ // saving" promise the dashboard makes).
94
+ return jsonTokens(candidate) < jsonTokens(data) ? candidate : data;
95
+ }
@@ -1,5 +1,6 @@
1
1
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { type ISharkcraftInspection } from '@shrkcrft/inspector';
3
+ import { type ICcrStore } from '@shrkcrft/compress';
3
4
  import { type IMcpServerConfig } from './mcp-server-config.js';
4
5
  import type { IToolDefinition, McpGateResolver } from './tool-definition.js';
5
6
  export interface StartMcpServerOptions {
@@ -40,6 +41,8 @@ interface ServerState {
40
41
  toolsByName: Map<string, IToolDefinition>;
41
42
  /** Optional tier-gate resolver. */
42
43
  gateResolver?: McpGateResolver;
44
+ /** In-memory CCR store shared across this server's tool calls. */
45
+ ccrStore: ICcrStore;
43
46
  }
44
47
  /**
45
48
  * Resolve which directory the MCP server should treat as the target project.
@@ -1 +1 @@
1
- {"version":3,"file":"create-mcp-server.d.ts","sourceRoot":"","sources":["../../src/server/create-mcp-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAQnE,OAAO,EAAqB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,eAAe,EAEf,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED,MAAM,WAAW,6BAA8B,SAAQ,gBAAgB;IACrE,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACzC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,mCAAmC;IACnC,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,MAAM,CAIR;AAqBD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,6BAA6B,GAAG;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;CACpB,CAqHA;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEvF"}
1
+ {"version":3,"file":"create-mcp-server.d.ts","sourceRoot":"","sources":["../../src/server/create-mcp-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAQnE,OAAO,EAAqB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,eAAe,EAEf,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAM9B,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED,MAAM,WAAW,6BAA8B,SAAQ,gBAAgB;IACrE,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACzC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,mCAAmC;IACnC,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,MAAM,CAIR;AAqBD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,6BAA6B,GAAG;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;CACpB,CAiIA;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEvF"}
@@ -3,8 +3,11 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { inspectSharkcraft } from '@shrkcrft/inspector';
6
+ import { InMemoryCcrStore } from '@shrkcrft/compress';
7
+ import { serializeToolData } from "./serialize-tool-data.js";
6
8
  import { MCP_SERVER_NAME, MCP_SERVER_VERSION, } from "./mcp-server-config.js";
7
9
  import { ALL_TOOLS } from "../tools/index.js";
10
+ import { PRIMARY_MCP_TOOLS, shouldAdvertiseFullToolset } from "../tools/primary-tools.js";
8
11
  import { validateToolInput } from "./tool-input-validators.js";
9
12
  import { buildResourceList, readResource } from "../resources/index.js";
10
13
  /**
@@ -26,7 +29,7 @@ function toolResponseToCallResult(response) {
26
29
  if (response.text)
27
30
  content.push({ type: 'text', text: response.text });
28
31
  if (response.data !== undefined) {
29
- content.push({ type: 'text', text: JSON.stringify(response.data, null, 2) });
32
+ content.push({ type: 'text', text: serializeToolData(response.data) });
30
33
  }
31
34
  if (content.length === 0)
32
35
  content.push({ type: 'text', text: '(empty)' });
@@ -44,6 +47,7 @@ export function createSharkcraftServer(config) {
44
47
  config: effectiveConfig,
45
48
  inspection: null,
46
49
  toolsByName: new Map(ALL_TOOLS.map((t) => [t.name, t])),
50
+ ccrStore: new InMemoryCcrStore(),
47
51
  ...(config.gateResolver ? { gateResolver: config.gateResolver } : {}),
48
52
  };
49
53
  const server = new Server({ name: effectiveConfig.name, version: effectiveConfig.version }, {
@@ -52,13 +56,24 @@ export function createSharkcraftServer(config) {
52
56
  resources: { listChanged: true },
53
57
  },
54
58
  });
55
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
56
- tools: ALL_TOOLS.map((t) => ({
57
- name: t.name,
58
- description: t.description,
59
- inputSchema: t.inputSchema,
60
- })),
61
- }));
59
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
60
+ // Default `tools/list` advertises only the ~30 primary tools to
61
+ // keep the agent's tool-selection surface focused. The other ~200
62
+ // tools stay CALLABLE via `tools/call` for agents that already
63
+ // know the name (e.g. via `shrk export claude-skill` referencing
64
+ // them). Set SHRK_MCP_FULL_TOOLS=1 to advertise everything.
65
+ const advertiseFull = shouldAdvertiseFullToolset();
66
+ const advertised = advertiseFull
67
+ ? ALL_TOOLS
68
+ : ALL_TOOLS.filter((t) => PRIMARY_MCP_TOOLS.has(t.name));
69
+ return {
70
+ tools: advertised.map((t) => ({
71
+ name: t.name,
72
+ description: t.description,
73
+ inputSchema: t.inputSchema,
74
+ })),
75
+ };
76
+ });
62
77
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
63
78
  const name = request.params.name;
64
79
  const args = (request.params.arguments ?? {});
@@ -112,7 +127,7 @@ export function createSharkcraftServer(config) {
112
127
  }
113
128
  try {
114
129
  const inspection = await loadInspection(state);
115
- const response = await tool.handler(validation.data, { inspection, cwd: state.config.cwd });
130
+ const response = await tool.handler(validation.data, { inspection, cwd: state.config.cwd, allTools: ALL_TOOLS, ccrStore: state.ccrStore });
116
131
  return toolResponseToCallResult(response);
117
132
  }
118
133
  catch (e) {
@@ -0,0 +1,24 @@
1
+ import { type ICcrStore } from '@shrkcrft/compress';
2
+ export interface IFittedArray {
3
+ /** The array shaped for output: lossless columnar, or a lossy sample. */
4
+ value: unknown;
5
+ /** Set when a lossy sample was taken — the CCR key for the cached original. */
6
+ ccrKey?: string;
7
+ }
8
+ /**
9
+ * Fit a homogeneous object array to an optional token budget (P5.2).
10
+ *
11
+ * - No budget (or under budget): the lossless columnar form.
12
+ * - Over budget: the SmartCrusher row-sample (representative rows kept, the
13
+ * rest dropped) with the FULL original cached in `store` — the agent can
14
+ * `retrieve_original` with the returned `ccrKey`.
15
+ *
16
+ * `compressJson({ maxTokens })` owns the lossless-vs-lossy DECISION, but its
17
+ * sampler keep-count is not derived from the budget, so a single sample can
18
+ * still exceed `maxTokens`. We therefore binary-search the row cap so the
19
+ * emitted payload actually fits the budget (down to a 1-row floor — a single
20
+ * row's columnar envelope may still exceed a very small budget, which is the
21
+ * best achievable while keeping any data).
22
+ */
23
+ export declare function fitArrayToBudget(array: readonly unknown[], maxTokens: number | undefined, store?: ICcrStore): IFittedArray;
24
+ //# sourceMappingURL=fit-array-to-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fit-array-to-budget.d.ts","sourceRoot":"","sources":["../../src/server/fit-array-to-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,CAAC,EAAE,SAAS,GAChB,YAAY,CA2Cd"}
@@ -0,0 +1,60 @@
1
+ import { compactArrayToColumnar, compressJson, estimateTokens, EContentType, } from '@shrkcrft/compress';
2
+ /**
3
+ * Fit a homogeneous object array to an optional token budget (P5.2).
4
+ *
5
+ * - No budget (or under budget): the lossless columnar form.
6
+ * - Over budget: the SmartCrusher row-sample (representative rows kept, the
7
+ * rest dropped) with the FULL original cached in `store` — the agent can
8
+ * `retrieve_original` with the returned `ccrKey`.
9
+ *
10
+ * `compressJson({ maxTokens })` owns the lossless-vs-lossy DECISION, but its
11
+ * sampler keep-count is not derived from the budget, so a single sample can
12
+ * still exceed `maxTokens`. We therefore binary-search the row cap so the
13
+ * emitted payload actually fits the budget (down to a 1-row floor — a single
14
+ * row's columnar envelope may still exceed a very small budget, which is the
15
+ * best achievable while keeping any data).
16
+ */
17
+ export function fitArrayToBudget(array, maxTokens, store) {
18
+ const columnar = compactArrayToColumnar(array) ?? array;
19
+ if (!maxTokens || maxTokens <= 0)
20
+ return { value: columnar };
21
+ const json = JSON.stringify(array);
22
+ const run = (maxItems) => {
23
+ const r = compressJson(json, {
24
+ maxTokens,
25
+ ...(maxItems !== undefined ? { maxItems } : {}),
26
+ ...(store ? { store } : {}),
27
+ });
28
+ // A CCR key is set only on the lossy sample path; under budget the result
29
+ // is the lossless form, so the caller falls back to the columnar value.
30
+ if (!r.ccrKey)
31
+ return null;
32
+ const firstLine = r.compressed.split('\n')[0] ?? 'null';
33
+ return { value: JSON.parse(firstLine), ccrKey: r.ccrKey };
34
+ };
35
+ const fits = (fitted) => estimateTokens(JSON.stringify(fitted.value), EContentType.JsonArray) <= maxTokens;
36
+ // Default sample (no cap). Null → under budget, emit the lossless form.
37
+ const initial = run();
38
+ if (!initial)
39
+ return { value: columnar };
40
+ if (fits(initial))
41
+ return initial;
42
+ // Largest row cap whose sampled payload still fits the budget.
43
+ let lo = 1;
44
+ let hi = array.length;
45
+ let best = null;
46
+ while (lo <= hi) {
47
+ const mid = Math.floor((lo + hi) / 2);
48
+ const candidate = run(mid);
49
+ if (candidate && fits(candidate)) {
50
+ best = candidate;
51
+ lo = mid + 1;
52
+ }
53
+ else {
54
+ hi = mid - 1;
55
+ }
56
+ }
57
+ // Even one row over budget → keep the smallest sample (best effort, still
58
+ // recoverable via ccrKey) rather than the much larger default sample.
59
+ return best ?? run(1) ?? initial;
60
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Serialize a tool's structured `data` into the text the MCP wire carries.
3
+ *
4
+ * The default is **minified** JSON: still valid JSON (identical shape, so
5
+ * JSON-parsing clients are unaffected), but without the pretty-print
6
+ * indentation that every `JSON.stringify(data, null, 2)` paid for. Across
7
+ * ~200 tools that indentation is pure token overhead an agent reads and pays
8
+ * for. Set `SHRK_MCP_PRETTY=1` to restore indented output for debugging.
9
+ *
10
+ * This transform is lossless and structure-preserving by design. Lossy /
11
+ * shape-changing compaction (columnar tables, CCR offload) is opt-in per
12
+ * tool, never applied blindly here.
13
+ */
14
+ export declare function serializeToolData(data: unknown): string;
15
+ //# sourceMappingURL=serialize-tool-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize-tool-data.d.ts","sourceRoot":"","sources":["../../src/server/serialize-tool-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAGvD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Serialize a tool's structured `data` into the text the MCP wire carries.
3
+ *
4
+ * The default is **minified** JSON: still valid JSON (identical shape, so
5
+ * JSON-parsing clients are unaffected), but without the pretty-print
6
+ * indentation that every `JSON.stringify(data, null, 2)` paid for. Across
7
+ * ~200 tools that indentation is pure token overhead an agent reads and pays
8
+ * for. Set `SHRK_MCP_PRETTY=1` to restore indented output for debugging.
9
+ *
10
+ * This transform is lossless and structure-preserving by design. Lossy /
11
+ * shape-changing compaction (columnar tables, CCR offload) is opt-in per
12
+ * tool, never applied blindly here.
13
+ */
14
+ export function serializeToolData(data) {
15
+ if (wantsPretty())
16
+ return JSON.stringify(data, null, 2) ?? 'null';
17
+ return JSON.stringify(data) ?? 'null';
18
+ }
19
+ function wantsPretty() {
20
+ const v = process.env.SHRK_MCP_PRETTY;
21
+ return v === '1' || v === 'true' || v === 'yes';
22
+ }
@@ -1,4 +1,5 @@
1
1
  import type { ISharkcraftInspection } from '@shrkcrft/inspector';
2
+ import type { ICcrStore } from '@shrkcrft/compress';
2
3
  export interface IToolJsonSchema {
3
4
  type: 'object';
4
5
  properties?: Record<string, unknown>;
@@ -8,6 +9,20 @@ export interface IToolJsonSchema {
8
9
  export interface IToolContext {
9
10
  inspection: ISharkcraftInspection;
10
11
  cwd: string;
12
+ /**
13
+ * The full list of tools registered in the server. Tools that need
14
+ * to self-reflect (e.g. `get_safety_audit`) use this instead of
15
+ * importing `ALL_TOOLS` from the tool-registry to avoid import cycles.
16
+ */
17
+ allTools?: readonly IToolDefinition[];
18
+ /**
19
+ * Per-server in-memory Compress-Cache-Retrieve store. The
20
+ * `compress_context` tool caches originals here and `retrieve_original`
21
+ * reads them back. In-memory only — the MCP server never writes to disk,
22
+ * honouring the read-only contract. Absent in unit tests that construct a
23
+ * bare context.
24
+ */
25
+ ccrStore?: ICcrStore;
11
26
  }
12
27
  export interface IToolDefinition {
13
28
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-definition.d.ts","sourceRoot":"","sources":["../../src/server/tool-definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,qBAAqB,CAAC;IAClC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,eAAe,CAAC;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;IAC3G;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,eAAe,KAAK,gBAAgB,GAAG,IAAI,CAAC;AAEjF,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB"}
1
+ {"version":3,"file":"tool-definition.d.ts","sourceRoot":"","sources":["../../src/server/tool-definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,qBAAqB,CAAC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,eAAe,CAAC;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;IAC3G;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,eAAe,KAAK,gBAAgB,GAAG,IAAI,CAAC;AAEjF,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-input-validators.d.ts","sourceRoot":"","sources":["../../src/server/tool-input-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwFxB,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAgBpE,CAAC;AAEH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAkB9E"}
1
+ {"version":3,"file":"tool-input-validators.d.ts","sourceRoot":"","sources":["../../src/server/tool-input-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmIxB,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAsBpE,CAAC;AAEH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAkB9E"}
@@ -38,6 +38,7 @@ const getRelevantContextSchema = z
38
38
  includeRules: z.boolean().optional(),
39
39
  includePaths: z.boolean().optional(),
40
40
  includeDocs: z.boolean().optional(),
41
+ compact: z.boolean().optional(),
41
42
  })
42
43
  .strict();
43
44
  const getRelevantRulesSchema = z
@@ -75,6 +76,42 @@ const getPipelineContextSchema = z
75
76
  scope: z.array(z.string()).optional(),
76
77
  })
77
78
  .strict();
79
+ const compressContextSchema = z
80
+ .object({
81
+ content: z.string().min(1, 'content is required'),
82
+ contentType: z.string().optional(),
83
+ query: z.string().optional(),
84
+ maxItems: z.number().int().min(1).optional(),
85
+ // Arms the lossy SmartCrusher row-sampler for oversized homogeneous arrays.
86
+ // Must mirror the tool's inputSchema, or the strict validator rejects the
87
+ // call on the real MCP wire before the handler ever runs.
88
+ maxTokens: z.number().int().min(1).optional(),
89
+ })
90
+ .strict();
91
+ const retrieveOriginalSchema = z.object({ key: z.string().min(1, 'key is required') }).strict();
92
+ const alignCacheSchema = z
93
+ .object({ content: z.string().min(1, 'content is required'), map: z.unknown().optional() })
94
+ .strict();
95
+ const restoreCacheSchema = z
96
+ .object({ content: z.string(), map: z.unknown() })
97
+ .strict();
98
+ const getKnowledgeGraphSchema = z
99
+ .object({
100
+ format: z.enum(['json', 'table']).optional(),
101
+ // Mirrors the tool's inputSchema (P5.2). Must stay in lockstep, or the
102
+ // schema-parity guard (schema-parity.test.ts) turns red.
103
+ maxTokens: z.number().int().min(1).optional(),
104
+ })
105
+ .strict();
106
+ // deps_audit advertises package/format/maxTokens; validate them on the wire so
107
+ // the new lossy `maxTokens` budget can't be armed with a bad value (P5.2/P1.3).
108
+ const depsAuditSchema = z
109
+ .object({
110
+ package: z.string().optional(),
111
+ format: z.enum(['json', 'table']).optional(),
112
+ maxTokens: z.number().int().min(1).optional(),
113
+ })
114
+ .strict();
78
115
  export const TOOL_INPUT_SCHEMAS = Object.freeze({
79
116
  create_generation_plan: createGenerationPlanSchema,
80
117
  render_template_preview: renderTemplatePreviewSchema,
@@ -91,6 +128,12 @@ export const TOOL_INPUT_SCHEMAS = Object.freeze({
91
128
  get_pipeline_context: getPipelineContextSchema,
92
129
  get_pack: getPackSchema,
93
130
  create_pipeline_plan: createPipelinePlanSchema,
131
+ compress_context: compressContextSchema,
132
+ retrieve_original: retrieveOriginalSchema,
133
+ align_cache: alignCacheSchema,
134
+ restore_cache: restoreCacheSchema,
135
+ get_knowledge_graph: getKnowledgeGraphSchema,
136
+ deps_audit: depsAuditSchema,
94
137
  });
95
138
  export function validateToolInput(toolName, input) {
96
139
  const schema = TOOL_INPUT_SCHEMAS[toolName];
@@ -1 +1 @@
1
- {"version":3,"file":"agent-brief.tool.d.ts","sourceRoot":"","sources":["../../src/tools/agent-brief.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE,eAAO,MAAM,oBAAoB,EAAE,eA2ClC,CAAC"}
1
+ {"version":3,"file":"agent-brief.tool.d.ts","sourceRoot":"","sources":["../../src/tools/agent-brief.tool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE,eAAO,MAAM,oBAAoB,EAAE,eA+DlC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { buildAgentBrief, BriefMode } from '@shrkcrft/inspector';
2
+ import { compressMarkdown } from '@shrkcrft/compress';
2
3
  const VALID_MODES = new Set(Object.values(BriefMode));
3
4
  export const createAgentBriefTool = {
4
5
  name: 'create_agent_brief',
@@ -14,6 +15,10 @@ export const createAgentBriefTool = {
14
15
  maxTokens: { type: 'number' },
15
16
  chunked: { type: 'boolean' },
16
17
  sectionBudgets: { type: 'object' },
18
+ compact: {
19
+ type: 'boolean',
20
+ description: 'Run the brief markdown through the deterministic markdown compressor (headers/leads/structure kept, prose thinned). Reversible — the original is cached and a `<<ccr:KEY>>` marker emitted (retrieve_original to recover).',
21
+ },
17
22
  },
18
23
  additionalProperties: false,
19
24
  },
@@ -39,6 +44,21 @@ export const createAgentBriefTool = {
39
44
  ...(chunked ? { chunked: true } : {}),
40
45
  ...(sectionBudgets ? { sectionBudgets } : {}),
41
46
  });
47
+ if (input['compact'] === true) {
48
+ const c = compressMarkdown(brief.markdown, ctx.ccrStore ? { store: ctx.ccrStore } : {});
49
+ return {
50
+ data: {
51
+ ...brief,
52
+ markdown: c.compressed,
53
+ compaction: {
54
+ strategy: c.strategy,
55
+ tokensBefore: c.savings.before,
56
+ tokensAfter: c.savings.after,
57
+ ccrKey: c.ccrKey ?? null,
58
+ },
59
+ },
60
+ };
61
+ }
42
62
  return { data: brief };
43
63
  },
44
64
  };
@@ -0,0 +1,11 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Active cache-aligner: replace volatile tokens with stable placeholders so a
4
+ * provider KV-cache prefix stays steady across turns. Returns the map in the
5
+ * payload (never writes disk) so the host carries it forward — honouring
6
+ * MCP-never-writes. Reversible via `restore_cache`.
7
+ */
8
+ export declare const alignCacheTool: IToolDefinition;
9
+ /** The restore half of {@link alignCacheTool}. Read-only. */
10
+ export declare const restoreCacheTool: IToolDefinition;
11
+ //# sourceMappingURL=align-cache.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"align-cache.tool.d.ts","sourceRoot":"","sources":["../../src/tools/align-cache.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AASpE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,eAkC5B,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,EAAE,eA0B9B,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { alignVolatileTokens, restoreVolatileTokens } from '@shrkcrft/compress';
2
+ function asAlignmentMap(value) {
3
+ if (typeof value !== 'object' || value === null)
4
+ return undefined;
5
+ const m = value;
6
+ if (m.version !== 1 || !Array.isArray(m.bindings))
7
+ return undefined;
8
+ return value;
9
+ }
10
+ /**
11
+ * Active cache-aligner: replace volatile tokens with stable placeholders so a
12
+ * provider KV-cache prefix stays steady across turns. Returns the map in the
13
+ * payload (never writes disk) so the host carries it forward — honouring
14
+ * MCP-never-writes. Reversible via `restore_cache`.
15
+ */
16
+ export const alignCacheTool = {
17
+ name: 'align_cache',
18
+ description: 'Replace volatile tokens (UUIDs, JWTs, ISO timestamps, hashes, epochs) in a blob with stable `«vk:…»` placeholders so a provider KV-cache prefix stays stable across turns — same information, fewer cache-busting tokens. Returns the aligned text plus a map; pass the map back in next turn (and to `restore_cache`) so placeholders stay stable. Deterministic, reversible, no model. Read-only.',
19
+ inputSchema: {
20
+ type: 'object',
21
+ properties: {
22
+ content: { type: 'string', description: 'The text to align.' },
23
+ map: { type: 'object', description: 'A prior alignment map to carry forward (optional).' },
24
+ },
25
+ required: ['content'],
26
+ additionalProperties: false,
27
+ },
28
+ handler(input) {
29
+ const content = typeof input.content === 'string' ? input.content : '';
30
+ if (content.length === 0) {
31
+ return {
32
+ isError: true,
33
+ text: 'align_cache requires a non-empty "content" string.',
34
+ error: { code: 'invalid-input', message: 'content is required' },
35
+ };
36
+ }
37
+ const prior = asAlignmentMap(input.map);
38
+ const result = alignVolatileTokens(content, prior);
39
+ return {
40
+ data: {
41
+ aligned: result.aligned,
42
+ map: result.map,
43
+ replaced: result.replaced,
44
+ restoreWith: 'restore_cache { "content": "<aligned>", "map": <map> }',
45
+ },
46
+ text: result.aligned,
47
+ };
48
+ },
49
+ };
50
+ /** The restore half of {@link alignCacheTool}. Read-only. */
51
+ export const restoreCacheTool = {
52
+ name: 'restore_cache',
53
+ description: 'Reverse `align_cache`: restore the original volatile tokens in an aligned blob using its map. Lossless. Read-only.',
54
+ inputSchema: {
55
+ type: 'object',
56
+ properties: {
57
+ content: { type: 'string', description: 'Aligned text containing `«vk:…»` placeholders.' },
58
+ map: { type: 'object', description: 'The alignment map returned by `align_cache`.' },
59
+ },
60
+ required: ['content', 'map'],
61
+ additionalProperties: false,
62
+ },
63
+ handler(input) {
64
+ const content = typeof input.content === 'string' ? input.content : '';
65
+ const map = asAlignmentMap(input.map);
66
+ if (!map) {
67
+ return {
68
+ isError: true,
69
+ text: 'restore_cache requires the `map` returned by align_cache.',
70
+ error: { code: 'invalid-input', message: 'a valid alignment map is required' },
71
+ };
72
+ }
73
+ const restored = restoreVolatileTokens(content, map);
74
+ return { data: { restored }, text: restored };
75
+ },
76
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"all-tools.d.ts","sourceRoot":"","sources":["../../src/tools/all-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAmTpE,eAAO,MAAM,SAAS,EAAE,SAAS,eAAe,EA6P9C,CAAC"}
1
+ {"version":3,"file":"all-tools.d.ts","sourceRoot":"","sources":["../../src/tools/all-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAkVpE,eAAO,MAAM,SAAS,EAAE,SAAS,eAAe,EA4R9C,CAAC"}