@descent-vtt/spec-guard 0.6.0 → 0.7.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.
- package/CHANGELOG.md +75 -8
- package/README.md +86 -1
- package/dist/cli.d.ts +17 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +126 -7
- package/dist/cli.js.map +1 -1
- package/dist/glob.d.ts +17 -2
- package/dist/glob.d.ts.map +1 -1
- package/dist/glob.js +25 -9
- package/dist/glob.js.map +1 -1
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +117 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +544 -0
- package/dist/mcp.js.map +1 -0
- package/dist/parser.d.ts +25 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +54 -15
- package/dist/parser.js.map +1 -1
- package/dist/query.d.ts +108 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +206 -0
- package/dist/query.js.map +1 -0
- package/dist/rules.d.ts +108 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +153 -0
- package/dist/rules.js.map +1 -0
- package/dist/runner.d.ts +16 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +108 -88
- package/dist/runner.js.map +1 -1
- package/dist/specs.d.ts +44 -0
- package/dist/specs.d.ts.map +1 -0
- package/dist/specs.js +62 -0
- package/dist/specs.js.map +1 -0
- package/package.json +1 -1
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `spec-guard mcp`: the rules, served to an agent over the Model Context
|
|
3
|
+
* Protocol on stdio.
|
|
4
|
+
*
|
|
5
|
+
* No SDK. MCP over stdio is JSON-RPC 2.0, one message per line, and what a
|
|
6
|
+
* server has to get right fits in this file: framing, the two eras of the
|
|
7
|
+
* protocol, and four methods' worth of results. The official SDK brings a
|
|
8
|
+
* schema library and a dependency tree to do the same, and spec-guard's first
|
|
9
|
+
* invariant is that it has no runtime dependencies at all. ADR-0012 has the
|
|
10
|
+
* rest, including what this file deliberately does not implement.
|
|
11
|
+
*
|
|
12
|
+
* Two eras, served side by side. Revisions up to 2025-11-25 open with an
|
|
13
|
+
* `initialize` handshake; 2026-07-28 has none, and every request carries its
|
|
14
|
+
* protocol version in `_meta`. Clients of both are in use, so each request is
|
|
15
|
+
* classified on its own - by the rule the TypeScript SDK's server applies, not
|
|
16
|
+
* by one invented here: a request that claims a version in `_meta` is modern
|
|
17
|
+
* and its claim is validated; anything else, `initialize` included, is legacy.
|
|
18
|
+
*/
|
|
19
|
+
import { promises as fs } from 'node:fs';
|
|
20
|
+
import { toPosix } from './glob.js';
|
|
21
|
+
import { formatReport } from './reporter.js';
|
|
22
|
+
import { elapsed, runSpecGuard } from './runner.js';
|
|
23
|
+
import { answerQuery, formatQuery, inQueriedPaths, loadRuleSet, QueryPathError, resolveQueryPath, viewDocument, } from './query.js';
|
|
24
|
+
import { governs, viewRule } from './rules.js';
|
|
25
|
+
/* ----------------------------------------------------------------- protocol */
|
|
26
|
+
/** Revisions that carry their version on every request. Newest first. */
|
|
27
|
+
export const MODERN_PROTOCOL_VERSIONS = ['2026-07-28'];
|
|
28
|
+
/** Revisions negotiated by `initialize`, newest first - the SDK's own list. */
|
|
29
|
+
export const LEGACY_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05', '2024-10-07'];
|
|
30
|
+
export const PROTOCOL_VERSION_KEY = 'io.modelcontextprotocol/protocolVersion';
|
|
31
|
+
export const CLIENT_CAPABILITIES_KEY = 'io.modelcontextprotocol/clientCapabilities';
|
|
32
|
+
export const CLIENT_INFO_KEY = 'io.modelcontextprotocol/clientInfo';
|
|
33
|
+
export const SERVER_INFO_KEY = 'io.modelcontextprotocol/serverInfo';
|
|
34
|
+
export const PARSE_ERROR = -32700;
|
|
35
|
+
export const INVALID_REQUEST = -32600;
|
|
36
|
+
export const METHOD_NOT_FOUND = -32601;
|
|
37
|
+
export const INVALID_PARAMS = -32602;
|
|
38
|
+
export const INTERNAL_ERROR = -32603;
|
|
39
|
+
/** Resource not found before 2026-07-28, which forbids it in favour of -32602. */
|
|
40
|
+
export const LEGACY_RESOURCE_NOT_FOUND = -32002;
|
|
41
|
+
export const UNSUPPORTED_PROTOCOL_VERSION = -32022;
|
|
42
|
+
class ProtocolError extends Error {
|
|
43
|
+
code;
|
|
44
|
+
data;
|
|
45
|
+
constructor(code, message, data) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.code = code;
|
|
48
|
+
this.data = data;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function isObject(value) {
|
|
52
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
53
|
+
}
|
|
54
|
+
/** JSON-RPC allows a null id; MCP does not, and requires an integer if a number. */
|
|
55
|
+
function isRequestId(value) {
|
|
56
|
+
return typeof value === 'string' || Number.isInteger(value);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* What is wrong with a request's `_meta`, once it claims a protocol version.
|
|
60
|
+
*
|
|
61
|
+
* Only what the server depends on or the revision requires: a version that is a
|
|
62
|
+
* string, capabilities that are an object, and client info shaped as client info
|
|
63
|
+
* when it is sent. A claim is never silently ignored - a malformed one is an
|
|
64
|
+
* error, not a reason to fall back to legacy handling.
|
|
65
|
+
*/
|
|
66
|
+
export function envelopeIssue(meta) {
|
|
67
|
+
if (!(CLIENT_CAPABILITIES_KEY in meta))
|
|
68
|
+
return `${CLIENT_CAPABILITIES_KEY}: missing`;
|
|
69
|
+
if (typeof meta[PROTOCOL_VERSION_KEY] !== 'string')
|
|
70
|
+
return `${PROTOCOL_VERSION_KEY}: expected a string`;
|
|
71
|
+
if (!isObject(meta[CLIENT_CAPABILITIES_KEY]))
|
|
72
|
+
return `${CLIENT_CAPABILITIES_KEY}: expected an object`;
|
|
73
|
+
const info = meta[CLIENT_INFO_KEY];
|
|
74
|
+
if (info !== undefined && !(isObject(info) && typeof info['name'] === 'string' && typeof info['version'] === 'string')) {
|
|
75
|
+
return `${CLIENT_INFO_KEY}: expected an object with a string name and version`;
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The era a request belongs to, or the error that answers it instead.
|
|
81
|
+
*
|
|
82
|
+
* `initialize` is the legacy handshake unless it carries a valid modern claim.
|
|
83
|
+
* Any other request is modern exactly when `_meta` holds the version key - its
|
|
84
|
+
* presence is the claim, whatever its value - and legacy otherwise.
|
|
85
|
+
*/
|
|
86
|
+
export function classifyRequest(method, params) {
|
|
87
|
+
const meta = params?.['_meta'];
|
|
88
|
+
const claimed = isObject(meta) && PROTOCOL_VERSION_KEY in meta;
|
|
89
|
+
if (!claimed)
|
|
90
|
+
return 'legacy';
|
|
91
|
+
const issue = envelopeIssue(meta);
|
|
92
|
+
const version = meta[PROTOCOL_VERSION_KEY];
|
|
93
|
+
const supported = issue === undefined && MODERN_PROTOCOL_VERSIONS.includes(version);
|
|
94
|
+
if (method === 'initialize' && !supported)
|
|
95
|
+
return 'legacy';
|
|
96
|
+
if (issue !== undefined)
|
|
97
|
+
throw new ProtocolError(INVALID_PARAMS, `Invalid _meta envelope: ${issue}`);
|
|
98
|
+
if (!supported) {
|
|
99
|
+
throw new ProtocolError(UNSUPPORTED_PROTOCOL_VERSION, 'Unsupported protocol version', {
|
|
100
|
+
supported: [...MODERN_PROTOCOL_VERSIONS],
|
|
101
|
+
requested: version,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return 'modern';
|
|
105
|
+
}
|
|
106
|
+
/** The version `initialize` settles on: the one asked for, or the newest legacy one. */
|
|
107
|
+
export function negotiateLegacyVersion(requested) {
|
|
108
|
+
// No typeof check: a list of strings includes nothing that is not one.
|
|
109
|
+
return LEGACY_PROTOCOL_VERSIONS.includes(requested) ? requested : LEGACY_PROTOCOL_VERSIONS[0];
|
|
110
|
+
}
|
|
111
|
+
/* -------------------------------------------------------------- the surface */
|
|
112
|
+
export const SERVER_NAME = 'spec-guard';
|
|
113
|
+
export const INSTRUCTIONS = 'spec-guard enforces the architecture decisions written in this project\'s Markdown specs and ADRs. ' +
|
|
114
|
+
'Before creating or changing a file, call get_architectural_rules with its path to learn the rules in force there: ' +
|
|
115
|
+
'imports it must not make, the layer it belongs to, text it must not contain. ' +
|
|
116
|
+
'After changing files, call check_architecture with their paths to find violations before CI does. ' +
|
|
117
|
+
'Rules in draft, proposed, rejected, deprecated or superseded documents are not in force and are only counted.';
|
|
118
|
+
const READ_ONLY = { readOnlyHint: true, idempotentHint: true, openWorldHint: false };
|
|
119
|
+
export const TOOLS = [
|
|
120
|
+
{
|
|
121
|
+
name: 'get_architectural_rules',
|
|
122
|
+
title: 'Architectural rules for a path',
|
|
123
|
+
description: 'Lists the architecture rules in force for a file or directory, grouped by the ADR or spec that states them: ' +
|
|
124
|
+
'modules it must not import, the layer it belongs to and the layers it must not depend on, import cycles, ' +
|
|
125
|
+
'and text or symbols it must not contain, each with the reason the document gives. ' +
|
|
126
|
+
'Answers from the specs without reading the codebase, so it works for a file that does not exist yet. ' +
|
|
127
|
+
'Rules in documents that are not in force are counted and named but not listed unless include_inactive is true.',
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties: {
|
|
131
|
+
path: {
|
|
132
|
+
type: 'string',
|
|
133
|
+
description: 'A file or directory, relative to the project root or absolute inside it.',
|
|
134
|
+
},
|
|
135
|
+
include_inactive: {
|
|
136
|
+
type: 'boolean',
|
|
137
|
+
description: 'Also list rules from draft, proposed, rejected, deprecated and superseded documents.',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
required: ['path'],
|
|
141
|
+
additionalProperties: false,
|
|
142
|
+
},
|
|
143
|
+
annotations: READ_ONLY,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'check_architecture',
|
|
147
|
+
title: 'Check the architecture rules',
|
|
148
|
+
description: 'Runs the architecture rules in force against the files on disk and reports every violation, as CI would. ' +
|
|
149
|
+
'Given paths, runs only the rules that govern them - each over its whole scope, so a count or a cycle is judged ' +
|
|
150
|
+
'exactly as CI judges it - and marks which violations lie in those paths. Save your edits before calling.',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
paths: {
|
|
155
|
+
type: 'array',
|
|
156
|
+
items: { type: 'string' },
|
|
157
|
+
description: 'Files or directories to check the rules of, relative to the project root. Omit to run every rule.',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
additionalProperties: false,
|
|
161
|
+
},
|
|
162
|
+
annotations: READ_ONLY,
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
export const RULES_URI = 'spec://rules';
|
|
166
|
+
export const DOCUMENT_URI_PREFIX = 'spec://doc/';
|
|
167
|
+
export const RESOURCE_TEMPLATES = [
|
|
168
|
+
{
|
|
169
|
+
uriTemplate: `${DOCUMENT_URI_PREFIX}{+path}`,
|
|
170
|
+
name: 'spec-document',
|
|
171
|
+
title: 'Spec document',
|
|
172
|
+
description: 'Any spec document by its path relative to the project root, including documents that are not in force.',
|
|
173
|
+
mimeType: 'text/markdown',
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
export function documentUri(relativeFile) {
|
|
177
|
+
return `${DOCUMENT_URI_PREFIX}${relativeFile.split('/').map(encodeURIComponent).join('/')}`;
|
|
178
|
+
}
|
|
179
|
+
/** The spec path a document URI names, or null for anything else. */
|
|
180
|
+
export function documentPath(uri) {
|
|
181
|
+
if (!uri.startsWith(DOCUMENT_URI_PREFIX))
|
|
182
|
+
return null;
|
|
183
|
+
try {
|
|
184
|
+
return uri.slice(DOCUMENT_URI_PREFIX.length).split('/').map(decodeURIComponent).join('/');
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Malformed percent-encoding names no document.
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function toolError(text) {
|
|
192
|
+
return { text, isError: true };
|
|
193
|
+
}
|
|
194
|
+
/** Arguments a tool does not declare, which the model should hear about. */
|
|
195
|
+
function unknownArguments(args, allowed) {
|
|
196
|
+
const unknown = Object.keys(args).filter((name) => !allowed.includes(name));
|
|
197
|
+
return unknown.length === 0
|
|
198
|
+
? undefined
|
|
199
|
+
: toolError(`Unknown argument${unknown.length === 1 ? '' : 's'} ${unknown.map((name) => `"${name}"`).join(', ')}; this tool takes ${allowed.join(' and ')}.`);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Builds the function that answers one parsed JSON-RPC message.
|
|
203
|
+
*
|
|
204
|
+
* Returns the message to send back, or null when nothing is owed: a
|
|
205
|
+
* notification, or a response the client should not have sent.
|
|
206
|
+
*/
|
|
207
|
+
export function createMcpHandler(options) {
|
|
208
|
+
const serverInfo = { name: SERVER_NAME, version: options.version };
|
|
209
|
+
const capabilities = { tools: {}, resources: {} };
|
|
210
|
+
const readFile = options.readFile ?? ((file) => fs.readFile(file, 'utf8'));
|
|
211
|
+
const ruleSetOptions = {
|
|
212
|
+
patterns: options.patterns,
|
|
213
|
+
root: options.root,
|
|
214
|
+
// No defaults of their own: loadRuleSet has them, and a second copy here
|
|
215
|
+
// could never disagree with it in a way anything could see.
|
|
216
|
+
includeSpecs: options.run?.includeSpecs,
|
|
217
|
+
defaultSkips: options.run?.defaultSkips,
|
|
218
|
+
};
|
|
219
|
+
const noSpecs = () => toolError(`No spec files matched ${options.patterns.map((pattern) => `"${pattern}"`).join(', ')} under ${options.root}. ` +
|
|
220
|
+
'Start the server with --spec <glob> or --root <dir> pointing at the project.');
|
|
221
|
+
async function getRules(args) {
|
|
222
|
+
const unknown = unknownArguments(args, ['path', 'include_inactive']);
|
|
223
|
+
if (unknown)
|
|
224
|
+
return unknown;
|
|
225
|
+
if (typeof args['path'] !== 'string')
|
|
226
|
+
return toolError('"path" is required and must be a string.');
|
|
227
|
+
const includeInactive = args['include_inactive'] ?? options.run?.ignoreStatus ?? false;
|
|
228
|
+
if (typeof includeInactive !== 'boolean')
|
|
229
|
+
return toolError('"include_inactive" must be true or false.');
|
|
230
|
+
const startedAt = performance.now();
|
|
231
|
+
const query = await resolveQueryPath(args['path'], options.root);
|
|
232
|
+
const ruleSet = await loadRuleSet(ruleSetOptions);
|
|
233
|
+
if (ruleSet.specFiles.length === 0)
|
|
234
|
+
return noSpecs();
|
|
235
|
+
const report = { ...answerQuery(ruleSet, [query], includeInactive), durationMs: elapsed(startedAt) };
|
|
236
|
+
return { text: formatQuery(report), structured: { ...report } };
|
|
237
|
+
}
|
|
238
|
+
async function checkArchitecture(args) {
|
|
239
|
+
const unknown = unknownArguments(args, ['paths']);
|
|
240
|
+
if (unknown)
|
|
241
|
+
return unknown;
|
|
242
|
+
const rawPaths = args['paths'];
|
|
243
|
+
if (rawPaths !== undefined && !(Array.isArray(rawPaths) && rawPaths.every((entry) => typeof entry === 'string'))) {
|
|
244
|
+
return toolError('"paths" must be an array of strings.');
|
|
245
|
+
}
|
|
246
|
+
const paths = rawPaths === undefined ? undefined : await Promise.all(rawPaths.map((entry) => resolveQueryPath(entry, options.root)));
|
|
247
|
+
let inForce = 0;
|
|
248
|
+
const report = await runSpecGuard({
|
|
249
|
+
...options.run,
|
|
250
|
+
patterns: options.patterns,
|
|
251
|
+
root: options.root,
|
|
252
|
+
select: (assertion) => {
|
|
253
|
+
inForce += 1;
|
|
254
|
+
return paths === undefined || paths.some((query) => governs(assertion, query));
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
if (report.summary.specs === 0)
|
|
258
|
+
return noSpecs();
|
|
259
|
+
const scope = paths === undefined
|
|
260
|
+
? `all ${inForce} rules in force`
|
|
261
|
+
: `${report.summary.total} of ${inForce} rules in force - the ones that govern ${paths.map((query) => query.path).join(', ')}`;
|
|
262
|
+
const structured = {
|
|
263
|
+
ok: report.ok,
|
|
264
|
+
engine: report.engine,
|
|
265
|
+
paths: paths?.map((query) => query.path) ?? null,
|
|
266
|
+
rules: { inForce, checked: report.summary.total, passed: report.summary.passed, failed: report.summary.failed },
|
|
267
|
+
failures: report.results
|
|
268
|
+
.filter((result) => !result.ok)
|
|
269
|
+
.map((result) => ({
|
|
270
|
+
document: result.location.relativeFile,
|
|
271
|
+
line: result.location.line,
|
|
272
|
+
kind: result.kind,
|
|
273
|
+
description: result.description,
|
|
274
|
+
reason: result.reason ?? null,
|
|
275
|
+
message: result.message,
|
|
276
|
+
matches: result.matches.map((match) => ({
|
|
277
|
+
...match,
|
|
278
|
+
inPaths: paths === undefined || inQueriedPaths(match.file, paths),
|
|
279
|
+
})),
|
|
280
|
+
warnings: result.warnings,
|
|
281
|
+
})),
|
|
282
|
+
errors: report.errors.map((error) => ({
|
|
283
|
+
file: error.location.relativeFile,
|
|
284
|
+
line: error.location.line,
|
|
285
|
+
message: error.message,
|
|
286
|
+
})),
|
|
287
|
+
inactiveSpecs: report.inactiveSpecs,
|
|
288
|
+
warnings: report.warnings,
|
|
289
|
+
durationMs: Math.round(report.durationMs * 1000) / 1000,
|
|
290
|
+
};
|
|
291
|
+
const text = `Checked ${scope}.\n\n${formatReport(report, { color: false, verbose: false, ascii: true }, options.run?.maxSnippets)}`;
|
|
292
|
+
return { text, structured };
|
|
293
|
+
}
|
|
294
|
+
async function callTool(params) {
|
|
295
|
+
const name = params['name'];
|
|
296
|
+
if (typeof name !== 'string')
|
|
297
|
+
throw new ProtocolError(INVALID_PARAMS, 'tools/call needs the name of a tool.');
|
|
298
|
+
const tool = name === 'get_architectural_rules' ? getRules : name === 'check_architecture' ? checkArchitecture : undefined;
|
|
299
|
+
if (tool === undefined)
|
|
300
|
+
throw new ProtocolError(INVALID_PARAMS, `Unknown tool: ${name}`);
|
|
301
|
+
const args = params['arguments'] ?? {};
|
|
302
|
+
if (!isObject(args))
|
|
303
|
+
throw new ProtocolError(INVALID_PARAMS, 'Tool arguments must be an object.');
|
|
304
|
+
let outcome;
|
|
305
|
+
try {
|
|
306
|
+
outcome = await tool(args);
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
// A path outside the root is the model's to fix; anything else is still
|
|
310
|
+
// better reported to the model than turned into a protocol failure it
|
|
311
|
+
// cannot read.
|
|
312
|
+
outcome = toolError(error instanceof QueryPathError ? error.message : `spec-guard failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
content: [{ type: 'text', text: outcome.text }],
|
|
316
|
+
...(outcome.structured === undefined ? {} : { structuredContent: outcome.structured }),
|
|
317
|
+
...(outcome.isError ? { isError: true } : {}),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
async function listResources() {
|
|
321
|
+
const ruleSet = await loadRuleSet(ruleSetOptions);
|
|
322
|
+
return {
|
|
323
|
+
resources: [
|
|
324
|
+
{
|
|
325
|
+
uri: RULES_URI,
|
|
326
|
+
name: 'rules',
|
|
327
|
+
title: 'Rules in force',
|
|
328
|
+
description: 'Every rule in force, with the document that states it and its scope, as JSON.',
|
|
329
|
+
mimeType: 'application/json',
|
|
330
|
+
},
|
|
331
|
+
// Documents not in force are readable through the template and left out
|
|
332
|
+
// of the list, which a client may put in front of a model wholesale.
|
|
333
|
+
...ruleSet.documents
|
|
334
|
+
.filter((document) => document.inForce)
|
|
335
|
+
.map((document) => ({
|
|
336
|
+
uri: documentUri(document.relativeFile),
|
|
337
|
+
name: document.relativeFile,
|
|
338
|
+
title: document.title ?? document.relativeFile,
|
|
339
|
+
mimeType: 'text/markdown',
|
|
340
|
+
})),
|
|
341
|
+
],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
function rulesResource(ruleSet) {
|
|
345
|
+
return {
|
|
346
|
+
root: toPosix(options.root),
|
|
347
|
+
specFiles: ruleSet.specFiles,
|
|
348
|
+
rules: ruleSet.rules
|
|
349
|
+
.filter(({ document }) => document.inForce)
|
|
350
|
+
.map(({ assertion, document }) => viewRule(assertion, document)),
|
|
351
|
+
notInForce: ruleSet.documents
|
|
352
|
+
.filter((document) => !document.inForce)
|
|
353
|
+
.map((document) => ({ ...viewDocument(document), rules: document.directives.length })),
|
|
354
|
+
errors: ruleSet.errors.map((error) => ({
|
|
355
|
+
file: error.location.relativeFile,
|
|
356
|
+
line: error.location.line,
|
|
357
|
+
message: error.message,
|
|
358
|
+
})),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
async function readResource(params, era) {
|
|
362
|
+
const uri = params['uri'];
|
|
363
|
+
if (typeof uri !== 'string')
|
|
364
|
+
throw new ProtocolError(INVALID_PARAMS, 'resources/read needs a uri.');
|
|
365
|
+
const ruleSet = await loadRuleSet(ruleSetOptions);
|
|
366
|
+
if (uri === RULES_URI) {
|
|
367
|
+
return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(rulesResource(ruleSet), null, 2) }] };
|
|
368
|
+
}
|
|
369
|
+
// Membership, never a path join: the only files this reads are the ones the
|
|
370
|
+
// spec patterns matched, so no URI can reach anything else on disk.
|
|
371
|
+
const wanted = documentPath(uri);
|
|
372
|
+
const document = ruleSet.documents.find((candidate) => candidate.relativeFile === wanted);
|
|
373
|
+
const text = document === undefined ? undefined : await readFile(document.file).catch(() => undefined);
|
|
374
|
+
if (text === undefined) {
|
|
375
|
+
throw new ProtocolError(era === 'modern' ? INVALID_PARAMS : LEGACY_RESOURCE_NOT_FOUND, 'Resource not found', { uri });
|
|
376
|
+
}
|
|
377
|
+
return { contents: [{ uri, mimeType: 'text/markdown', text }] };
|
|
378
|
+
}
|
|
379
|
+
/** A list request's cursor. This server never issues one, so any is invalid. */
|
|
380
|
+
function refuseCursor(params) {
|
|
381
|
+
if (params?.['cursor'] !== undefined)
|
|
382
|
+
throw new ProtocolError(INVALID_PARAMS, 'Invalid cursor: this server does not paginate.');
|
|
383
|
+
}
|
|
384
|
+
async function dispatch(method, params, era) {
|
|
385
|
+
const given = params ?? {};
|
|
386
|
+
if (era === 'legacy') {
|
|
387
|
+
if (method === 'initialize') {
|
|
388
|
+
return {
|
|
389
|
+
protocolVersion: negotiateLegacyVersion(given['protocolVersion']),
|
|
390
|
+
capabilities,
|
|
391
|
+
serverInfo,
|
|
392
|
+
instructions: INSTRUCTIONS,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
if (method === 'ping')
|
|
396
|
+
return {};
|
|
397
|
+
}
|
|
398
|
+
else if (method === 'server/discover') {
|
|
399
|
+
return { supportedVersions: [...MODERN_PROTOCOL_VERSIONS], capabilities, instructions: INSTRUCTIONS };
|
|
400
|
+
}
|
|
401
|
+
switch (method) {
|
|
402
|
+
case 'tools/list':
|
|
403
|
+
refuseCursor(params);
|
|
404
|
+
return { tools: TOOLS };
|
|
405
|
+
case 'tools/call':
|
|
406
|
+
return callTool(given);
|
|
407
|
+
case 'resources/list':
|
|
408
|
+
refuseCursor(params);
|
|
409
|
+
return listResources();
|
|
410
|
+
case 'resources/templates/list':
|
|
411
|
+
refuseCursor(params);
|
|
412
|
+
return { resourceTemplates: RESOURCE_TEMPLATES };
|
|
413
|
+
case 'resources/read':
|
|
414
|
+
return readResource(given, era);
|
|
415
|
+
default:
|
|
416
|
+
throw new ProtocolError(METHOD_NOT_FOUND, 'Method not found');
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/** The 2026-07-28 shape: a result type, caching hints where required, and identity. */
|
|
420
|
+
function modernResult(method, result) {
|
|
421
|
+
// Every cacheable result is marked stale at once and private. The rules are
|
|
422
|
+
// read fresh on each request, and a client serving an ADR edited a minute ago
|
|
423
|
+
// from cache would be doing the one thing this tool exists to stop.
|
|
424
|
+
const cacheable = method !== 'tools/call';
|
|
425
|
+
return {
|
|
426
|
+
resultType: 'complete',
|
|
427
|
+
...result,
|
|
428
|
+
...(cacheable ? { ttlMs: 0, cacheScope: 'private' } : {}),
|
|
429
|
+
_meta: { [SERVER_INFO_KEY]: serverInfo },
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
return async (message) => {
|
|
433
|
+
if (!isObject(message)) {
|
|
434
|
+
return {
|
|
435
|
+
jsonrpc: '2.0',
|
|
436
|
+
error: {
|
|
437
|
+
code: INVALID_REQUEST,
|
|
438
|
+
message: Array.isArray(message) ? 'Invalid Request: batches are not supported' : 'Invalid Request',
|
|
439
|
+
},
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
const { id, method, params } = message;
|
|
443
|
+
if (message['jsonrpc'] === '2.0' && method === undefined && isRequestId(id) && ('result' in message || 'error' in message)) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
if (message['jsonrpc'] !== '2.0' || typeof method !== 'string' || (id !== undefined && !isRequestId(id))) {
|
|
447
|
+
return { jsonrpc: '2.0', ...(isRequestId(id) ? { id } : {}), error: { code: INVALID_REQUEST, message: 'Invalid Request' } };
|
|
448
|
+
}
|
|
449
|
+
if (id === undefined)
|
|
450
|
+
return null;
|
|
451
|
+
try {
|
|
452
|
+
if (params !== undefined && !isObject(params))
|
|
453
|
+
throw new ProtocolError(INVALID_PARAMS, 'params must be an object.');
|
|
454
|
+
const era = classifyRequest(method, params);
|
|
455
|
+
const result = await dispatch(method, params, era);
|
|
456
|
+
return { jsonrpc: '2.0', id, result: era === 'modern' ? modernResult(method, result) : result };
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
const failure = error instanceof ProtocolError
|
|
460
|
+
? { code: error.code, message: error.message, data: error.data }
|
|
461
|
+
: { code: INTERNAL_ERROR, message: `Internal error: ${error instanceof Error ? error.message : String(error)}` };
|
|
462
|
+
return { jsonrpc: '2.0', id, error: failure };
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
/* -------------------------------------------------------------------- stdio */
|
|
467
|
+
/** The key a request is tracked under: `1` and `"1"` are different ids. */
|
|
468
|
+
function trackingKey(id) {
|
|
469
|
+
return `${typeof id}:${id}`;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Serves a handler over newline-delimited JSON-RPC until the input ends.
|
|
473
|
+
*
|
|
474
|
+
* The whole stdio binding. Messages are split on `\n` with a trailing `\r`
|
|
475
|
+
* dropped, blank lines are skipped, and every response is written as a single
|
|
476
|
+
* line - `JSON.stringify` never emits a raw newline, which is what the binding
|
|
477
|
+
* requires. Requests are answered concurrently and in whatever order they
|
|
478
|
+
* finish. A request the client cancels gets no response at all. When the input
|
|
479
|
+
* closes, requests still running are allowed to finish and then this resolves.
|
|
480
|
+
*/
|
|
481
|
+
export function serveStdio(input, write, handle) {
|
|
482
|
+
return new Promise((resolve, reject) => {
|
|
483
|
+
// Decoded here rather than with setEncoding, which cannot be told apart
|
|
484
|
+
// from not setting one: Node reads an empty encoding name as UTF-8 too.
|
|
485
|
+
const decoder = new TextDecoder();
|
|
486
|
+
let buffer = '';
|
|
487
|
+
let running = 0;
|
|
488
|
+
let ended = false;
|
|
489
|
+
const inFlight = new Set();
|
|
490
|
+
const cancelled = new Set();
|
|
491
|
+
// Resolves once the input has ended and the last request has answered. A
|
|
492
|
+
// count rather than a set of promises, so that getting it wrong either hangs
|
|
493
|
+
// or ends early - both of which a test sees.
|
|
494
|
+
const settle = () => {
|
|
495
|
+
if (ended && running === 0)
|
|
496
|
+
resolve();
|
|
497
|
+
};
|
|
498
|
+
const receive = (line) => {
|
|
499
|
+
// A CRLF line keeps its \r: JSON allows it as whitespace, and a line of
|
|
500
|
+
// nothing else is blank.
|
|
501
|
+
if (line.trim() === '')
|
|
502
|
+
return;
|
|
503
|
+
let message;
|
|
504
|
+
try {
|
|
505
|
+
message = JSON.parse(line);
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
write(JSON.stringify({ jsonrpc: '2.0', error: { code: PARSE_ERROR, message: 'Parse error' } }));
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
if (isObject(message) && message['method'] === 'notifications/cancelled') {
|
|
512
|
+
const requestId = isObject(message['params']) ? message['params']['requestId'] : undefined;
|
|
513
|
+
if (isRequestId(requestId) && inFlight.has(trackingKey(requestId)))
|
|
514
|
+
cancelled.add(trackingKey(requestId));
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const key = isObject(message) && typeof message['method'] === 'string' ? trackingKey(message['id']) : undefined;
|
|
518
|
+
inFlight.add(key);
|
|
519
|
+
running += 1;
|
|
520
|
+
void handle(message).then((response) => {
|
|
521
|
+
running -= 1;
|
|
522
|
+
inFlight.delete(key);
|
|
523
|
+
if (!cancelled.delete(key) && response !== null)
|
|
524
|
+
write(JSON.stringify(response));
|
|
525
|
+
settle();
|
|
526
|
+
});
|
|
527
|
+
};
|
|
528
|
+
input.on('data', (chunk) => {
|
|
529
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
530
|
+
for (let newline = buffer.indexOf('\n'); newline !== -1; newline = buffer.indexOf('\n')) {
|
|
531
|
+
const line = buffer.slice(0, newline);
|
|
532
|
+
buffer = buffer.slice(newline + 1);
|
|
533
|
+
receive(line);
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
input.once('end', () => {
|
|
537
|
+
ended = true;
|
|
538
|
+
receive(buffer);
|
|
539
|
+
settle();
|
|
540
|
+
});
|
|
541
|
+
input.once('error', reject);
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.d.ts
CHANGED
|
@@ -50,6 +50,20 @@ export declare const INACTIVE_STATUSES: ReadonlySet<string>;
|
|
|
50
50
|
* fence - this project's README does - is not read as declaring a status.
|
|
51
51
|
*/
|
|
52
52
|
export declare function parseStatus(source: string): SpecStatus | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* The document's title: its first level-one heading.
|
|
55
|
+
*
|
|
56
|
+
* Read so that a rule can be shown with the decision it belongs to - "ADR-0011:
|
|
57
|
+
* Layering constraints and import cycles" says more to someone about to edit a
|
|
58
|
+
* file than `docs/adr/0011-layers-and-cycles.md` does. Front-matter is skipped
|
|
59
|
+
* and code is masked, for the same reasons as the status: a README that shows
|
|
60
|
+
* an example ADR inside a fence has not titled itself with the example.
|
|
61
|
+
*
|
|
62
|
+
* Setext headings (a line underlined with `===`) are not read. Nobody writes an
|
|
63
|
+
* ADR that way, and a reader that guessed at underlines would find titles in
|
|
64
|
+
* tables.
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseTitle(source: string): string | undefined;
|
|
53
67
|
export interface ParseContext {
|
|
54
68
|
/** Absolute path of the spec file. */
|
|
55
69
|
file: string;
|
|
@@ -65,4 +79,15 @@ export declare function maskCode(source: string): string;
|
|
|
65
79
|
export declare function parseAttributes(input: string): Record<string, string>;
|
|
66
80
|
/** Extracts every spec-guard directive from a Markdown source string. */
|
|
67
81
|
export declare function parseDirectives(source: string, context: ParseContext): ParseResult;
|
|
82
|
+
/** A whole document: its directives, its status and its title. */
|
|
83
|
+
export interface ParsedDocument extends ParseResult {
|
|
84
|
+
title?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Everything a spec document declares, read with one pass of `maskCode`.
|
|
88
|
+
*
|
|
89
|
+
* `parseDirectives` and `parseTitle` each mask the source, and masking is most
|
|
90
|
+
* of what reading a spec costs; a caller that wants both should not pay twice.
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseDocument(source: string, context: ParseContext): ParsedDocument;
|
|
68
93
|
//# sourceMappingURL=parser.d.ts.map
|
package/dist/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAGV,aAAa,EACb,WAAW,EAEX,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,8CAA8C;AAC9C,eAAO,MAAM,KAAK,aAQhB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAuEzE,CAAC;AAIF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAMhD,CAAC;AA+HH;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAElE;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAGV,aAAa,EACb,WAAW,EAEX,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,8CAA8C;AAC9C,eAAO,MAAM,KAAK,aAQhB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAuEzE,CAAC;AAIF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAMhD,CAAC;AA+HH;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAElE;AAUD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE7D;AAeD,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAuD/C;AAMD,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrE;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,WAAW,CAElF;AAED,kEAAkE;AAClE,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,cAAc,CAKnF"}
|