specguard-mcp 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,7 +32,7 @@ refuses to boot and takes the tools that needed no configuration down with it.
32
32
 
33
33
  | Variable | Needed by | Default | What it is |
34
34
  | --- | --- | --- | --- |
35
- | `SPECGUARD_ENDPOINT` | `get_repository_overview`, `get_server_version`, `list_repositories`, `add_repository`, `registrable_repositories` | — | your SpecGuard instance's root URL, **including the scheme** — e.g. `https://specguard.example.com`, or `http://localhost:3000`. A value with no scheme is refused by name (`SPECGUARD_ENDPOINT is not a usable URL: "sg.example.com"`) rather than surfacing later as an opaque failure. `SPECGUARD_URL` is accepted as an alias, and is the name every message uses when it is the one you set. A blank value counts as unset, so leaving `SPECGUARD_ENDPOINT` empty in a templated config falls through to `SPECGUARD_URL` instead of suppressing it. `get_server_version` needs only this variable — it sends no API key, because the version route is unauthenticated by design |
35
+ | `SPECGUARD_ENDPOINT` | `get_repository_overview`, `get_intent_schema`, `get_server_version`, `list_repositories`, `add_repository`, `registrable_repositories` | — | your SpecGuard instance's root URL, **including the scheme** — e.g. `https://specguard.example.com`, or `http://localhost:3000`. A value with no scheme is refused by name (`SPECGUARD_ENDPOINT is not a usable URL: "sg.example.com"`) rather than surfacing later as an opaque failure. `SPECGUARD_URL` is accepted as an alias, and is the name every message uses when it is the one you set. A blank value counts as unset, so leaving `SPECGUARD_ENDPOINT` empty in a templated config falls through to `SPECGUARD_URL` instead of suppressing it. `get_server_version` and `get_intent_schema` need only this variable — they send no API key, because the routes they read are unauthenticated by design |
36
36
  | `SPECGUARD_API_KEY` | `get_repository_overview`, `near_duplicate_clusters` (default calls) | — | an agent/CI API key (`sgk_…`) issued by that deployment — a **per-repository** key, which is the single repository those tools answer about by default |
37
37
  | `SPECGUARD_USER_API_KEY` | `list_repositories` (fallback), `add_repository`, `registrable_repositories`, `remove_repository` (fallback), `create_repository_api_key` (fallback), `revoke_repository_api_key` (fallback), `list_repository_api_keys` (fallback), `list_repository_agent_keys` (fallback), `revoke_repository_agent_key` (fallback), `list_repository_agent_keys_presented_revoked` (fallback), `list_repository_members` (fallback), `add_repository_member` (fallback), `update_repository_member_permissions` (fallback), `remove_repository_member` (fallback), `get_repository_overview` / `near_duplicate_clusters` **with** `repository` (fallback), `rename_repository` | — | a **user** API key (`sgu_…`), minted from that deployment's account page. A different credential from the one above, not a second place to put the same value: SpecGuard decides which of them a request may use from the token's prefix, before it reads anything, and answers `401` for the other one. Set whichever your tools need — both, if you use both |
38
38
  | `SPECGUARD_AGENT_API_KEY` | `list_repositories` (preferred), `remove_repository` (preferred), `create_repository_api_key` (preferred), `revoke_repository_api_key` (preferred), `list_repository_api_keys` (preferred), `list_repository_agent_keys` (preferred), `revoke_repository_agent_key` (preferred), `list_repository_agent_keys_presented_revoked` (preferred), `list_repository_members` (preferred), `add_repository_member` (preferred), `update_repository_member_permissions` (preferred), `remove_repository_member` (preferred), `get_repository_overview` / `near_duplicate_clusters` **with** `repository` (preferred) | — | an **agent** API key (`sga_…`), minted from that deployment's account page (Agent keys panel) with an explicit set of repositories and permissions. It speaks for nobody: its reach is exactly the set granted onto it, fixed at mint time, and every read is bounded by that set server-side. This is the credential to give an automated agent — one key, many repositories, none of a person's rights. When it and `SPECGUARD_USER_API_KEY` are both set, every tool that answers either key — `list_repositories`, `remove_repository`, the members tools, the key-lifecycle tools, and `get_repository_overview` / `near_duplicate_clusters` **with** `repository` — uses **this** one, so discovery stays inside the set the other tools can reach |
@@ -90,6 +90,59 @@ tool call carrying findings — an agent told "the tool failed" retries the tool
90
90
  a finding fixes the annotation. Only exit `2` is a tool error, and it carries the linter's stderr,
91
91
  because the gem deliberately emits no document on that path.
92
92
 
93
+ ### `get_intent_schema`
94
+
95
+ Serves the **OpenTestIntent schema document itself** — the contract an `@intent:` annotation is
96
+ validated against — read live from the deployment's own unauthenticated root-level schema mirror,
97
+ which hands back the canonical document's bytes verbatim.
98
+
99
+ Call it **before** writing or editing an annotation. This is the *reference*; `lint_intent_annotations`
100
+ is the *judge*, and a judge can only tell you that something you already wrote is wrong.
101
+
102
+ **Reading the contract is the only way to learn parts of it.** A refusal names the legal values of a
103
+ field you got *wrong*, and says nothing at all about a field you *omitted* — so the fastest way to
104
+ learn the rules from refusals alone is to submit values you believe are invalid. And an **optional**
105
+ property can never appear in any refusal: `required` does not name it, and a closed-object check
106
+ only ever reports the key you did send, so nothing you submit at any value causes the linter to
107
+ mention it. That part of the contract is reachable here and nowhere else in this toolset.
108
+
109
+ The answer is an **envelope** that carries the whole document in both shapes, derived from one
110
+ fetched body so they cannot disagree — plus the enforcement identity beside it:
111
+
112
+ | field | |
113
+ | --- | --- |
114
+ | `structured.schema` | the document **parsed** — the shape to read the field rules and any enumerated values off |
115
+ | `structured.enforced` | the identity the deployment itself serves from its `GET /version`: `schema_sha256`, the digest of the contract it actually enforces, and `schema_origin`, where those bytes come from on the server — or `null` when the deployment could not say |
116
+ | `text` | the served bytes **unchanged** — no re-encoding, no reformatting, so a digest taken over this text matches the canonical document's, which is the mirror's whole promise |
117
+
118
+ **The end-to-end check is derivable from this one tool.** Take a SHA-256 digest over `text` and
119
+ compare it with `enforced.schema_sha256`: a **match** means the reference you read is the contract
120
+ that will judge you; a **mismatch** means the bytes you received are *not* what the deployment
121
+ enforces — do not author annotations against them, and read `enforced.schema_origin` to see which
122
+ half of the disagreement is the server's. The tool serves both facts side by side and never
123
+ judges: a mismatch is never refused or warned here, because the judgment is yours.
124
+
125
+ **`enforced: null` means "this deployment could not say"** — its `/version` omits the identity
126
+ keys (a build predating the identity channel), answers non-2xx, or the identity fetch fails
127
+ entirely — and the document answer still stands in full. It is not the same null as a served
128
+ `schema_sha256: null` *inside* a present `enforced`: that is the deployment's own honest "I
129
+ enforce from this origin and cannot currently read it", passed through exactly as served.
130
+
131
+ Nothing in this bridge restates the schema's contents — not here, not in a tool description, not in
132
+ a test. The answer *is* the contract; any prose copy of it would be one release behind the document
133
+ this tool serves, and this repo deliberately vendors no copy of its own.
134
+
135
+ **A 404 means the deployment predates the mirror route: the endpoint is right and the build is old.**
136
+ The error text names the endpoint as possibly misconfigured, because a non-contract 404 body names
137
+ no cause — when the other tools work against the same endpoint, read it as *"the deployment needs
138
+ upgrading"*, not as a wrong URL. A **2xx** whose body will not parse is reported as a malformed
139
+ mirror instead, naming the route rather than your configuration: the response arrived, so the
140
+ endpoint is not the thing to go and fix.
141
+
142
+ **Needs no API key of any kind** — both routes it reads (the schema mirror and `GET /version`) are
143
+ unauthenticated by design, because a contract is not a secret — so it works with
144
+ `SPECGUARD_ENDPOINT` alone and sends no `Authorization` header. Takes no arguments.
145
+
93
146
  ### `get_repository_overview`
