@shiftleftpt/sbd-toe-mcp 0.20.0-beta.7 → 0.20.0-beta.9
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/assets/agent-guide.md +14 -2
- package/dist/index.js +243 -207
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/ask-manual.js +6 -1
- package/dist/orchestrator/ask-manual.js.map +1 -1
- package/dist/resources/sbd-toe-resources.js +19 -58
- package/dist/resources/sbd-toe-resources.js.map +1 -1
- package/dist/serving/applicability.d.ts +47 -0
- package/dist/serving/applicability.js +170 -0
- package/dist/serving/applicability.js.map +1 -0
- package/dist/serving/protocol-envelope.d.ts +2 -0
- package/dist/serving/protocol-envelope.js.map +1 -1
- package/dist/tools/assess-implementation.js +2 -0
- package/dist/tools/assess-implementation.js.map +1 -1
- package/dist/tools/consult-security-requirements.d.ts +2 -0
- package/dist/tools/consult-security-requirements.js +3 -0
- package/dist/tools/consult-security-requirements.js.map +1 -1
- package/dist/tools/generate-sbd-toe-skill.d.ts +1 -0
- package/dist/tools/generate-sbd-toe-skill.js +2 -0
- package/dist/tools/generate-sbd-toe-skill.js.map +1 -1
- package/dist/tools/get-chapter-implementation-checklist.js +2 -0
- package/dist/tools/get-chapter-implementation-checklist.js.map +1 -1
- package/dist/tools/get-guide-by-role.d.ts +2 -0
- package/dist/tools/get-guide-by-role.js +2 -0
- package/dist/tools/get-guide-by-role.js.map +1 -1
- package/dist/tools/get-operating-model.js +2 -0
- package/dist/tools/get-operating-model.js.map +1 -1
- package/dist/tools/get-threat-landscape.d.ts +2 -0
- package/dist/tools/get-threat-landscape.js +2 -0
- package/dist/tools/get-threat-landscape.js.map +1 -1
- package/dist/tools/get-verification-matrix.js +2 -0
- package/dist/tools/get-verification-matrix.js.map +1 -1
- package/dist/tools/map-regulatory-activation.js +2 -0
- package/dist/tools/map-regulatory-activation.js.map +1 -1
- package/dist/tools/plan-rollout.js +2 -0
- package/dist/tools/plan-rollout.js.map +1 -1
- package/dist/tools/prepare-codegen-context.d.ts +2 -0
- package/dist/tools/prepare-codegen-context.js +2 -0
- package/dist/tools/prepare-codegen-context.js.map +1 -1
- package/dist/tools/resolve-entities.d.ts +2 -0
- package/dist/tools/resolve-entities.js +5 -0
- package/dist/tools/resolve-entities.js.map +1 -1
- package/dist/tools/select-requirements.d.ts +1 -11
- package/dist/tools/select-requirements.js +2 -0
- package/dist/tools/select-requirements.js.map +1 -1
- package/dist/tools/structured-tools.js +27 -86
- package/dist/tools/structured-tools.js.map +1 -1
- package/dist/version-info.d.ts +2 -0
- package/dist/version-info.js +6 -0
- package/dist/version-info.js.map +1 -1
- package/package.json +1 -1
package/assets/agent-guide.md
CHANGED
|
@@ -29,6 +29,15 @@ because the retrieved context is in Portuguese.
|
|
|
29
29
|
|
|
30
30
|
## Session setup
|
|
31
31
|
|
|
32
|
+
**Step 0 — identify the server.** Read resource `sbd://toe/version` (via `resources/read`),
|
|
33
|
+
or — on clients without resource support — call `read_sbd_toe_resource(uri="sbd://toe/version")`.
|
|
34
|
+
It returns the server name/version plus the served knowledge identity from the verified pin:
|
|
35
|
+
`manual {tag, commit}`, `kg {release_tag, sha256, source, consumer_contract_version}`,
|
|
36
|
+
`ontology {tag, commit}`. Every tool response also carries the compact stamp
|
|
37
|
+
`provenance.kg` (the served kg release_tag). The same tool mirrors ANY resource of the
|
|
38
|
+
list below — including the templated ones (e.g. `sbd://toe/codegen-instructions/codegen`,
|
|
39
|
+
the target of `codegen_instructions_ref` in dieted payloads).
|
|
40
|
+
|
|
32
41
|
After reading this guide, run:
|
|
33
42
|
|
|
34
43
|
```
|
|
@@ -285,6 +294,8 @@ Always distinguish between:
|
|
|
285
294
|
| "Governance plan for this repo" | `plan_sbd_toe_repo_governance` → generate plan from returned artefact list |
|
|
286
295
|
| "What to review given these changed files?" | `map_sbd_toe_review_scope` |
|
|
287
296
|
| "Set up SbD-ToE for this client / create a skill" | `generate_sbd_toe_skill` |
|
|
297
|
+
| "What server / manual / KG version is this?" | resource `sbd://toe/version`, or `read_sbd_toe_resource(uri="sbd://toe/version")` on clients without resources |
|
|
298
|
+
| "Client cannot read MCP resources" | `read_sbd_toe_resource(uri)` — verbatim mirror of any resource, templated URIs included |
|
|
288
299
|
|
|
289
300
|
---
|
|
290
301
|
|
|
@@ -294,8 +305,9 @@ Always distinguish between:
|
|
|
294
305
|
|---|---|
|
|
295
306
|
| `sbd://toe/agent-guide` | This document — full operational guide |
|
|
296
307
|
| `sbd://toe/index-compact` | Full chapter map as JSON — fast structured lookup |
|
|
297
|
-
| `sbd://toe/chapter-applicability/{riskLevel}` |
|
|
308
|
+
| `sbd://toe/chapter-applicability/{riskLevel}` | Graduated applicability: every chapter present, per-chapter demand for the level |
|
|
298
309
|
| `sbd://toe/ontology` | Full ontology YAML — domain_mapping, concerns, inference rules |
|
|
310
|
+
| `sbd://toe/version` | Server identity + served knowledge provenance (manual/kg/ontology, from the pin) — read at session start |
|
|
299
311
|
|
|
300
312
|
---
|
|
301
313
|
|
|
@@ -334,7 +346,7 @@ Always distinguish between:
|
|
|
334
346
|
|
|
335
347
|
| Level | Scope | Unlocks |
|
|
336
348
|
|---|---|---|
|
|
337
|
-
| `L1` | Low risk — internal, no sensitive data |
|
|
349
|
+
| `L1` | Low risk — internal, no sensitive data | ALL chapters — demand mostly recomendado/opcional |
|
|
338
350
|
| `L2` | Medium risk — public APIs, user data | + chapters 06, 11 |
|
|
339
351
|
| `L3` | High risk — PII, regulated systems | + chapter 13 |
|
|
340
352
|
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import readline from "node:readline";
|
|
|
5
5
|
import { getConfig, resolveAppPath } from "./config.js";
|
|
6
6
|
import { formatSampledAnswerResult, inspectManualRetrieval, prepareManualAnsweringContext, searchManualQuestion } from "./orchestrator/ask-manual.js";
|
|
7
7
|
import { loadSystemPromptTemplate } from "./prompt/system-prompt.js";
|
|
8
|
-
import { loadBundleProvenance } from "./version-info.js";
|
|
8
|
+
import { loadBundleProvenance, servedKgReleaseTag } from "./version-info.js";
|
|
9
9
|
import { handleGetSbdToeChapterBrief, handleListSbdToeChapters, handleMapSbdToeApplicability, handleQuerySbdToeEntities } from "./tools/structured-tools.js";
|
|
10
10
|
import { handleGenerateSbdToeSkill } from "./tools/generate-sbd-toe-skill.js";
|
|
11
11
|
import { handleMapSbdToeReviewScope } from "./tools/map-review-scope.js";
|
|
@@ -56,6 +56,180 @@ function loadPackageMetadata() {
|
|
|
56
56
|
};
|
|
57
57
|
return cachedPackageMetadata;
|
|
58
58
|
}
|
|
59
|
+
/** The single source of the resource surface — resources/list AND the
|
|
60
|
+
* read_sbd_toe_resource tool derive from THIS list (never hardcoded twice). */
|
|
61
|
+
const RESOURCE_CATALOG = [
|
|
62
|
+
{
|
|
63
|
+
uri: "sbd://toe/agent-guide",
|
|
64
|
+
name: "SbD-ToE Agent Guide",
|
|
65
|
+
description: "READ THIS FIRST. Operational guide for AI agents: SbD-ToE identity (Security by Design — Theory of Everything), CONSULT/GUIDE modes, routing by SDLC phase and domain, tool selection, epistemic standards, chapter map, risk levels, identifier conventions.",
|
|
66
|
+
mimeType: "text/markdown"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
uri: "sbd://toe/chapter-applicability/{riskLevel}",
|
|
70
|
+
name: "SbD-ToE Chapter Applicability",
|
|
71
|
+
description: "Graduated chapter applicability for a risk level (L1/L2/L3): presence always, demand scales — derived from authored assignment proportionality (0.14.0).",
|
|
72
|
+
mimeType: "application/json"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
uri: "sbd://toe/index-compact",
|
|
76
|
+
name: "SbD-ToE Index Compact",
|
|
77
|
+
description: "Compact JSON index of the full SbD-ToE manual. Injectable into system prompt to eliminate exploratory discovery.",
|
|
78
|
+
mimeType: "application/json"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
uri: "sbd://toe/ontology",
|
|
82
|
+
name: "SbD-ToE Ontology",
|
|
83
|
+
description: "Full SbD-ToE ontology YAML: domain_mapping (requirement category → control domains), " +
|
|
84
|
+
"inference rules with priorities, resolution pipelines (consult/guide/threats/review), " +
|
|
85
|
+
"and entity schemas. Read once per session to understand the deterministic resolution model " +
|
|
86
|
+
"before calling consult_security_requirements, get_threat_landscape or get_guide_by_role.",
|
|
87
|
+
mimeType: "application/yaml"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
uri: "sbd://toe/skill/{role}",
|
|
91
|
+
name: "SbD-ToE Role Skill",
|
|
92
|
+
description: "Role-specialised SbD-ToE skill for a canonical role (default risk L2) — the role's manual " +
|
|
93
|
+
"slice as installable skill content. Same output as generate_sbd_toe_skill(role, format=skill).",
|
|
94
|
+
mimeType: "text/markdown"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
uri: "sbd://toe/subagent/{role}",
|
|
98
|
+
name: "SbD-ToE Role Sub-agent Definition",
|
|
99
|
+
description: "Installable sub-agent definition for a canonical role (default risk L2, harnessed flavour — " +
|
|
100
|
+
"grants mcp__sbd-toe__* tools). Same output as generate_sbd_toe_skill(role, format=subagent).",
|
|
101
|
+
mimeType: "text/markdown"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
uri: "sbd://toe/codegen-instructions/{mode}",
|
|
105
|
+
name: "SbD-ToE Codegen Instructions (per mode)",
|
|
106
|
+
description: "Static per-mode boilerplate of prepare_sbd_toe_codegen_context (mode: codegen, review or " +
|
|
107
|
+
"test-plan): llm_codegen_instructions slots + security_rationale_template skeleton — " +
|
|
108
|
+
"byte-identical to the detail=full inline content when assembled per the embedded rules — " +
|
|
109
|
+
"plus the detail_encoding legend for detail=standard/minimal payloads (v2 token diet). " +
|
|
110
|
+
"Referenced by codegen_instructions_ref in dieted payloads.",
|
|
111
|
+
mimeType: "application/json"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
uri: "sbd://toe/version",
|
|
115
|
+
name: "SbD-ToE MCP Version",
|
|
116
|
+
description: "Version of the running SbD-ToE MCP server (name, version, description) plus the provenance of the served knowledge: manual {version, commit}, kg {release_tag, substrate_version, consumer_contract_version} and ontology {tag, commit}, read from the consumed-bundle pin.",
|
|
117
|
+
mimeType: "application/json"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
uri: "sbd://toe/grounded-codegen-guide",
|
|
121
|
+
name: "SbD-ToE Grounded Codegen Guide",
|
|
122
|
+
description: "Agent-facing guide for using prepare_sbd_toe_codegen_context. " +
|
|
123
|
+
"Covers workflow, branching by status (ready_for_codegen / needs_clarification / " +
|
|
124
|
+
"needs_decomposition / unsupported_scope), output discipline (cite citation_map, fill " +
|
|
125
|
+
"security_rationale, distinguish code/tests/evidence), and explicit prohibitions " +
|
|
126
|
+
"(no invented IDs, no compliance claims, no rastreabilidade-noise inside source files).",
|
|
127
|
+
mimeType: "text/markdown"
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
/** Declared resource-read failure (never-silent): carries the JSON-RPC code. */
|
|
131
|
+
/**
|
|
132
|
+
* Materialize any resource of RESOURCE_CATALOG by concrete URI (templated URIs
|
|
133
|
+
* take the value in the URI, e.g. sbd://toe/codegen-instructions/codegen).
|
|
134
|
+
* Shared by resources/read AND the read_sbd_toe_resource tool (0.13.0) — one
|
|
135
|
+
* implementation, no drift. Unknown URI ⇒ ResourceReadError listing the valid set.
|
|
136
|
+
*/
|
|
137
|
+
async function materializeResource(uri) {
|
|
138
|
+
const path = uri.startsWith("sbd:") ? uri.slice(4) : "";
|
|
139
|
+
const applicabilityMatch = /^\/\/toe\/chapter-applicability\/([^/]+)$/.exec(path);
|
|
140
|
+
if (applicabilityMatch !== null) {
|
|
141
|
+
const riskLevel = applicabilityMatch[1] ?? "";
|
|
142
|
+
if (!["L1", "L2", "L3"].includes(riskLevel)) {
|
|
143
|
+
throw new ResourceReadError(-32602, `Invalid riskLevel: "${riskLevel}". Allowed values: L1, L2, L3.`);
|
|
144
|
+
}
|
|
145
|
+
const data = buildChapterApplicabilityJson(riskLevel);
|
|
146
|
+
return { mimeType: "application/json", text: JSON.stringify(data, null, 2) };
|
|
147
|
+
}
|
|
148
|
+
const codegenInstructionsMatch = /^\/\/toe\/codegen-instructions\/([^/]+)$/.exec(path);
|
|
149
|
+
if (codegenInstructionsMatch !== null) {
|
|
150
|
+
const mode = codegenInstructionsMatch[1] ?? "";
|
|
151
|
+
if (!["codegen", "review", "test-plan"].includes(mode)) {
|
|
152
|
+
throw new ResourceReadError(-32602, `Invalid codegen-instructions mode: "${mode}". Allowed values: codegen, review, test-plan.`);
|
|
153
|
+
}
|
|
154
|
+
const content = buildCodegenInstructionsResourceContent(mode);
|
|
155
|
+
return { mimeType: "application/json", text: JSON.stringify(content, null, 2) };
|
|
156
|
+
}
|
|
157
|
+
const roleSkillMatch = /^\/\/toe\/(skill|subagent)\/([^/]+)$/.exec(path);
|
|
158
|
+
if (roleSkillMatch !== null) {
|
|
159
|
+
const format = roleSkillMatch[1] === "subagent" ? "subagent" : "skill";
|
|
160
|
+
const role = decodeURIComponent(roleSkillMatch[2] ?? "");
|
|
161
|
+
try {
|
|
162
|
+
const result = handleGenerateSbdToeSkill({ role, format });
|
|
163
|
+
return { mimeType: "text/markdown", text: result.content };
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
throw new ResourceReadError(-32602, error instanceof Error ? error.message : "Could not generate role skill.");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (uri === "sbd://toe/index-compact") {
|
|
170
|
+
try {
|
|
171
|
+
return { mimeType: "application/json", text: readFileSync(resolveAppPath("data/publish/sbd-toe-index-compact.json"), "utf-8") };
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
throw new ResourceReadError(-32603, "Could not read the SbD-ToE compact index.");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (uri === "sbd://toe/agent-guide") {
|
|
178
|
+
try {
|
|
179
|
+
return { mimeType: "text/markdown", text: readFileSync(resolveAppPath("assets/agent-guide.md"), "utf-8") };
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
throw new ResourceReadError(-32603, "Could not read SbD-ToE agent guide.");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (uri === "sbd://toe/ontology") {
|
|
186
|
+
try {
|
|
187
|
+
return { mimeType: "application/yaml", text: readFileSync(resolveAppPath("data/publish/ontology/sbdtoe-ontology.yaml"), "utf-8") };
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
throw new ResourceReadError(-32603, "Could not read SbD-ToE ontology YAML.");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (uri === "sbd://toe/grounded-codegen-guide") {
|
|
194
|
+
try {
|
|
195
|
+
return { mimeType: "text/markdown", text: readGroundedCodegenGuide() };
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
throw new ResourceReadError(-32603, "Could not read SbD-ToE grounded codegen guide.");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (uri === "sbd://toe/version") {
|
|
202
|
+
try {
|
|
203
|
+
const pkg = loadPackageMetadata();
|
|
204
|
+
const provenance = loadBundleProvenance();
|
|
205
|
+
const payload = JSON.stringify({
|
|
206
|
+
name: pkg.name,
|
|
207
|
+
version: pkg.version,
|
|
208
|
+
description: pkg.description,
|
|
209
|
+
// Provenance of the served knowledge (from the consumed-bundle.json pin).
|
|
210
|
+
// Absent if the pin cannot be read; never invented.
|
|
211
|
+
manual: provenance?.manual,
|
|
212
|
+
kg: provenance?.kg,
|
|
213
|
+
ontology: provenance?.ontology
|
|
214
|
+
});
|
|
215
|
+
return { mimeType: "application/json", text: payload };
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
throw new ResourceReadError(-32603, "Could not read package.json.");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
throw new ResourceReadError(-32602, `Unknown resource URI: ${uri}. Valid URIs (templated take the value in the URI): ${validResourceUris()}.`);
|
|
222
|
+
}
|
|
223
|
+
class ResourceReadError extends Error {
|
|
224
|
+
code;
|
|
225
|
+
constructor(code, message) {
|
|
226
|
+
super(message);
|
|
227
|
+
this.code = code;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function validResourceUris() {
|
|
231
|
+
return RESOURCE_CATALOG.map((r) => r.uri).join(", ");
|
|
232
|
+
}
|
|
59
233
|
class McpRuntime {
|
|
60
234
|
nextRequestId = 10_000;
|
|
61
235
|
pending = new Map();
|
|
@@ -291,9 +465,13 @@ class McpRuntime {
|
|
|
291
465
|
version: packageMetadata.version
|
|
292
466
|
},
|
|
293
467
|
instructions: "You are connected to the SbD-ToE MCP server (Security by Design — Theory of Everything).\n" +
|
|
294
|
-
"
|
|
468
|
+
"Chapters 00–14. Security guidance only — does not override project rules or development standards.\n" +
|
|
295
469
|
"Always respond in the user's language regardless of the manual content language.\n" +
|
|
296
470
|
"\n" +
|
|
471
|
+
"At session start, identify the server: read resource sbd://toe/version — or call the\n" +
|
|
472
|
+
"read_sbd_toe_resource tool with that URI on clients without resource support — to learn\n" +
|
|
473
|
+
"the server version and the served knowledge (manual/kg/ontology, from the verified pin).\n" +
|
|
474
|
+
"\n" +
|
|
297
475
|
"BEFORE answering any SbD-ToE question, read resource sbd://toe/agent-guide — it contains\n" +
|
|
298
476
|
"operating modes, routing by phase/domain, tool selection, epistemic standards, and chapter map.\n" +
|
|
299
477
|
"\n" +
|
|
@@ -648,7 +826,7 @@ class McpRuntime {
|
|
|
648
826
|
name: "get_sbd_toe_verification_matrix",
|
|
649
827
|
title: "Get SbD-ToE Verification Matrix",
|
|
650
828
|
description: "The EXPECTED side of verification: per requirement/control at a risk level, the validation method " +
|
|
651
|
-
"+ expected evidence + EvidencePattern reference (the
|
|
829
|
+
"+ expected evidence + EvidencePattern reference (the published patterns — totals declared per response). The deterministic " +
|
|
652
830
|
"complement of the auditor's expectation and the test-plan. Cited per row; coverage-preserving — " +
|
|
653
831
|
"declares the requirements with no EvidencePattern. Use to answer 'how do I prove chapter/level X?'.",
|
|
654
832
|
inputSchema: {
|
|
@@ -731,7 +909,7 @@ class McpRuntime {
|
|
|
731
909
|
{
|
|
732
910
|
name: "map_sbd_toe_applicability",
|
|
733
911
|
title: "Map SbD-ToE Applicability",
|
|
734
|
-
description: "
|
|
912
|
+
description: "GRADUATED applicability (0.14.0): every chapter applies at every level — returns per-chapter authored demand (obrigatório/recomendado/opcional/specific) derived from the bundle, anchored on the chapter-01 canonical matrix; plus context-conditional bundles for the given technologies. projectRole adds a per-role view. Nothing is excluded by level.",
|
|
735
913
|
inputSchema: {
|
|
736
914
|
type: "object",
|
|
737
915
|
properties: {
|
|
@@ -768,6 +946,25 @@ class McpRuntime {
|
|
|
768
946
|
},
|
|
769
947
|
annotations: { readOnlyHint: true }
|
|
770
948
|
},
|
|
949
|
+
{
|
|
950
|
+
name: "read_sbd_toe_resource",
|
|
951
|
+
title: "Read SbD-ToE Resource (mirror)",
|
|
952
|
+
description: "Mirror of resources/read for clients without MCP resource support (e.g. Claude Desktop): " +
|
|
953
|
+
"returns the content of any server resource by URI — including templated ones with the value " +
|
|
954
|
+
"in the URI (e.g. sbd://toe/codegen-instructions/codegen). Makes the codegen_instructions_ref " +
|
|
955
|
+
"of dieted prepare payloads resolvable on ANY client, and sbd://toe/version readable as a tool. " +
|
|
956
|
+
`Valid URIs: ${validResourceUris()}. ` +
|
|
957
|
+
"Unknown URI returns a declared error listing the valid set (never silent).",
|
|
958
|
+
inputSchema: {
|
|
959
|
+
type: "object",
|
|
960
|
+
properties: {
|
|
961
|
+
uri: { type: "string", minLength: 1, description: "Resource URI (see the valid list in the tool description; templated URIs take the concrete value in place of {…})." }
|
|
962
|
+
},
|
|
963
|
+
required: ["uri"],
|
|
964
|
+
additionalProperties: false
|
|
965
|
+
},
|
|
966
|
+
annotations: { readOnlyHint: true }
|
|
967
|
+
},
|
|
771
968
|
{
|
|
772
969
|
name: "select_sbd_toe_requirements",
|
|
773
970
|
title: "Select SbD-ToE Requirements (MP1)",
|
|
@@ -1326,216 +1523,21 @@ class McpRuntime {
|
|
|
1326
1523
|
this.sendError(request.id, -32602, `Unknown prompt: ${name}`);
|
|
1327
1524
|
}
|
|
1328
1525
|
handleResourcesList(request) {
|
|
1329
|
-
this.sendResponse(request.id, {
|
|
1330
|
-
resources: [
|
|
1331
|
-
{
|
|
1332
|
-
uri: "sbd://toe/agent-guide",
|
|
1333
|
-
name: "SbD-ToE Agent Guide",
|
|
1334
|
-
description: "READ THIS FIRST. Operational guide for AI agents: SbD-ToE identity (Security by Design — Theory of Everything), CONSULT/GUIDE modes, routing by SDLC phase and domain, tool selection, epistemic standards, chapter map, risk levels, identifier conventions.",
|
|
1335
|
-
mimeType: "text/markdown"
|
|
1336
|
-
},
|
|
1337
|
-
{
|
|
1338
|
-
uri: "sbd://toe/chapter-applicability/{riskLevel}",
|
|
1339
|
-
name: "SbD-ToE Chapter Applicability",
|
|
1340
|
-
description: "Active, conditional and excluded chapters for a given risk level (L1/L2/L3).",
|
|
1341
|
-
mimeType: "application/json"
|
|
1342
|
-
},
|
|
1343
|
-
{
|
|
1344
|
-
uri: "sbd://toe/index-compact",
|
|
1345
|
-
name: "SbD-ToE Index Compact",
|
|
1346
|
-
description: "Compact JSON index of the full SbD-ToE manual. Injectable into system prompt to eliminate exploratory discovery.",
|
|
1347
|
-
mimeType: "application/json"
|
|
1348
|
-
},
|
|
1349
|
-
{
|
|
1350
|
-
uri: "sbd://toe/ontology",
|
|
1351
|
-
name: "SbD-ToE Ontology",
|
|
1352
|
-
description: "Full SbD-ToE ontology YAML: domain_mapping (requirement category → control domains), " +
|
|
1353
|
-
"8 inference rules with priorities, 4 resolution pipelines (consult/guide/threats/review), " +
|
|
1354
|
-
"and entity schemas. Read once per session to understand the deterministic resolution model " +
|
|
1355
|
-
"before calling consult_security_requirements, get_threat_landscape or get_guide_by_role.",
|
|
1356
|
-
mimeType: "application/yaml"
|
|
1357
|
-
},
|
|
1358
|
-
{
|
|
1359
|
-
uri: "sbd://toe/skill/{role}",
|
|
1360
|
-
name: "SbD-ToE Role Skill",
|
|
1361
|
-
description: "Role-specialised SbD-ToE skill for a canonical role (default risk L2) — the role's manual " +
|
|
1362
|
-
"slice as installable skill content. Same output as generate_sbd_toe_skill(role, format=skill).",
|
|
1363
|
-
mimeType: "text/markdown"
|
|
1364
|
-
},
|
|
1365
|
-
{
|
|
1366
|
-
uri: "sbd://toe/subagent/{role}",
|
|
1367
|
-
name: "SbD-ToE Role Sub-agent Definition",
|
|
1368
|
-
description: "Installable sub-agent definition for a canonical role (default risk L2, harnessed flavour — " +
|
|
1369
|
-
"grants mcp__sbd-toe__* tools). Same output as generate_sbd_toe_skill(role, format=subagent).",
|
|
1370
|
-
mimeType: "text/markdown"
|
|
1371
|
-
},
|
|
1372
|
-
{
|
|
1373
|
-
uri: "sbd://toe/codegen-instructions/{mode}",
|
|
1374
|
-
name: "SbD-ToE Codegen Instructions (per mode)",
|
|
1375
|
-
description: "Static per-mode boilerplate of prepare_sbd_toe_codegen_context (mode: codegen, review or " +
|
|
1376
|
-
"test-plan): llm_codegen_instructions slots + security_rationale_template skeleton — " +
|
|
1377
|
-
"byte-identical to the detail=full inline content when assembled per the embedded rules — " +
|
|
1378
|
-
"plus the detail_encoding legend for detail=standard/minimal payloads (v2 token diet). " +
|
|
1379
|
-
"Referenced by codegen_instructions_ref in dieted payloads.",
|
|
1380
|
-
mimeType: "application/json"
|
|
1381
|
-
},
|
|
1382
|
-
{
|
|
1383
|
-
uri: "sbd://toe/version",
|
|
1384
|
-
name: "SbD-ToE MCP Version",
|
|
1385
|
-
description: "Version of the running SbD-ToE MCP server (name, version, description) plus the provenance of the served knowledge: manual {version, commit}, kg {release_tag, substrate_version, consumer_contract_version} and ontology {tag, commit}, read from the consumed-bundle pin.",
|
|
1386
|
-
mimeType: "application/json"
|
|
1387
|
-
},
|
|
1388
|
-
{
|
|
1389
|
-
uri: "sbd://toe/codegen-instructions/{mode}",
|
|
1390
|
-
name: "SbD-ToE Codegen Instructions (per mode)",
|
|
1391
|
-
description: "Static per-mode boilerplate of prepare_sbd_toe_codegen_context (mode: codegen, review or " +
|
|
1392
|
-
"test-plan): llm_codegen_instructions slots + security_rationale_template skeleton — " +
|
|
1393
|
-
"byte-identical to the detail=full inline content when assembled per the embedded rules — " +
|
|
1394
|
-
"plus the detail_encoding legend for detail=standard/minimal payloads (v2 token diet). " +
|
|
1395
|
-
"Referenced by codegen_instructions_ref in dieted payloads.",
|
|
1396
|
-
mimeType: "application/json"
|
|
1397
|
-
},
|
|
1398
|
-
{
|
|
1399
|
-
uri: "sbd://toe/grounded-codegen-guide",
|
|
1400
|
-
name: "SbD-ToE Grounded Codegen Guide",
|
|
1401
|
-
description: "Agent-facing guide for using prepare_sbd_toe_codegen_context. " +
|
|
1402
|
-
"Covers workflow, branching by status (ready_for_codegen / needs_clarification / " +
|
|
1403
|
-
"needs_decomposition / unsupported_scope), output discipline (cite citation_map, fill " +
|
|
1404
|
-
"security_rationale, distinguish code/tests/evidence), and explicit prohibitions " +
|
|
1405
|
-
"(no invented IDs, no compliance claims, no rastreabilidade-noise inside source files).",
|
|
1406
|
-
mimeType: "text/markdown"
|
|
1407
|
-
}
|
|
1408
|
-
]
|
|
1409
|
-
});
|
|
1526
|
+
this.sendResponse(request.id, { resources: RESOURCE_CATALOG });
|
|
1410
1527
|
}
|
|
1411
1528
|
async handleResourcesRead(request) {
|
|
1412
1529
|
const uri = typeof request.params?.uri === "string" ? request.params.uri : "";
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
if (!["L1", "L2", "L3"].includes(riskLevel)) {
|
|
1417
|
-
this.sendError(request.id, -32602, `Invalid riskLevel: "${riskLevel}". Allowed values: L1, L2, L3.`);
|
|
1418
|
-
return;
|
|
1419
|
-
}
|
|
1420
|
-
const data = buildChapterApplicabilityJson(riskLevel);
|
|
1421
|
-
this.sendResponse(request.id, {
|
|
1422
|
-
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(data, null, 2) }]
|
|
1423
|
-
});
|
|
1424
|
-
return;
|
|
1425
|
-
}
|
|
1426
|
-
const codegenInstructionsMatch = /^\/\/toe\/codegen-instructions\/([^/]+)$/.exec(uri.startsWith("sbd:") ? uri.slice(4) : "");
|
|
1427
|
-
if (codegenInstructionsMatch !== null) {
|
|
1428
|
-
const mode = codegenInstructionsMatch[1] ?? "";
|
|
1429
|
-
if (!["codegen", "review", "test-plan"].includes(mode)) {
|
|
1430
|
-
this.sendError(request.id, -32602, `Invalid codegen-instructions mode: "${mode}". Allowed values: codegen, review, test-plan.`);
|
|
1431
|
-
return;
|
|
1432
|
-
}
|
|
1433
|
-
const content = buildCodegenInstructionsResourceContent(mode);
|
|
1434
|
-
this.sendResponse(request.id, {
|
|
1435
|
-
contents: [
|
|
1436
|
-
{ uri, mimeType: "application/json", text: JSON.stringify(content, null, 2) }
|
|
1437
|
-
]
|
|
1438
|
-
});
|
|
1439
|
-
return;
|
|
1440
|
-
}
|
|
1441
|
-
const roleSkillMatch = /^\/\/toe\/(skill|subagent)\/([^/]+)$/.exec(uri.startsWith("sbd:") ? uri.slice(4) : "");
|
|
1442
|
-
if (roleSkillMatch !== null) {
|
|
1443
|
-
const format = roleSkillMatch[1] === "subagent" ? "subagent" : "skill";
|
|
1444
|
-
const role = decodeURIComponent(roleSkillMatch[2] ?? "");
|
|
1445
|
-
try {
|
|
1446
|
-
const result = handleGenerateSbdToeSkill({ role, format });
|
|
1447
|
-
this.sendResponse(request.id, {
|
|
1448
|
-
contents: [{ uri, mimeType: "text/markdown", text: result.content }]
|
|
1449
|
-
});
|
|
1450
|
-
}
|
|
1451
|
-
catch (error) {
|
|
1452
|
-
this.sendError(request.id, -32602, error instanceof Error ? error.message : "Could not generate role skill.");
|
|
1453
|
-
}
|
|
1454
|
-
return;
|
|
1455
|
-
}
|
|
1456
|
-
if (uri === "sbd://toe/index-compact") {
|
|
1457
|
-
const indexPath = resolveAppPath("data/publish/sbd-toe-index-compact.json");
|
|
1458
|
-
let indexText;
|
|
1459
|
-
try {
|
|
1460
|
-
indexText = readFileSync(indexPath, "utf-8");
|
|
1461
|
-
}
|
|
1462
|
-
catch {
|
|
1463
|
-
this.sendError(request.id, -32603, "Could not read the SbD-ToE compact index.");
|
|
1464
|
-
return;
|
|
1465
|
-
}
|
|
1466
|
-
this.sendResponse(request.id, {
|
|
1467
|
-
contents: [{ uri, mimeType: "application/json", text: indexText }]
|
|
1468
|
-
});
|
|
1469
|
-
return;
|
|
1470
|
-
}
|
|
1471
|
-
if (uri === "sbd://toe/agent-guide") {
|
|
1472
|
-
const guidePath = resolveAppPath("assets/agent-guide.md");
|
|
1473
|
-
let guideText;
|
|
1474
|
-
try {
|
|
1475
|
-
guideText = readFileSync(guidePath, "utf-8");
|
|
1476
|
-
}
|
|
1477
|
-
catch {
|
|
1478
|
-
this.sendError(request.id, -32603, "Could not read SbD-ToE agent guide.");
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
this.sendResponse(request.id, {
|
|
1482
|
-
contents: [{ uri, mimeType: "text/markdown", text: guideText }]
|
|
1483
|
-
});
|
|
1484
|
-
return;
|
|
1485
|
-
}
|
|
1486
|
-
if (uri === "sbd://toe/ontology") {
|
|
1487
|
-
const ontologyPath = resolveAppPath("data/publish/ontology/sbdtoe-ontology.yaml");
|
|
1488
|
-
let ontologyText;
|
|
1489
|
-
try {
|
|
1490
|
-
ontologyText = readFileSync(ontologyPath, "utf-8");
|
|
1491
|
-
}
|
|
1492
|
-
catch {
|
|
1493
|
-
this.sendError(request.id, -32603, "Could not read SbD-ToE ontology YAML.");
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
this.sendResponse(request.id, {
|
|
1497
|
-
contents: [{ uri, mimeType: "application/yaml", text: ontologyText }]
|
|
1498
|
-
});
|
|
1499
|
-
return;
|
|
1530
|
+
try {
|
|
1531
|
+
const { mimeType, text } = await materializeResource(uri);
|
|
1532
|
+
this.sendResponse(request.id, { contents: [{ uri, mimeType, text }] });
|
|
1500
1533
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
guideText = readGroundedCodegenGuide();
|
|
1505
|
-
}
|
|
1506
|
-
catch {
|
|
1507
|
-
this.sendError(request.id, -32603, "Could not read SbD-ToE grounded codegen guide.");
|
|
1534
|
+
catch (error) {
|
|
1535
|
+
if (error instanceof ResourceReadError) {
|
|
1536
|
+
this.sendError(request.id, error.code, error.message);
|
|
1508
1537
|
return;
|
|
1509
1538
|
}
|
|
1510
|
-
this.
|
|
1511
|
-
contents: [{ uri, mimeType: "text/markdown", text: guideText }]
|
|
1512
|
-
});
|
|
1513
|
-
return;
|
|
1539
|
+
this.sendError(request.id, -32603, error instanceof Error ? error.message : "Could not read resource.");
|
|
1514
1540
|
}
|
|
1515
|
-
if (uri === "sbd://toe/version") {
|
|
1516
|
-
try {
|
|
1517
|
-
const pkg = loadPackageMetadata();
|
|
1518
|
-
const provenance = loadBundleProvenance();
|
|
1519
|
-
const payload = JSON.stringify({
|
|
1520
|
-
name: pkg.name,
|
|
1521
|
-
version: pkg.version,
|
|
1522
|
-
description: pkg.description,
|
|
1523
|
-
// Provenance of the served knowledge (from the consumed-bundle.json pin).
|
|
1524
|
-
// Absent if the pin cannot be read; never invented.
|
|
1525
|
-
manual: provenance?.manual,
|
|
1526
|
-
kg: provenance?.kg,
|
|
1527
|
-
ontology: provenance?.ontology
|
|
1528
|
-
});
|
|
1529
|
-
this.sendResponse(request.id, {
|
|
1530
|
-
contents: [{ uri, mimeType: "application/json", text: payload }]
|
|
1531
|
-
});
|
|
1532
|
-
}
|
|
1533
|
-
catch {
|
|
1534
|
-
this.sendError(request.id, -32603, "Could not read package.json.");
|
|
1535
|
-
}
|
|
1536
|
-
return;
|
|
1537
|
-
}
|
|
1538
|
-
this.sendError(request.id, -32602, `Unknown resource URI: ${uri}`);
|
|
1539
1541
|
}
|
|
1540
1542
|
parseStringListArg(value) {
|
|
1541
1543
|
if (Array.isArray(value)) {
|
|
@@ -1932,6 +1934,40 @@ class McpRuntime {
|
|
|
1932
1934
|
});
|
|
1933
1935
|
return;
|
|
1934
1936
|
}
|
|
1937
|
+
case "read_sbd_toe_resource": {
|
|
1938
|
+
const uriArg = typeof args?.uri === "string" ? args.uri.trim() : "";
|
|
1939
|
+
if (uriArg.length === 0) {
|
|
1940
|
+
this.sendError(request.id, -32602, `read_sbd_toe_resource requires "uri". Valid URIs: ${validResourceUris()}.`);
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1943
|
+
try {
|
|
1944
|
+
const { mimeType, text } = await materializeResource(uriArg);
|
|
1945
|
+
const payload = {
|
|
1946
|
+
provenance: {
|
|
1947
|
+
kg: servedKgReleaseTag(),
|
|
1948
|
+
content_type: "canonical",
|
|
1949
|
+
produced_by: "resources_read_mirror",
|
|
1950
|
+
source_data: uriArg,
|
|
1951
|
+
note: "Verbatim mirror of resources/read for clients without resource support — same materialization, no drift. " +
|
|
1952
|
+
"Motivation: codegen_instructions_ref of dieted payloads is resolvable on any client."
|
|
1953
|
+
},
|
|
1954
|
+
uri: uriArg,
|
|
1955
|
+
mimeType,
|
|
1956
|
+
content: text
|
|
1957
|
+
};
|
|
1958
|
+
this.sendResponse(request.id, {
|
|
1959
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
catch (error) {
|
|
1963
|
+
if (error instanceof ResourceReadError) {
|
|
1964
|
+
this.sendError(request.id, error.code, error.message);
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
this.sendError(request.id, -32603, error instanceof Error ? error.message : "Could not read resource.");
|
|
1968
|
+
}
|
|
1969
|
+
return;
|
|
1970
|
+
}
|
|
1935
1971
|
case "select_sbd_toe_requirements": {
|
|
1936
1972
|
const result = handleSelectRequirements(args);
|
|
1937
1973
|
this.sendResponse(request.id, {
|