@shiftleftpt/sbd-toe-mcp 0.6.1 → 0.6.3

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
@@ -1,6 +1,6 @@
1
1
  # @shiftleftpt/sbd-toe-mcp
2
2
 
3
- MCP server for the SbD-ToE security manual — structured tools for Claude, GitHub Copilot, Cursor, Windsurf, Zed and any MCP-compatible client.
3
+ MCP server for the **SbD-ToE** (**Security by Design — Theory of Everything**) security manual — structured tools for Claude, GitHub Copilot, Cursor, Windsurf, Zed and any MCP-compatible client.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@shiftleftpt%2fsbd-toe-mcp)](https://www.npmjs.com/package/@shiftleftpt/sbd-toe-mcp)
6
6
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)
@@ -49,7 +49,7 @@ For full installation instructions for all clients see [`docs/installation.md`](
49
49
 
50
50
  ## What it does
51
51
 
52
- This MCP server gives any AI client structured access to the [SbD-ToE security manual](https://www.securitybydesign.dev/sbd-toe/sbd-manual/) — a comprehensive framework for secure-by-design software development.
52
+ This MCP server gives any AI client structured access to the [SbD-ToE security manual](https://www.securitybydesign.dev/sbd-toe/sbd-manual/) — a 15-chapter (00–14) framework for Security by Design — Theory of Everything.
53
53
 
54
54
  All data is bundled locally. No Algolia, no internet connection required at runtime, no API keys.
55
55
 
package/dist/index.js CHANGED
@@ -7,10 +7,10 @@ import { formatSampledAnswerResult, inspectManualRetrieval, prepareManualAnsweri
7
7
  import { loadSystemPromptTemplate } from "./prompt/system-prompt.js";
8
8
  import { getSnapshotCache, retrievePublishedContext } from "./backend/semantic-index-gateway.js";
9
9
  import { handleGetSbdToeChapterBrief, handleListSbdToeChapters, handleMapSbdToeApplicability, handleQuerySbdToeEntities } from "./tools/structured-tools.js";
10
- import { handleGenerateDocument } from "./tools/generate-document.js";
10
+ import { handleGenerateSbdToeSkill } from "./tools/generate-sbd-toe-skill.js";
11
11
  import { handleMapSbdToeReviewScope } from "./tools/map-review-scope.js";
12
12
  import { handlePlanRepoGovernance } from "./tools/plan-repo-governance.js";
13
- import { buildChapterApplicabilityJson, buildSetupAgentPrompt, buildSkillTemplateMarkdown } from "./resources/sbd-toe-resources.js";
13
+ import { buildChapterApplicabilityJson, buildSetupAgentPrompt } from "./resources/sbd-toe-resources.js";
14
14
  const PROTOCOL_VERSION = "2025-03-26";
15
15
  const LOG_LEVELS = [
16
16
  "debug",
@@ -255,7 +255,9 @@ class McpRuntime {
255
255
  "BEFORE answering any SbD-ToE question, read resource sbd://toe/agent-guide — it contains\n" +
256
256
  "operating modes, routing by phase/domain, tool selection, epistemic standards, and chapter map.\n" +
257
257
  "\n" +
258
- "Then run setup_sbd_toe_agent(riskLevel, projectRole) for risk-level specific active chapters."
258
+ "Then run setup_sbd_toe_agent(riskLevel, projectRole) for risk-level specific active chapters.\n" +
259
+ "\n" +
260
+ "To create a skill or instructions file for an AI client, use generate_sbd_toe_skill(clientType)."
259
261
  });
260
262
  }
261
263
  handleSetLogLevel(request) {
@@ -293,23 +295,23 @@ class McpRuntime {
293
295
  {
294
296
  name: "search_sbd_toe_manual",
295
297
  title: "Search SbD-ToE Manual",
296
- description: "Recupera contexto grounded do manual SbD-ToE a partir do snapshot semântico local embutido.",
298
+ description: "Retrieves grounded context from the SbD-ToE manual using the embedded local semantic snapshot.",
297
299
  inputSchema: {
298
300
  type: "object",
299
301
  properties: {
300
302
  question: {
301
303
  type: "string",
302
- description: "Pergunta em linguagem natural sobre o manual."
304
+ description: "Natural-language question about the manual."
303
305
  },
304
306
  debug: {
305
307
  type: "boolean",
306
- description: "Quando true, anexa o debug completo do retrieval."
308
+ description: "When true, appends full retrieval debug information."
307
309
  },
308
310
  topK: {
309
311
  type: "integer",
310
312
  minimum: 1,
311
313
  maximum: 15,
312
- description: "Número máximo de records usados como contexto."
314
+ description: "Maximum number of records used as context."
313
315
  }
314
316
  },
315
317
  required: ["question"],
@@ -322,23 +324,23 @@ class McpRuntime {
322
324
  {
323
325
  name: "answer_sbd_toe_manual",
324
326
  title: "Answer SbD-ToE Manual",
325
- description: "Faz retrieval do manual SbD-ToE e pede a resposta final ao modelo configurado no cliente via sampling MCP.",
327
+ description: "Retrieves SbD-ToE manual context and requests the final answer from the client's model via MCP sampling.",
326
328
  inputSchema: {
327
329
  type: "object",
328
330
  properties: {
329
331
  question: {
330
332
  type: "string",
331
- description: "Pergunta em linguagem natural sobre o manual."
333
+ description: "Natural-language question about the manual."
332
334
  },
333
335
  debug: {
334
336
  type: "boolean",
335
- description: "Quando true, anexa o debug completo."
337
+ description: "When true, appends full debug information."
336
338
  },
337
339
  topK: {
338
340
  type: "integer",
339
341
  minimum: 1,
340
342
  maximum: 15,
341
- description: "Número máximo de records usados como contexto."
343
+ description: "Maximum number of records used as context."
342
344
  }
343
345
  },
344
346
  required: ["question"],
@@ -351,19 +353,19 @@ class McpRuntime {
351
353
  {
352
354
  name: "inspect_sbd_toe_retrieval",
353
355
  title: "Inspect SbD-ToE Retrieval",
354
- description: "Inspeciona retrieval, seleção de contexto e prompt final sem pedir resposta ao modelo do cliente.",
356
+ description: "Inspects retrieval, context selection and final prompt without requesting an answer from the client model.",
355
357
  inputSchema: {
356
358
  type: "object",
357
359
  properties: {
358
360
  question: {
359
361
  type: "string",
360
- description: "Pergunta a usar na inspeção do retrieval."
362
+ description: "Question to use for the retrieval inspection."
361
363
  },
362
364
  topK: {
363
365
  type: "integer",
364
366
  minimum: 1,
365
367
  maximum: 15,
366
- description: "Número máximo de records selecionados para o prompt."
368
+ description: "Maximum number of records selected for the prompt."
367
369
  }
368
370
  },
369
371
  required: ["question"],
@@ -376,14 +378,14 @@ class McpRuntime {
376
378
  {
377
379
  name: "list_sbd_toe_chapters",
378
380
  title: "List SbD-ToE Chapters",
379
- description: "Lista os capítulos do manual SbD-ToE com id, título e aplicabilidade.",
381
+ description: "Lists SbD-ToE manual chapters with id, title and applicability.",
380
382
  inputSchema: {
381
383
  type: "object",
382
384
  properties: {
383
385
  riskLevel: {
384
386
  type: "string",
385
387
  enum: ["L1", "L2", "L3"],
386
- description: "Filtrar por nível de risco."
388
+ description: "Filter by risk level."
387
389
  }
388
390
  },
389
391
  additionalProperties: false
@@ -393,7 +395,7 @@ class McpRuntime {
393
395
  {
394
396
  name: "query_sbd_toe_entities",
395
397
  title: "Query SbD-ToE Entities",
396
- description: "Consulta entidades do manual por query, tipo, capítulo ou nível de risco.",
398
+ description: "Queries manual entities by text, entity type, chapter or risk level.",
397
399
  inputSchema: {
398
400
  type: "object",
399
401
  properties: {
@@ -411,7 +413,7 @@ class McpRuntime {
411
413
  {
412
414
  name: "get_sbd_toe_chapter_brief",
413
415
  title: "Get SbD-ToE Chapter Brief",
414
- description: "Devolve resumo operacional de um capítulo: papel, fases, artefactos, intent_topics.",
416
+ description: "Returns an operational summary of a chapter: role, phases, artefacts, intent_topics.",
415
417
  inputSchema: {
416
418
  type: "object",
417
419
  properties: {
@@ -424,66 +426,39 @@ class McpRuntime {
424
426
  },
425
427
  {
426
428
  name: "plan_sbd_toe_repo_governance",
427
- title: "Plan SbD-ToE Repo Governance",
428
- description: "Dado o tipo de repositório, plataforma e nível de risco, devolve um plano de governança com controlos aplicáveis, checkpoints de baseline, checklist de evidências e recomendações de plataforma.",
429
+ title: "List SbD-ToE Manual Artefacts",
430
+ description: "Returns the list of artefacts/documents identified in the SbD-ToE manual, " +
431
+ "grouped by chapter, with risk level applicability. " +
432
+ "Optionally filter by riskLevel (L1/L2/L3). " +
433
+ "All data comes from the manual indices — nothing is invented. " +
434
+ "The manual does not provide templates; ask the LLM to generate one if needed.",
429
435
  inputSchema: {
430
436
  type: "object",
431
437
  properties: {
432
- repoType: {
433
- type: "string",
434
- enum: ["library", "service", "webapp", "infrastructure", "pipeline", "monorepo"],
435
- description: "Tipo de repositório."
436
- },
437
- platform: {
438
- type: "string",
439
- enum: ["github", "gitlab"],
440
- description: "Plataforma de hosting do repositório."
441
- },
442
438
  riskLevel: {
443
439
  type: "string",
444
440
  enum: ["L1", "L2", "L3"],
445
- description: "Nível de risco do projecto."
446
- },
447
- organizationContext: {
448
- type: "object",
449
- description: "Contexto organizacional opcional.",
450
- properties: {
451
- scale: { type: "string", enum: ["startup", "mid-size", "enterprise"] },
452
- teamSize: { type: "integer", minimum: 1 },
453
- enforcementLevel: { type: "string", enum: ["advisory", "enforced", "strict"] }
454
- },
455
- additionalProperties: false
441
+ description: "Optional. If provided, only artefacts applicable at this risk level are returned."
456
442
  }
457
443
  },
458
- required: ["repoType", "platform", "riskLevel"],
444
+ required: [],
459
445
  additionalProperties: false
460
446
  },
461
447
  annotations: { readOnlyHint: true }
462
448
  },
463
449
  {
464
- name: "generate_document",
465
- title: "Generate SbD-ToE Document",
466
- description: "Gera o esqueleto estruturado de um documento SbD-ToE (secções, campos obrigatórios, critérios de aceitação) para um tipo e nível de risco.",
450
+ name: "generate_sbd_toe_skill",
451
+ title: "Generate SbD-ToE Skill Content",
452
+ description: "Use this tool when asked to 'create a skill for SbD-ToE', 'set up instructions', " +
453
+ "'configure this client to use SbD-ToE', or 'integrate SbD-ToE'. " +
454
+ "Returns the canonical skill content from sbd://toe/agent-guide. " +
455
+ "Save the returned content to the appropriate skill/instructions file for your client " +
456
+ "(e.g. .claude/skills/sbd-toe.md, .github/copilot-instructions.md, .cursorrules). " +
457
+ "No parameters required.",
467
458
  inputSchema: {
468
459
  type: "object",
469
- properties: {
470
- type: {
471
- type: "string",
472
- enum: ["classification-template", "threat-model-template", "checklist", "training-plan", "secure-config"],
473
- description: "Tipo de documento a gerar."
474
- },
475
- riskLevel: {
476
- type: "string",
477
- enum: ["L1", "L2", "L3"],
478
- description: "Nível de risco do projecto."
479
- },
480
- context: {
481
- type: "object",
482
- description: "Contexto adicional do projecto (reservado, não usado na estrutura).",
483
- additionalProperties: true
484
- }
485
- },
486
- required: ["type", "riskLevel"],
460
+ properties: {},
461
+ required: [],
487
462
  additionalProperties: false
488
463
  },
489
464
  annotations: { readOnlyHint: true }
@@ -491,7 +466,7 @@ class McpRuntime {
491
466
  {
492
467
  name: "map_sbd_toe_review_scope",
493
468
  title: "Map SbD-ToE Review Scope",
494
- description: "Dado um conjunto de ficheiros alterados, mapeia quais knowledge bundles SbD-ToE devem ser revistos, com reasoning explícito por path.",
469
+ description: "Given a set of changed files, maps which SbD-ToE knowledge bundles should be reviewed, with explicit reasoning per path.",
495
470
  inputSchema: {
496
471
  type: "object",
497
472
  properties: {
@@ -499,16 +474,16 @@ class McpRuntime {
499
474
  type: "array",
500
475
  items: { type: "string" },
501
476
  minItems: 1,
502
- description: "Lista de paths relativos ao raiz do repositório."
477
+ description: "List of paths relative to the repository root."
503
478
  },
504
479
  riskLevel: {
505
480
  type: "string",
506
481
  enum: ["L1", "L2", "L3"],
507
- description: "Nível de risco do projecto."
482
+ description: "Project risk level."
508
483
  },
509
484
  projectContext: {
510
485
  type: "object",
511
- description: "Contexto adicional do projecto (opcional).",
486
+ description: "Additional project context (optional).",
512
487
  properties: {
513
488
  repoRole: { type: "string" },
514
489
  runtimeModel: { type: "string" },
@@ -519,7 +494,7 @@ class McpRuntime {
519
494
  },
520
495
  diffSummary: {
521
496
  type: "string",
522
- description: "Resumo do diff (truncado a 500 chars)."
497
+ description: "Diff summary (truncated to 500 chars)."
523
498
  }
524
499
  },
525
500
  required: ["changedFiles", "riskLevel"],
@@ -530,7 +505,7 @@ class McpRuntime {
530
505
  {
531
506
  name: "map_sbd_toe_applicability",
532
507
  title: "Map SbD-ToE Applicability",
533
- description: "Mapeia capítulos/controlos activos, condicionais e excluídos para um nível de risco L1/L2/L3. Suporta contexto de projecto para activar bundles relevantes.",
508
+ description: "Maps active, conditional and excluded chapters/controls for a given risk level L1/L2/L3. Supports project context to activate relevant bundles.",
534
509
  inputSchema: {
535
510
  type: "object",
536
511
  properties: {
@@ -546,20 +521,20 @@ class McpRuntime {
546
521
  "network-segmentation", "cryptography"
547
522
  ]
548
523
  },
549
- description: "Tecnologias usadas no projecto."
524
+ description: "Technologies used in the project."
550
525
  },
551
526
  hasPersonalData: {
552
527
  type: "boolean",
553
- description: "O projecto processa dados pessoais?"
528
+ description: "Does the project process personal data?"
554
529
  },
555
530
  isPublicFacing: {
556
531
  type: "boolean",
557
- description: "O projecto tem exposição pública?"
532
+ description: "Does the project have public-facing exposure?"
558
533
  },
559
534
  projectRole: {
560
535
  type: "string",
561
536
  enum: ["developer", "architect", "security", "devops", "manager"],
562
- description: "Papel do utilizador no projecto."
537
+ description: "User role in the project."
563
538
  }
564
539
  },
565
540
  required: ["riskLevel"],
@@ -574,11 +549,11 @@ class McpRuntime {
574
549
  return {
575
550
  name: "ask_sbd_toe_manual",
576
551
  title: "Ask SbD-ToE Manual",
577
- description: "Prompt MCP para orientar o chat do VS Code a responder perguntas sobre o manual SbD-ToE com grounding.",
552
+ description: "MCP prompt to guide the AI chat to answer questions about the SbD-ToE manual with grounding.",
578
553
  arguments: [
579
554
  {
580
555
  name: "question",
581
- description: "Pergunta sobre o manual SbD-ToE.",
556
+ description: "Question about the SbD-ToE manual.",
582
557
  required: true
583
558
  }
584
559
  ]
@@ -591,16 +566,16 @@ class McpRuntime {
591
566
  {
592
567
  name: "setup_sbd_toe_agent",
593
568
  title: "Setup SbD-ToE Agent",
594
- description: "Prompt MCP para configurar um agente com o contexto e regras do manual SbD-ToE para um nível de risco.",
569
+ description: "MCP prompt to configure an agent with SbD-ToE manual context and rules for a given risk level.",
595
570
  arguments: [
596
571
  {
597
572
  name: "riskLevel",
598
- description: "Nível de risco do projecto: L1, L2 ou L3.",
573
+ description: "Project risk level: L1, L2 or L3.",
599
574
  required: true
600
575
  },
601
576
  {
602
577
  name: "projectRole",
603
- description: "Papel ou descrição do projecto (opcional).",
578
+ description: "Project role or description (optional).",
604
579
  required: false
605
580
  }
606
581
  ]
@@ -616,10 +591,10 @@ class McpRuntime {
616
591
  if (name === "ask_sbd_toe_manual") {
617
592
  const question = typeof args.question === "string" ? args.question : "";
618
593
  const promptText = `${loadSystemPromptTemplate()}\n\n` +
619
- "Use a ferramenta `search_sbd_toe_manual` antes de responder.\n" +
594
+ "Use the `search_sbd_toe_manual` tool before answering.\n" +
620
595
  `Question: ${question}`;
621
596
  this.sendResponse(request.id, {
622
- description: "Prompt grounded para perguntas sobre o manual SbD-ToE.",
597
+ description: "Grounded prompt for questions about the SbD-ToE manual.",
623
598
  messages: [
624
599
  {
625
600
  role: "user",
@@ -635,13 +610,13 @@ class McpRuntime {
635
610
  if (name === "setup_sbd_toe_agent") {
636
611
  const riskLevel = args["riskLevel"];
637
612
  if (typeof riskLevel !== "string" || !["L1", "L2", "L3"].includes(riskLevel)) {
638
- this.sendError(request.id, -32602, 'O argumento "riskLevel" é obrigatório e deve ser L1, L2 ou L3.');
613
+ this.sendError(request.id, -32602, 'The "riskLevel" argument is required and must be L1, L2 or L3.');
639
614
  return;
640
615
  }
641
616
  const projectRole = typeof args["projectRole"] === "string" ? args["projectRole"] : undefined;
642
617
  const promptText = buildSetupAgentPrompt(riskLevel, projectRole);
643
618
  this.sendResponse(request.id, {
644
- description: "Prompt para configurar um agente com o contexto SbD-ToE.",
619
+ description: "Prompt to configure an agent with SbD-ToE context.",
645
620
  messages: [
646
621
  {
647
622
  role: "user",
@@ -654,34 +629,28 @@ class McpRuntime {
654
629
  });
655
630
  return;
656
631
  }
657
- this.sendError(request.id, -32602, `Prompt desconhecida: ${name}`);
632
+ this.sendError(request.id, -32602, `Unknown prompt: ${name}`);
658
633
  }
659
634
  handleResourcesList(request) {
660
635
  this.sendResponse(request.id, {
661
636
  resources: [
662
637
  {
663
- uri: "sbd://toe/skill-template/{riskLevel}/{projectRole}",
664
- name: "SbD-ToE Skill Template",
665
- description: "Template de skill/instructions SbD-ToE para um nível de risco e papel de projecto.",
638
+ uri: "sbd://toe/agent-guide",
639
+ name: "SbD-ToE Agent Guide",
640
+ 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.",
666
641
  mimeType: "text/markdown"
667
642
  },
668
643
  {
669
644
  uri: "sbd://toe/chapter-applicability/{riskLevel}",
670
645
  name: "SbD-ToE Chapter Applicability",
671
- description: "Capítulos activos, condicionais e excluídos para um nível de risco L1/L2/L3.",
646
+ description: "Active, conditional and excluded chapters for a given risk level (L1/L2/L3).",
672
647
  mimeType: "application/json"
673
648
  },
674
649
  {
675
650
  uri: "sbd://toe/index-compact",
676
651
  name: "SbD-ToE Index Compact",
677
- description: "Índice compacto do manual SbD-ToE. Injectável em system prompt para eliminar fase de descoberta exploratória.",
652
+ description: "Compact JSON index of the full SbD-ToE manual. Injectable into system prompt to eliminate exploratory discovery.",
678
653
  mimeType: "application/json"
679
- },
680
- {
681
- uri: "sbd://toe/agent-guide",
682
- name: "SbD-ToE Agent Guide",
683
- description: "Full operational guide for agents: CONSULT/GUIDE modes, routing by phase and domain, tool selection, epistemic standards, chapter map, risk levels.",
684
- mimeType: "text/markdown"
685
654
  }
686
655
  ]
687
656
  });
@@ -692,7 +661,7 @@ class McpRuntime {
692
661
  if (applicabilityMatch !== null) {
693
662
  const riskLevel = applicabilityMatch[1] ?? "";
694
663
  if (!["L1", "L2", "L3"].includes(riskLevel)) {
695
- this.sendError(request.id, -32602, `riskLevel inválido: "${riskLevel}". Valores permitidos: L1, L2, L3.`);
664
+ this.sendError(request.id, -32602, `Invalid riskLevel: "${riskLevel}". Allowed values: L1, L2, L3.`);
696
665
  return;
697
666
  }
698
667
  const data = buildChapterApplicabilityJson(riskLevel);
@@ -701,20 +670,6 @@ class McpRuntime {
701
670
  });
702
671
  return;
703
672
  }
704
- const skillTemplateMatch = /^\/\/toe\/skill-template\/([^/]+)\/([^/]+)$/.exec(uri.startsWith("sbd:") ? uri.slice(4) : "");
705
- if (skillTemplateMatch !== null) {
706
- const riskLevel = skillTemplateMatch[1] ?? "";
707
- const projectRole = skillTemplateMatch[2] ?? "";
708
- if (!["L1", "L2", "L3"].includes(riskLevel)) {
709
- this.sendError(request.id, -32602, `riskLevel inválido: "${riskLevel}". Valores permitidos: L1, L2, L3.`);
710
- return;
711
- }
712
- const text = buildSkillTemplateMarkdown(riskLevel, projectRole);
713
- this.sendResponse(request.id, {
714
- contents: [{ uri, mimeType: "text/markdown", text }]
715
- });
716
- return;
717
- }
718
673
  if (uri === "sbd://toe/index-compact") {
719
674
  const indexPath = resolveAppPath("data/publish/sbd-toe-index-compact.json");
720
675
  let indexText;
@@ -722,7 +677,7 @@ class McpRuntime {
722
677
  indexText = readFileSync(indexPath, "utf-8");
723
678
  }
724
679
  catch {
725
- this.sendError(request.id, -32603, "Não foi possível ler o índice compacto SbD-ToE.");
680
+ this.sendError(request.id, -32603, "Could not read the SbD-ToE compact index.");
726
681
  return;
727
682
  }
728
683
  this.sendResponse(request.id, {
@@ -745,12 +700,12 @@ class McpRuntime {
745
700
  });
746
701
  return;
747
702
  }
748
- this.sendError(request.id, -32602, `URI de resource desconhecida: ${uri}`);
703
+ this.sendError(request.id, -32602, `Unknown resource URI: ${uri}`);
749
704
  }
750
705
  getStringArg(args, key) {
751
706
  const value = args[key];
752
707
  if (typeof value !== "string" || value.trim().length === 0) {
753
- throw new Error(`O argumento "${key}" é obrigatório.`);
708
+ throw new Error(`The "${key}" argument is required.`);
754
709
  }
755
710
  return value;
756
711
  }
@@ -768,7 +723,7 @@ class McpRuntime {
768
723
  }
769
724
  async requestSampling(systemPrompt, userPrompt) {
770
725
  if (!this.supportsSampling()) {
771
- throw new Error("O cliente MCP atual não declarou suporte para sampling.");
726
+ throw new Error("The current MCP client has not declared sampling support.");
772
727
  }
773
728
  const startedAt = Date.now();
774
729
  await this.log("debug", {
@@ -903,11 +858,11 @@ class McpRuntime {
903
858
  const debug = this.getOptionalBooleanArg(args, "debug");
904
859
  const topK = this.getOptionalIntegerArg(args, "topK");
905
860
  if (!this.supportsSampling()) {
906
- // Fallback gracioso: devolver top-3 documentos sem sampling
861
+ // Graceful fallback: return top-3 documents without sampling
907
862
  const bundle = await retrievePublishedContext(question, 3);
908
863
  const fallbackResult = {
909
864
  sampling_unavailable: true,
910
- note: "Sampling não disponível neste cliente. Apresentando os 3 documentos mais relevantes como contexto.",
865
+ note: "Sampling is not available in this client. Returning the 3 most relevant documents as context.",
911
866
  results: bundle.retrieved
912
867
  };
913
868
  this.sendResponse(request.id, {
@@ -983,7 +938,7 @@ class McpRuntime {
983
938
  return;
984
939
  }
985
940
  case "plan_sbd_toe_repo_governance": {
986
- const result = handlePlanRepoGovernance(args);
941
+ const result = handlePlanRepoGovernance(args, getSnapshotCache());
987
942
  this.sendResponse(request.id, {
988
943
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
989
944
  });
@@ -996,8 +951,8 @@ class McpRuntime {
996
951
  });
997
952
  return;
998
953
  }
999
- case "generate_document": {
1000
- const result = handleGenerateDocument(args);
954
+ case "generate_sbd_toe_skill": {
955
+ const result = handleGenerateSbdToeSkill();
1001
956
  this.sendResponse(request.id, {
1002
957
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1003
958
  });
@@ -1048,11 +1003,11 @@ class McpRuntime {
1048
1003
  error_code: -32602,
1049
1004
  message: "Unknown tool requested"
1050
1005
  });
1051
- this.sendError(request.id, -32602, `Tool desconhecida: ${name}`);
1006
+ this.sendError(request.id, -32602, `Unknown tool: ${name}`);
1052
1007
  }
1053
1008
  }
1054
1009
  catch (error) {
1055
- // Erros com rpcError emitem JSON-RPC error (ex: -32602 para input inválido)
1010
+ // Errors with rpcError emit JSON-RPC error (e.g. -32602 for invalid input)
1056
1011
  if (error instanceof Error &&
1057
1012
  "rpcError" in error &&
1058
1013
  error.rpcError !== null &&
@@ -1069,7 +1024,7 @@ class McpRuntime {
1069
1024
  this.sendError(request.id, rpcError.code, rpcError.message, rpcError.data);
1070
1025
  return;
1071
1026
  }
1072
- const message = error instanceof Error ? error.message : "Erro inesperado.";
1027
+ const message = error instanceof Error ? error.message : "Unexpected error.";
1073
1028
  await this.log("error", {
1074
1029
  event_type: "tool.call",
1075
1030
  outcome: "failed",