94
147
 
95
148
  Asks SpecGuard what a repository's suite looks like **without running it** — the cold-start question
@@ -391,7 +444,10 @@ cancelled after two of four shards leaves a half-sized row in the history perman
391
444
 
392
445
  Reports **which build of the SpecGuard deployment is answering**, read from the deployment's own
393
446
  unauthenticated root-level `GET /version` — the figure the release bot's `VERSION` file carries,
394
- served as `{"version": "0.1.46"}`-shaped JSON and passed through verbatim as `{version}`.
447
+ served as a JSON object and passed through verbatim. Since SPGD-1316 the body also carries the
448
+ enforced contract's identity beside the build (`schema_sha256` + `schema_origin`); this tool
449
+ passes the whole answer through without interpreting it — `get_intent_schema` is where the served
450
+ contract is read beside that identity and the two are compared.
395
451
 
396
452
  **This is the server's build, not this bridge's.** The version in the initialize handshake's
397
453
  `serverInfo` and the `specguard-mcp/<version>` User-Agent describe *this bridge* — a different
@@ -411,8 +467,8 @@ cause — when the other tools work against the same endpoint, read that error a
411
467
  needs upgrading"*, not as a wrong URL.
412
468
 
413
469
  **Needs no API key of any kind** — the route is unauthenticated by design — so it works with
414
- `SPECGUARD_ENDPOINT` alone, and it is the one tool here that sends no `Authorization` header. Takes
415
- no arguments.
470
+ `SPECGUARD_ENDPOINT` alone, and it sends no `Authorization` header (as does `get_intent_schema`, the
471
+ other credential-free read here). Takes no arguments.
416
472
 
417
473
  ### `list_repositories`
418
474
 
@@ -322,7 +322,9 @@ export declare function requireUserOrAgentApiConfig(config: Config): Credentiall
322
322
  * `Credential`: the server's root-level `GET /version` (SPGD-1197, specguard
323
323
  * 08ab408) answers unauthenticated BY DESIGN — the platform's own doctrine
324
324
  * places it outside the credential seam, at the root where the no-account
325
- * reads (`/up`, the schema mirror) already live. Demanding a key here would
325
+ * reads (`/up`, the schema mirror) already live. SPGD-1331 made it serve a
326
+ * second such ask: the schema mirror named there is now wrapped too
327
+ * (`get_intent_schema`), through this same helper. Demanding a key here would
326
328
  * invent a requirement the deployment does not have, and the
327
329
  * credential-free config this returns is what keeps the transport from
328
330
  * sending an `Authorization` header at all.
@@ -190,7 +190,9 @@ export function requireUserOrAgentApiConfig(config) {
190
190
  * `Credential`: the server's root-level `GET /version` (SPGD-1197, specguard
191
191
  * 08ab408) answers unauthenticated BY DESIGN — the platform's own doctrine
192
192
  * places it outside the credential seam, at the root where the no-account
193
- * reads (`/up`, the schema mirror) already live. Demanding a key here would
193
+ * reads (`/up`, the schema mirror) already live. SPGD-1331 made it serve a
194
+ * second such ask: the schema mirror named there is now wrapped too
195
+ * (`get_intent_schema`), through this same helper. Demanding a key here would
194
196
  * invent a requirement the deployment does not have, and the
195
197
  * credential-free config this returns is what keeps the transport from
196
198
  * sending an `Authorization` header at all.
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
@@ -9,10 +9,34 @@ import { requireAgentApiConfig, requireApiConfig, requireEndpointApiConfig, requ
9
9
  *
10
10
  * The key is PRESENT-CONDITIONAL since SPGD-1200: every credentialled helper
11
11
  * binds one and it rides every request as before, while a credential-free ask
12
- * (`requireEndpointApiConfig`, the unauthenticated `/version`) presents NO
12
+ * (`requireEndpointApiConfig` — the unauthenticated `/version`, and since
13
+ * SPGD-1331 the schema mirror beside it) presents NO
13
14
  * `Authorization` header at all rather than `Bearer ` with nothing after it.
14
15
  */
15
16
  export declare function getJson(api: ApiConfig, path: string, query: Record<string, string | undefined>, fetchImpl: typeof globalThis.fetch): Promise<unknown>;
17
+ /**
18
+ * `GET` that hands back the RAW BODY TEXT — the read half of `deleteJson`'s
19
+ * argument, for a route whose bytes are the answer.
20
+ *
21
+ * `requestJson` JSON-parses every 2xx it sees and, when that parse fails,
22
+ * throws a sentence telling the operator to check that the endpoint points at
23
+ * a SpecGuard deployment "and not, say, a proxy or login page". That is the
24
+ * right diagnosis for a body that should have been JSON and was not; it is the
25
+ * WRONG one for a caller whose contract is the bytes themselves, because it
26
+ * names a cause (misconfigured endpoint) that the correct response in hand
27
+ * refutes. `deleteJson` already carries this shape for its own reason — its
28
+ * `204` has no body at all — and the argument generalises: what a SUCCESS body
29
+ * is for differs per caller, while the status check and the "reached and
30
+ * refused" hand-off to `describeFailure` do not.
31
+ *
32
+ * So this shares through `requestText` — the one total deadline, the abort,
33
+ * the reached-and-stopped vs could-not-reach split, and every crafted status
34
+ * sentence — and differs from `getJson` in exactly one thing: it returns what
35
+ * came back instead of what it parsed. A caller that wants a parsed value
36
+ * parses it, and owns the diagnosis for its own body, which is the only place
37
+ * that diagnosis can be correct.
38
+ */
39
+ export declare function getText(api: ApiConfig, path: string, fetchImpl: typeof globalThis.fetch): Promise<string>;
16
40
  /**
17
41
  * `POST` with a JSON body — the write half of the transport, and deliberately
18
42
  * the SAME function underneath.
@@ -55,8 +79,8 @@ export declare function patchJson(api: ApiConfig, path: string, body: Record<str
55
79
  * "answered 204 but the body was not JSON" — the trap this verb specifically
56
80
  * introduces, and the reason the DELETE path has its own success handling
57
81
  * instead of sharing `requestJson`'s. The status check and the
58
- * "reached and refused" hand-off to `describeFailure` are still shared
59
- * verbatim: only what happens to a SUCCESS body differs.
82
+ * "reached and refused" hand-off to `describeFailure` are still shared through
83
+ * `requestText`: only what happens to a SUCCESS body differs.
60
84
  */
61
85
  export declare function deleteJson(api: ApiConfig, path: string, fetchImpl: typeof globalThis.fetch): Promise<string>;
62
86
  /**
@@ -10,7 +10,8 @@ import { ApiError } from "../errors.js";
10
10
  *
11
11
  * The key is PRESENT-CONDITIONAL since SPGD-1200: every credentialled helper
12
12
  * binds one and it rides every request as before, while a credential-free ask
13
- * (`requireEndpointApiConfig`, the unauthenticated `/version`) presents NO
13
+ * (`requireEndpointApiConfig` — the unauthenticated `/version`, and since
14
+ * SPGD-1331 the schema mirror beside it) presents NO
14
15
  * `Authorization` header at all rather than `Bearer ` with nothing after it.
15
16
  */
16
17
  export async function getJson(api, path, query, fetchImpl) {
@@ -21,6 +22,31 @@ export async function getJson(api, path, query, fetchImpl) {
21
22
  }
22
23
  return requestJson(url, api, fetchImpl, { method: "GET" });
23
24
  }
25
+ /**
26
+ * `GET` that hands back the RAW BODY TEXT — the read half of `deleteJson`'s
27
+ * argument, for a route whose bytes are the answer.
28
+ *
29
+ * `requestJson` JSON-parses every 2xx it sees and, when that parse fails,
30
+ * throws a sentence telling the operator to check that the endpoint points at
31
+ * a SpecGuard deployment "and not, say, a proxy or login page". That is the
32
+ * right diagnosis for a body that should have been JSON and was not; it is the
33
+ * WRONG one for a caller whose contract is the bytes themselves, because it
34
+ * names a cause (misconfigured endpoint) that the correct response in hand
35
+ * refutes. `deleteJson` already carries this shape for its own reason — its
36
+ * `204` has no body at all — and the argument generalises: what a SUCCESS body
37
+ * is for differs per caller, while the status check and the "reached and
38
+ * refused" hand-off to `describeFailure` do not.
39
+ *
40
+ * So this shares through `requestText` — the one total deadline, the abort,
41
+ * the reached-and-stopped vs could-not-reach split, and every crafted status
42
+ * sentence — and differs from `getJson` in exactly one thing: it returns what
43
+ * came back instead of what it parsed. A caller that wants a parsed value
44
+ * parses it, and owns the diagnosis for its own body, which is the only place
45
+ * that diagnosis can be correct.
46
+ */
47
+ export async function getText(api, path, fetchImpl) {
48
+ return requestText(new URL(`${api.endpoint}${path}`), api, fetchImpl, { method: "GET" });
49
+ }
24
50
  /**
25
51
  * `POST` with a JSON body — the write half of the transport, and deliberately
26
52
  * the SAME function underneath.
@@ -73,14 +99,11 @@ export async function patchJson(api, path, body, fetchImpl) {
73
99
  * "answered 204 but the body was not JSON" — the trap this verb specifically
74
100
  * introduces, and the reason the DELETE path has its own success handling
75
101
  * instead of sharing `requestJson`'s. The status check and the
76
- * "reached and refused" hand-off to `describeFailure` are still shared
77
- * verbatim: only what happens to a SUCCESS body differs.
102
+ * "reached and refused" hand-off to `describeFailure` are still shared through
103
+ * `requestText`: only what happens to a SUCCESS body differs.
78
104
  */
79
105
  export async function deleteJson(api, path, fetchImpl) {
80
- const { response, body } = await fetchWithTimeout(new URL(`${api.endpoint}${path}`), api, fetchImpl, { method: "DELETE" });
81
- if (!response.ok)
82
- throw describeFailure(response.status, body, api);
83
- return body;
106
+ return requestText(new URL(`${api.endpoint}${path}`), api, fetchImpl, { method: "DELETE" });
84
107
  }
85
108
  /**
86
109
  * `DELETE` that answers with a JSON body — the destructive verb's one non-empty
@@ -150,6 +173,26 @@ async function requestJson(url, api, fetchImpl, request) {
150
173
  "or login page.", response.status);
151
174
  }
152
175
  }
176
+ /**
177
+ * The raw-body verbs' half of the response handling `requestJson` owns, in one
178
+ * place.
179
+ *
180
+ * Extracted when `getText` needed a home beside the JSON verbs rather than
181
+ * copied into it: the status check and the "reached and refused" hand-off to
182
+ * `describeFailure` are identical for both raw-body verbs, and what a SUCCESS
183
+ * body is for — the thing that differs per caller — stays out of here. There
184
+ * is deliberately NO not-JSON branch: for a bytes-are-the-answer contract,
185
+ * `requestJson`'s "was not JSON" diagnosis is wrong even when a parse would
186
+ * fail, because it names a cause (misconfigured endpoint) the correct response
187
+ * in hand refutes. A caller that wants a parsed value parses its own body and
188
+ * owns that judgment.
189
+ */
190
+ async function requestText(url, api, fetchImpl, request) {
191
+ const { response, body } = await fetchWithTimeout(url, api, fetchImpl, request);
192
+ if (!response.ok)
193
+ throw describeFailure(response.status, body, api);
194
+ return body;
195
+ }
153
196
  /** The three-clause guard both `*JsonObject` narrowings share. */
154
197
  function asJsonObject(body) {
155
198
  if (typeof body !== "object" || body === null || Array.isArray(body)) {
@@ -266,7 +309,19 @@ async function fetchWithTimeout(url, api, fetchImpl, request) {
266
309
  fetchImpl(url, {
267
310
  method: request.method,
268
311
  headers: {
269
- Accept: "application/json",
312
+ // What this bridge will accept, and every media type the deployment
313
+ // actually serves it — the header is a CLAIM, so it must not exclude
314
+ // a route this client calls. SpecGuard's own doctrine puts one read
315
+ // outside the JSON surface: the schema mirror answers
316
+ // `application/schema+json`, the media type draft-07 registers for a
317
+ // schema document, and it is served by a `render plain:` with an
318
+ // explicit content type, which does not negotiate. So the narrower
319
+ // header happened to work — the request succeeded while announcing
320
+ // it would not accept what came back. Widened rather than made
321
+ // per-call: the `Accept` of this transport is a property of the
322
+ // client, not of an individual call, which is the same argument
323
+ // `RequestSpec` makes for staying narrow.
324
+ Accept: "application/json, application/schema+json",
270
325
  // The version rides the identity the platform's rejection triage
271
326
  // stores verbatim (`specguard-mcp/<version>`), the same shape the
272
327
  // sibling clients already send. Resolved per request — see
@@ -1 +1 @@
1
- {"version":3,"file":"specguard-api.js","sourceRoot":"","sources":["../../../src/support/specguard-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"specguard-api.js","sourceRoot":"","sources":["../../../src/support/specguard-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "./types.js";
2
+ declare const getIntentSchema: ToolDefinition;
3
+ export default getIntentSchema;
@@ -0,0 +1,264 @@
1
+ import { ApiError } from "../errors.js";
2
+ import { getJsonObject, getText, requireEndpointApiConfig } from "../support/specguard-api.js";
3
+ /**
4
+ * The OpenTestIntent contract, READABLE — the reference this bridge was
5
+ * missing beside the judge it already had.
6
+ *
7
+ * == The gap this closes, and why refusals could not close it
8
+ *
9
+ * SpecGuard is structurally gated on `@intent:` annotations existing, and the
10
+ * only thing this bridge could say about one until now was whether an
11
+ * annotation the agent HAD ALREADY WRITTEN was wrong. `lint_intent_annotations`
12
+ * is a judge, not a reference: an agent authoring a new annotation had to
13
+ * guess, write the guess to a file, lint it, and read the refusal.
14
+ *
15
+ * Refusals are an INCOMPLETE teacher, and the sharpest asymmetry is that a
16
+ * WRONG enumerated value names the legal set in its error while an ABSENT one
17
+ * does not — so the fastest way to learn the contract through a judge is to
18
+ * submit a value you believe is invalid, which is a perverse thing for a
19
+ * toolset to reward. Worse, the schema declares an OPTIONAL property, and an
20
+ * optional property is underivable in principle from that surface: `required`
21
+ * never names it, and a closed-object refusal only ever reports the key you
22
+ * DID send. No input to the linter at any value causes it to be mentioned.
23
+ * That is the hole this tool exists to fill, and it is why this is a read of
24
+ * the contract rather than a nicer error message on the judge.
25
+ *
26
+ * == It MIRRORS; it does not carry a copy
27
+ *
28
+ * The bytes come from the deployment's own root-level, unauthenticated schema
29
+ * mirror — `SchemasController`, which renders the vendored document verbatim
30
+ * with an explicit `application/schema+json` content type and whose request
31
+ * spec pins the response to the file's bytes by digest. Vendoring the schema
32
+ * into this repo instead would mint a THIRD copy of a document whose entire
33
+ * design is one canonical source plus byte-identical mirrors, and it would
34
+ * drift silently — a bridge that answers from its own copy answers about
35
+ * itself, not about the deployment the agent is being judged by.
36
+ *
37
+ * For the same reason the contract's contents are not transcribed into this
38
+ * file's description, the README, or a test name. A second copy of a field
39
+ * list is one release behind the schema by construction. The tool is
40
+ * cross-referenced by name from elsewhere; its ANSWER is where the fields
41
+ * live.
42
+ *
43
+ * == Why the body is fetched raw, and why both shapes come off one value
44
+ *
45
+ * `getText` rather than `getJsonObject`, and the reason is a diagnosis rather
46
+ * than a preference: `requestJson`'s not-JSON sentence tells the operator to
47
+ * check that the endpoint points at a SpecGuard deployment "and not, say, a
48
+ * proxy or login page" — the wrong remedy for a response that arrived
49
+ * perfectly correctly and simply is not what that helper assumed. So this
50
+ * shares the deadline and the failure diagnosis and owns its own success
51
+ * handling, exactly as `deleteJson` does for its empty `204`.
52
+ *
53
+ * The verbatim body is then served as the text view and PARSED ONCE for the
54
+ * document view, both derived from the one fetched value as `tools/types.ts`
55
+ * requires. The text half is what keeps the mirror's promise intact across
56
+ * this bridge: a consumer digesting what it received gets the same digest the
57
+ * platform's own spec asserts, which a re-encode or a pretty-print would
58
+ * destroy. The structured half is the shape an agent actually reads a
59
+ * contract from — and `application/schema+json` carries the `+json`
60
+ * structured-syntax suffix precisely so a client dispatching on "is this
61
+ * JSON" still parses it.
62
+ *
63
+ * A 2xx body that will not parse is a genuinely malformed mirror and is
64
+ * reported as THAT, naming the route rather than the endpoint variable: the
65
+ * response arrived, so the configuration is not the thing to go and fix.
66
+ *
67
+ * == The enforcement identity beside it: a SECOND body, whose disagreement IS
68
+ * the check
69
+ *
70
+ * Since SPGD-1316 the deployment also answers WHICH CONTRACT IT ENFORCES:
71
+ * `GET /version` carries `schema_sha256` — the digest of the vendored document
72
+ * this process validates every ingested annotation against — and
73
+ * `schema_origin`, the repo-relative path those bytes come from. The pairing
74
+ * the platform's own controller names is exact: the same bytes are fetchable,
75
+ * unauthenticated, from this same host at the mirror route above, so a client
76
+ * can digest them itself and check the served answer. This tool is where that
77
+ * loop closes. Until now the bridge carried those keys invisibly —
78
+ * `get_server_version` passed them through, but the tool whose question IS the
79
+ * contract named no comparison target, and `schema_sha256` appeared nowhere on
80
+ * this surface — so the question "is the reference I read the contract that
81
+ * will judge me?" was underivable from this toolset at all.
82
+ *
83
+ * `run()` now makes BOTH fetches and serves the two facts side by side. The
84
+ * identity fetch is the exact helper on the exact route `get_server_version`
85
+ * uses — `getJsonObject` against `/version` — so nothing new is invented: no
86
+ * second tool on that route, no new transport, no new credential kind, no new
87
+ * dependency. What is new is the shape of the answer: `structured` becomes an
88
+ * envelope, `{ schema, enforced }`, with the server's own key names preserved
89
+ * verbatim so the family cross-check is one vocabulary.
90
+ *
91
+ * The one-body doctrine above is RECONCILED here, not violated: `text` and
92
+ * `structured.schema` are two views of the ONE mirror body and must not
93
+ * disagree, while the whole point of `enforced` is that it CAN — a mismatch
94
+ * between a SHA-256 digest over `text` and `enforced.schema_sha256` IS the
95
+ * finding, and `enforced.schema_origin` is the fact that says which half of
96
+ * the disagreement is the server's. The tool serves both facts and never
97
+ * judges: refusing or warning on a mismatch would blind the agent in exactly
98
+ * the mangled-transport case where both facts matter most, and the judgment
99
+ * is the reader's.
100
+ *
101
+ * == The identity leg is best-effort by design
102
+ *
103
+ * Its failure must never fail the tool whose primary answer is the document.
104
+ * Any of — a deployment predating the identity channel (its `/version` omits
105
+ * the keys), a non-2xx answer, a network failure, a body that will not parse —
106
+ * yields `enforced: null` with the document answer still standing in full. No
107
+ * throw, no sentinel. `null` means "this deployment could not say", and the
108
+ * description says so in the reader's terms. This inherits the server's own
109
+ * nil doctrine in both directions: a current deployment whose vendored schema
110
+ * cannot be read answers `schema_sha256: null` at 200 — an honest null INSIDE
111
+ * a present envelope, passed through as served — while `enforced: null` is
112
+ * the envelope-level absence, the deployment having said nothing at all. The
113
+ * two nulls answer different questions and are kept apart.
114
+ *
115
+ * == No arguments, no credential
116
+ *
117
+ * Neither route takes parameters and neither authenticates anything, so the
118
+ * tool advertises no argument and binds no key — the second consumer of
119
+ * `requireEndpointApiConfig` after `get_server_version`, sending no
120
+ * `Authorization` header on EITHER fetch even when every key variable is set.
121
+ * A contract is not a secret, and presenting a key an endpoint does not read
122
+ * is not authentication, it is leakage.
123
+ */
124
+ const SCHEMA_PATH = "/schemas/open-test-intent.v1.json";
125
+ /**
126
+ * The identity route, beside the mirror route above — the exact path
127
+ * `get_server_version` reads, fetched here with the exact helper that tool
128
+ * uses. One route, one tool each: this is not a second tool on `/version`, it
129
+ * is the contract tool carrying the comparison target its own description
130
+ * invites the reader to compute.
131
+ */
132
+ const VERSION_PATH = "/version";
133
+ const getIntentSchema = {
134
+ name: "get_intent_schema",
135
+ title: "OpenTestIntent schema",
136
+ description: "Serves the OpenTestIntent schema document itself — the CONTRACT an `@intent:` annotation is " +
137
+ "validated against — read live from the SpecGuard deployment's own unauthenticated root-level " +
138
+ "schema mirror, which serves the canonical document's bytes verbatim. Call this BEFORE writing " +
139
+ "or editing an annotation: it is the reference, while lint_intent_annotations is the judge, and " +
140
+ "a judge can only tell you that something you already wrote is wrong. Reading the contract is " +
141
+ "also the ONLY way to learn parts of it: a refusal names the legal values of a field you got " +
142
+ "wrong but says nothing about a field you omitted, and an OPTIONAL property can never appear in " +
143
+ "any refusal at all — nothing you submit, at any value, causes the linter to mention it. The " +
144
+ "answer is an envelope carrying the whole document in both shapes, derived from one fetched " +
145
+ "body so they cannot disagree: `structured.schema` is it parsed, which is what to read the " +
146
+ "field rules and any enumerated values off; `text` is the served bytes UNCHANGED, so a digest " +
147
+ "taken over it matches the canonical document's. Beside the document, `structured.enforced` " +
148
+ "carries the enforcement identity the deployment itself serves from its `GET /version` — " +
149
+ "`schema_sha256`, the digest of the contract it actually enforces, and `schema_origin`, where " +
150
+ "those bytes come from on the server — which makes the end-to-end check derivable from this " +
151
+ "one tool: take a SHA-256 digest over `text` and compare it with `enforced.schema_sha256`. A " +
152
+ "match means the reference you read IS the contract that will judge you; a mismatch means the " +
153
+ "bytes you received are NOT what the deployment enforces, and you must not author annotations " +
154
+ "against them — `enforced.schema_origin` names which half of the disagreement is the " +
155
+ "server's. The tool serves both facts side by side and never judges: a mismatch is never " +
156
+ "refused or warned here, because the judgment is the reader's and a hard failure would blind " +
157
+ "you in exactly the mangled-transport case where both facts matter most. `enforced` is null " +
158
+ "when this deployment could not say — its `/version` omits the identity keys (a build " +
159
+ "predating the identity channel), answers non-2xx, or the identity fetch fails entirely — and " +
160
+ "the document answer still stands in full; null means 'this deployment could not say', never " +
161
+ "a sentinel. Nothing here restates the schema's contents — the answer is the contract, and " +
162
+ "any prose copy of it would be one release behind. A 404 means this deployment PREDATES the " +
163
+ "mirror route: the endpoint is right and the build is old. The error text names the endpoint " +
164
+ "as possibly misconfigured because a non-contract 404 body names no cause — when the other " +
165
+ "tools work against the same endpoint, read it as 'the deployment needs upgrading', not as a " +
166
+ "wrong URL. Needs NO API key of any kind — both routes it reads are unauthenticated by " +
167
+ "design, because a contract is not a secret — so it works with SPECGUARD_ENDPOINT alone and " +
168
+ "sends no Authorization header. Takes no arguments.",
169
+ inputSchema: {
170
+ type: "object",
171
+ // No properties, deliberately — a document has no ask to narrow. Still
172
+ // CLOSED rather than merely empty, for the reason `get-server-version.ts`
173
+ // states: `server.ts` forwards `arguments` unvalidated and `run` ignores
174
+ // them, so an open schema would let an invented argument be silently
175
+ // dropped while the call is answered as if it had been honoured.
176
+ additionalProperties: false,
177
+ },
178
+ async run(_args, context) {
179
+ const api = requireEndpointApiConfig(context.config);
180
+ const document = await getText(api, SCHEMA_PATH, context.fetch);
181
+ const schema = parseSchemaDocument(document, api.endpoint);
182
+ return {
183
+ // The served bytes, unchanged — see this file's header. The document's
184
+ // two views come off this ONE value; `enforced` is the deliberate SECOND
185
+ // body, whose possible disagreement with a digest over this text IS the
186
+ // check.
187
+ text: document,
188
+ structured: { schema, enforced: await enforcedIdentity(api, context.fetch) },
189
+ };
190
+ },
191
+ };
192
+ /**
193
+ * The parse, with the diagnosis this route actually needs.
194
+ *
195
+ * Deliberately NOT `requestJson`'s: its sentence sends the operator to check
196
+ * `SPECGUARD_ENDPOINT` for pointing at a proxy or a login page, and a 200 from
197
+ * the schema route is evidence AGAINST that reading — the deployment answered,
198
+ * on the path, with a status that says it meant to. What is wrong is the
199
+ * document, so the message says the document, and names the route so the
200
+ * report has somewhere to go.
201
+ *
202
+ * The object narrowing is part of the same answer rather than a second failure
203
+ * mode bolted beside it: a schema document's root is a JSON object, and a
204
+ * mirror serving an array or a bare scalar is malformed in exactly the way
205
+ * this sentence describes.
206
+ */
207
+ function parseSchemaDocument(body, endpoint) {
208
+ let parsed;
209
+ try {
210
+ parsed = JSON.parse(body);
211
+ }
212
+ catch {
213
+ throw new ApiError(`${endpoint}${SCHEMA_PATH} answered successfully but the document it served is not valid ` +
214
+ "JSON. The route was reached and answered, so this is a malformed schema mirror on the " +
215
+ "deployment rather than a configuration problem on this side.");
216
+ }
217
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
218
+ throw new ApiError(`${endpoint}${SCHEMA_PATH} answered successfully but the document it served is not a JSON ` +
219
+ "object, which a schema document's root must be. The route was reached and answered, so " +
220
+ "this is a malformed schema mirror on the deployment rather than a configuration problem " +
221
+ "on this side.");
222
+ }
223
+ return parsed;
224
+ }
225
+ /**
226
+ * The enforcement identity, fetched BEST-EFFORT — the `enforced` half of the
227
+ * envelope.
228
+ *
229
+ * Success is narrow and everything else is the same `null`. The narrow path: a
230
+ * 2xx JSON object carrying BOTH identity keys. A build predating the identity
231
+ * channel answers `{"version": …}` alone, and an envelope built over a missing
232
+ * key would be a fabricated half-answer rather than an honest absence, so the
233
+ * pair is required together — the same all-or-nothing choice the singular/
234
+ * plural branch in the transport makes. The values are copied through verbatim
235
+ * under the server's own key names, INCLUDING a null digest: a deployment that
236
+ * cannot currently read its vendored schema answers `schema_sha256: null` at
237
+ * 200 by its own doctrine, and that honesty is not this bridge's to improve —
238
+ * a present envelope saying "I enforce from this origin and cannot currently
239
+ * read it" is strictly more actionable than the envelope-level null below.
240
+ *
241
+ * Everything else — a non-2xx answer, an unreachable deployment, a timeout, a
242
+ * body that will not parse or is not an object, a `/version` that predates the
243
+ * route entirely — lands in the catch and returns `null`. That is deliberate:
244
+ * the identity leg is best-effort BY DESIGN, and its failure must never fail
245
+ * the tool whose primary answer is the document. `null` means "this deployment
246
+ * could not say", never a sentinel.
247
+ */
248
+ async function enforcedIdentity(api, fetchImpl) {
249
+ try {
250
+ const version = await getJsonObject(api, VERSION_PATH, {}, fetchImpl);
251
+ if ("schema_sha256" in version && "schema_origin" in version) {
252
+ return {
253
+ schema_sha256: version["schema_sha256"],
254
+ schema_origin: version["schema_origin"],
255
+ };
256
+ }
257
+ return null;
258
+ }
259
+ catch {
260
+ return null;
261
+ }
262
+ }
263
+ export default getIntentSchema;
264
+ //# sourceMappingURL=get-intent-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-intent-schema.js","sourceRoot":"","sources":["../../../src/tools/get-intent-schema.ts"],"names":[],"mappings":"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"}
@@ -44,8 +44,11 @@ import type { ToolDefinition } from "./types.js";
44
44
  * the tool advertises no argument and requires no key: it is the first tool
45
45
  * here served by `requireEndpointApiConfig`, and the transport sends no
46
46
  * `Authorization` header for it. The body is passed through verbatim —
47
- * reshaping `{version}` would be a second copy of the platform's own
48
- * identity answer, one release behind it.
47
+ * reshaping it would be a second copy of the platform's own identity answer,
48
+ * one release behind it. Since SPGD-1316 that body also carries the enforced
49
+ * contract's identity (`schema_sha256` + `schema_origin`) beside the build;
50
+ * this tool does not interpret it — `get_intent_schema` serves the contract
51
+ * beside that identity, which is where the pair is compared.
49
52
  */
50
53
  declare const getServerVersion: ToolDefinition;
51
54
  export default getServerVersion;
@@ -44,15 +44,23 @@ import { getJsonObject, requireEndpointApiConfig } from "../support/specguard-ap
44
44
  * the tool advertises no argument and requires no key: it is the first tool
45
45
  * here served by `requireEndpointApiConfig`, and the transport sends no
46
46
  * `Authorization` header for it. The body is passed through verbatim —
47
- * reshaping `{version}` would be a second copy of the platform's own
48
- * identity answer, one release behind it.
47
+ * reshaping it would be a second copy of the platform's own identity answer,
48
+ * one release behind it. Since SPGD-1316 that body also carries the enforced
49
+ * contract's identity (`schema_sha256` + `schema_origin`) beside the build;
50
+ * this tool does not interpret it — `get_intent_schema` serves the contract
51
+ * beside that identity, which is where the pair is compared.
49
52
  */
50
53
  const getServerVersion = {
51
54
  name: "get_server_version",
52
55
  title: "Server version",
53
56
  description: "Reports WHICH BUILD of the SpecGuard DEPLOYMENT is answering, read from the deployment's own " +
54
57
  "unauthenticated root-level `GET /version` — the figure the release bot's VERSION file carries, " +
55
- 'served as `{"version": "0.1.46"}`-shaped JSON and passed through verbatim as `{version}`. ' +
58
+ "served as a JSON object and passed through verbatim. Since SPGD-1316 that body also carries " +
59
+ "the enforced contract's identity beside the build — `schema_sha256`, the digest of the " +
60
+ "OpenTestIntent document this deployment validates annotations against, and `schema_origin`, " +
61
+ "where those bytes come from on the server — and the whole object is passed through without " +
62
+ "interpreting it; get_intent_schema is where the served contract is read beside that identity " +
63
+ "and the two are compared. " +
56
64
  "This is the SERVER's build, NOT this bridge's: the version in the initialize handshake's " +
57
65
  "`serverInfo` and the `specguard-mcp/<version>` User-Agent describe this bridge, a different " +
58
66
  "component released on its own cadence, so never read one as the other. Pinning which build's " +
@@ -65,8 +73,8 @@ const getServerVersion = {
65
73
  "names the endpoint as possibly misconfigured because a non-contract 404 body names no cause — " +
66
74
  "when the other tools work against the same endpoint, read that error as 'the deployment needs " +
67
75
  "upgrading', not as a wrong URL. Needs NO API key of any kind — the route is unauthenticated by " +
68
- "design — so it works with `SPECGUARD_ENDPOINT` alone, and it is the one tool here that sends " +
69
- "no `Authorization` header. Takes no arguments.",
76
+ "design — so it works with `SPECGUARD_ENDPOINT` alone, and it sends no `Authorization` header " +
77
+ "(as does get_intent_schema, the other credential-free read here). Takes no arguments.",
70
78
  inputSchema: {
71
79
  type: "object",
72
80
  // No properties, deliberately — see this file's header. Still CLOSED rather
@@ -1 +1 @@
1
- {"version":3,"file":"get-server-version.js","sourceRoot":"","sources":["../../../src/tools/get-server-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAGtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,MAAM,gBAAgB,GAAmB;IACvC,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,gBAAgB;IACvB,WAAW,EACT,+FAA+F;QAC/F,iGAAiG;QACjG,4FAA4F;QAC5F,2FAA2F;QAC3F,8FAA8F;QAC9F,+FAA+F;QAC/F,iGAAiG;QACjG,0FAA0F;QAC1F,gGAAgG;QAChG,+FAA+F;QAC/F,8FAA8F;QAC9F,iGAAiG;QACjG,gGAAgG;QAChG,gGAAgG;QAChG,iGAAiG;QACjG,+FAA+F;QAC/F,gDAAgD;IAClD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,4EAA4E;QAC5E,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,mDAAmD;QACnD,oBAAoB,EAAE,KAAK;KAC5B;IAED,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO;QACtB,MAAM,GAAG,GAAG,wBAAwB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAEvE,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACrC,UAAU,EAAE,MAAM;SACnB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"get-server-version.js","sourceRoot":"","sources":["../../../src/tools/get-server-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAGtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,gBAAgB,GAAmB;IACvC,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,gBAAgB;IACvB,WAAW,EACT,+FAA+F;QAC/F,iGAAiG;QACjG,8FAA8F;QAC9F,yFAAyF;QACzF,8FAA8F;QAC9F,6FAA6F;QAC7F,+FAA+F;QAC/F,4BAA4B;QAC5B,2FAA2F;QAC3F,8FAA8F;QAC9F,+FAA+F;QAC/F,iGAAiG;QACjG,0FAA0F;QAC1F,gGAAgG;QAChG,+FAA+F;QAC/F,8FAA8F;QAC9F,iGAAiG;QACjG,gGAAgG;QAChG,gGAAgG;QAChG,iGAAiG;QACjG,+FAA+F;QAC/F,uFAAuF;IACzF,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,4EAA4E;QAC5E,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,mDAAmD;QACnD,oBAAoB,EAAE,KAAK;KAC5B;IAED,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO;QACtB,MAAM,GAAG,GAAG,wBAAwB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAEvE,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACrC,UAAU,EAAE,MAAM;SACnB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -200,6 +200,37 @@ import type { ToolDefinition } from "./types.js";
200
200
  * unchanged and still binding: the endpoint was verified-shipped on
201
201
  * `origin/main` before this entry wrapped it. What moved was the platform,
202
202
  * not the bar.
203
+ *
204
+ * == The contract itself, readable at last
205
+ *
206
+ * - `get_intent_schema` wraps the root-level `GET
207
+ * /schemas/open-test-intent.v1.json` (shipped: `specguard/config/routes.rb`,
208
+ * `SchemasController`, spec-covered by
209
+ * `spec/requests/open_test_intent_schema_spec.rb`).
210
+ *
211
+ * The second credential-free entry, and the one that gives this registry a
212
+ * REFERENCE beside the JUDGE it opened with. `lint_intent_annotations` can
213
+ * only say that an annotation already written is wrong, and its refusals are
214
+ * an incomplete teacher — a wrong enumerated value names the legal set, an
215
+ * omitted field does not, and the schema's OPTIONAL property is underivable
216
+ * in principle from a closed-object refusal, which only ever reports a key
217
+ * that WAS sent. Serving the document closes that hole without touching the
218
+ * judge.
219
+ *
220
+ * It mirrors rather than vendors, deliberately: the schema's design is one
221
+ * canonical source plus byte-identical mirrors, so a copy inside this bridge
222
+ * would be a third one, drifting silently and answering about itself instead
223
+ * of about the deployment the agent is judged by. That is also why it forced
224
+ * the transport's raw-body READ (`getText`): `requestJson`'s not-JSON
225
+ * sentence blames the endpoint for pointing at a proxy or a login page, which
226
+ * is the wrong remedy for a response that arrived correctly — the same
227
+ * argument `deleteJson`'s empty `204` made, generalised. The shared `Accept`
228
+ * header was widened in the same slice to admit `application/schema+json`, the
229
+ * media type this route actually serves: the header is a claim this client
230
+ * makes, and it must not exclude a route this client calls. The standing rule
231
+ * is unchanged and still binding — the route was verified-shipped, spec-covered
232
+ * and root-level before this entry wrapped it, and `/check-intent` (a comment
233
+ * in `routes.rb`) stays out.
203
234
  */
204
235
  export declare const TOOLS: readonly ToolDefinition[];
205
236
  export type { ToolContext, ToolDefinition, ToolResult } from "./types.js";
@@ -1,6 +1,7 @@
1
1
  import addRepository from "./add-repository.js";
2
2
  import addRepositoryMember from "./add-repository-member.js";
3
3
  import createRepositoryApiKey from "./create-repository-api-key.js";
4
+ import getIntentSchema from "./get-intent-schema.js";
4
5
  import getServerVersion from "./get-server-version.js";
5
6
  import lintIntentAnnotations from "./lint-intent-annotations.js";
6
7
  import listRepositories from "./list-repositories.js";
@@ -218,9 +219,41 @@ import updateRepositoryMemberPermissions from "./update-repository-member-permis
218
219
  * unchanged and still binding: the endpoint was verified-shipped on
219
220
  * `origin/main` before this entry wrapped it. What moved was the platform,
220
221
  * not the bar.
222
+ *
223
+ * == The contract itself, readable at last
224
+ *
225
+ * - `get_intent_schema` wraps the root-level `GET
226
+ * /schemas/open-test-intent.v1.json` (shipped: `specguard/config/routes.rb`,
227
+ * `SchemasController`, spec-covered by
228
+ * `spec/requests/open_test_intent_schema_spec.rb`).
229
+ *
230
+ * The second credential-free entry, and the one that gives this registry a
231
+ * REFERENCE beside the JUDGE it opened with. `lint_intent_annotations` can
232
+ * only say that an annotation already written is wrong, and its refusals are
233
+ * an incomplete teacher — a wrong enumerated value names the legal set, an
234
+ * omitted field does not, and the schema's OPTIONAL property is underivable
235
+ * in principle from a closed-object refusal, which only ever reports a key
236
+ * that WAS sent. Serving the document closes that hole without touching the
237
+ * judge.
238
+ *
239
+ * It mirrors rather than vendors, deliberately: the schema's design is one
240
+ * canonical source plus byte-identical mirrors, so a copy inside this bridge
241
+ * would be a third one, drifting silently and answering about itself instead
242
+ * of about the deployment the agent is judged by. That is also why it forced
243
+ * the transport's raw-body READ (`getText`): `requestJson`'s not-JSON
244
+ * sentence blames the endpoint for pointing at a proxy or a login page, which
245
+ * is the wrong remedy for a response that arrived correctly — the same
246
+ * argument `deleteJson`'s empty `204` made, generalised. The shared `Accept`
247
+ * header was widened in the same slice to admit `application/schema+json`, the
248
+ * media type this route actually serves: the header is a claim this client
249
+ * makes, and it must not exclude a route this client calls. The standing rule
250
+ * is unchanged and still binding — the route was verified-shipped, spec-covered
251
+ * and root-level before this entry wrapped it, and `/check-intent` (a comment
252
+ * in `routes.rb`) stays out.
221
253
  */
222
254
  export const TOOLS = [
223
255
  lintIntentAnnotations,
256
+ getIntentSchema,
224
257
  getRepositoryOverview,
225
258
  getServerVersion,
226
259
  listRepositories,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AACvD,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,gBAAgB,MAAM,wBAAwB,CAAC;AACtD,OAAO,uBAAuB,MAAM,iCAAiC,CAAC;AACtE,OAAO,uCAAuC,MAAM,mDAAmD,CAAC;AACxG,OAAO,qBAAqB,MAAM,+BAA+B,CAAC;AAClE,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAC7D,OAAO,uBAAuB,MAAM,+BAA+B,CAAC;AACpE,OAAO,gBAAgB,MAAM,wBAAwB,CAAC;AACtD,OAAO,sBAAsB,MAAM,+BAA+B,CAAC;AACnE,OAAO,gBAAgB,MAAM,wBAAwB,CAAC;AACtD,OAAO,wBAAwB,MAAM,kCAAkC,CAAC;AACxE,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,iCAAiC,MAAM,2CAA2C,CAAC;AAG1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyMG;AACH,MAAM,CAAC,MAAM,KAAK,GAA8B;IAC9C,qBAAqB;IACrB,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,uBAAuB;IACvB,gBAAgB;IAChB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,qBAAqB;IACrB,mBAAmB;IACnB,iCAAiC;IACjC,sBAAsB;IACtB,gBAAgB;IAChB,uBAAuB;IACvB,uCAAuC;IACvC,wBAAwB;CACzB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,eAAe,MAAM,wBAAwB,CAAC;AACrD,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AACvD,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,gBAAgB,MAAM,wBAAwB,CAAC;AACtD,OAAO,uBAAuB,MAAM,iCAAiC,CAAC;AACtE,OAAO,uCAAuC,MAAM,mDAAmD,CAAC;AACxG,OAAO,qBAAqB,MAAM,+BAA+B,CAAC;AAClE,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAC7D,OAAO,uBAAuB,MAAM,+BAA+B,CAAC;AACpE,OAAO,gBAAgB,MAAM,wBAAwB,CAAC;AACtD,OAAO,sBAAsB,MAAM,+BAA+B,CAAC;AACnE,OAAO,gBAAgB,MAAM,wBAAwB,CAAC;AACtD,OAAO,wBAAwB,MAAM,kCAAkC,CAAC;AACxE,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,iCAAiC,MAAM,2CAA2C,CAAC;AAG1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwOG;AACH,MAAM,CAAC,MAAM,KAAK,GAA8B;IAC9C,qBAAqB;IACrB,eAAe;IACf,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,uBAAuB;IACvB,gBAAgB;IAChB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,qBAAqB;IACrB,mBAAmB;IACnB,iCAAiC;IACjC,sBAAsB;IACtB,gBAAgB;IAChB,uBAAuB;IACvB,uCAAuC;IACvC,wBAAwB;CACzB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specguard-mcp",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "description": "MCP server exposing SpecGuard suite intelligence to AI coding agents",
5
5
  "license": "ISC",
6
6
  "type": "module",