@ds9-solutions/mcp 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,11 +32,21 @@ No Windows, hosts que não resolvem `npx` usam `"command": "cmd", "args": ["/c",
32
32
  | `list_skill_files` / `get_skill_file` | Lista e lê os arquivos complementares de uma skill (`examples/`, `references/`), sob demanda |
33
33
  | `list_agents` / `get_agent` | Lista os subagentes e lê o conteúdo de um |
34
34
  | `search_guidelines` | Busca um trecho em todas as skills e agentes |
35
+ | `list_presets` | Lista os presets Spec Kit e o comando de instalação (somente leitura; não instala nada) |
35
36
 
36
37
  Também expõe prompts (`skill-<id>`, `agent-<id>`) e resources (`ds9://skills/<id>`, `ds9://agents/<id>`).
37
38
 
38
39
  Os arquivos complementares são servidos a partir de um índice em memória: só extensões permitidas, sem links simbólicos, com limite de tamanho e de quantidade, e sem acesso a caminhos arbitrários do disco.
39
40
 
41
+ ## Presets Spec Kit
42
+
43
+ Requer o `specify` (>=1.2.1) no PATH e um projeto com `.specify/`. A instalação é feita pelo próprio Spec Kit (`specify preset add --dev`), que mantém o `.registry`:
44
+
45
+ ```bash
46
+ npx -y @ds9-solutions/mcp presets list
47
+ npx -y @ds9-solutions/mcp presets add dart-frog-hexagonal [--priority 10] [--dir <projeto>]
48
+ ```
49
+
40
50
  ## Conteúdo
41
51
 
42
52
  Skills: `dart`, `hex-pattern-dart`, `dart-frog`, `driftorm`, `flutter` e `debugger`.
@@ -0,0 +1,26 @@
1
+ # Shared exceptions preset
2
+
3
+ This independent Dart Frog preset defines shared exception responsibilities
4
+ under `lib/common/exception/`: `BusinessException`, `ClientException` and
5
+ `MiddlewareException`. It does not prescribe an HTTP response format, retry
6
+ policy or another preset. Existing behavior and contracts are not changed
7
+ automatically; material conflicts must be presented to the owner.
8
+
9
+ The three template additions use `prepend` and are visible as Markdown. They
10
+ guide artifact generation and do not enforce code compliance automatically.
11
+
12
+ ## Manual installation
13
+
14
+ Requires Spec Kit 1.2.1 or later. From the target API repository root, replace
15
+ the example path with the actual location:
16
+
17
+ ```sh
18
+ specify preset add --dev /absolute/path/to/.specify_customs/exceptions
19
+ ```
20
+
21
+ Installation copies the source into the target project; edits here do not
22
+ update installed copies automatically. Consult `specify preset update --help`
23
+ or remove and reinstall manually to update. Check the template stack using
24
+ `specify preset resolve spec-template`, `specify preset resolve plan-template`
25
+ and `specify preset resolve tasks-template`. Overrides or `replace` layers
26
+ may stop lower-priority presets from contributing.
@@ -0,0 +1,25 @@
1
+ schema_version: "1.0"
2
+
3
+ preset:
4
+ id: dart-frog-exceptions
5
+ name: "[DS9] Dart Frog Exceptions"
6
+ version: "0.1.0"
7
+ description: "Guidance for shared exceptions and safe failure boundaries."
8
+
9
+ requires:
10
+ speckit_version: ">=1.2.1"
11
+
12
+ provides:
13
+ templates:
14
+ - type: template
15
+ name: spec-template
16
+ file: templates/spec-template.md
17
+ strategy: prepend
18
+ - type: template
19
+ name: plan-template
20
+ file: templates/plan-template.md
21
+ strategy: prepend
22
+ - type: template
23
+ name: tasks-template
24
+ file: templates/tasks-template.md
25
+ strategy: prepend
@@ -0,0 +1,25 @@
1
+ ## Shared exceptions: planning guidance
2
+
3
+ For APIs using this preset, shared exception definitions belong in
4
+ `lib/common/exception/`. Reuse existing definitions where compatible; identify
5
+ missing types and do not assume they are already implemented:
6
+
7
+ - `BusinessException` represents service and repository failures, preserving
8
+ the domain, appropriate status and original cause and stack for diagnostics.
9
+ - `ClientException` represents failures translated at the controller boundary,
10
+ with an appropriate status and client-safe message.
11
+ - `MiddlewareException` represents failures at the middleware boundary, with
12
+ an appropriate status and client-safe message; preserve diagnostic context
13
+ where applicable.
14
+
15
+ Plan explicit mappings between boundaries without swallowing failures or
16
+ turning them into success. Preserve approved behavior and response contracts.
17
+ Do not expose original errors, stack traces, credentials, SQL or provider
18
+ details to clients; protect sensitive information in logs as well. Include
19
+ tests for affected failure mappings, status and safe messages.
20
+
21
+ This preset independently describes exception responsibilities; it does not
22
+ choose an HTTP response format, prescribe retry policies or require another
23
+ preset. If its rules materially conflict with project governance, approved
24
+ contracts or another active preset, record the conflict and seek owner
25
+ direction before dependent decisions.
@@ -0,0 +1,7 @@
1
+ ## Failure behavior guidance
2
+
3
+ For applicable feature operations, specify observable validation and failure
4
+ behavior, expected status and safe client-facing messages according to the
5
+ approved API contract. Identify missing decisions rather than inventing error
6
+ responses. Preserve existing contracts unless the owner approves a change.
7
+ Internal exception types and their implementation belong in the plan.
@@ -0,0 +1,13 @@
1
+ ## Shared exceptions: task guidance
2
+
3
+ Where applicable, generate concrete tasks to reuse or implement
4
+ `BusinessException`, `ClientException` and `MiddlewareException` in
5
+ `lib/common/exception/`, and to map affected failures at the appropriate
6
+ boundaries. Preserve useful original causes and stacks for diagnostics without
7
+ exposing internals or sensitive data to clients or logs.
8
+
9
+ Include tests for affected error paths, status and safe messages, using the
10
+ approved contract. Do not generate unrelated refactors or change existing
11
+ responses without authorization. Surface material conflicts with project rules
12
+ or other active presets before dependent tasks. Verification tasks are
13
+ required when applicable even if the core template describes tests as optional.
@@ -0,0 +1,26 @@
1
+ # External adapters preset
2
+
3
+ This independent Dart Frog preset guides external HTTP, SDK and other service
4
+ integrations under `lib/common/adapters/<provider>/`. It does not cover
5
+ databases, `common/http` or prescribe retries. Existing integrations are not
6
+ automatically moved or changed. Conflicts with project rules or other presets
7
+ must be presented to the owner.
8
+
9
+ The three template additions use `prepend` and are visible as Markdown. They
10
+ are planning instructions, not an automated architecture enforcement tool.
11
+
12
+ ## Manual installation
13
+
14
+ Requires Spec Kit 1.2.1 or later. From the target API repository root, replace
15
+ the example path with the actual location:
16
+
17
+ ```sh
18
+ specify preset add --dev /absolute/path/to/.specify_customs/adapters
19
+ ```
20
+
21
+ Installation copies the source into the target project; edits here do not
22
+ update installed copies automatically. Consult `specify preset update --help`
23
+ or remove and reinstall manually to update. Check the template stack using
24
+ `specify preset resolve spec-template`, `specify preset resolve plan-template`
25
+ and `specify preset resolve tasks-template`. Overrides or `replace` layers
26
+ may stop lower-priority presets from contributing.
@@ -0,0 +1,25 @@
1
+ schema_version: "1.0"
2
+
3
+ preset:
4
+ id: dart-frog-external-adapters
5
+ name: "[DS9] Dart Frog External Adapters"
6
+ version: "0.1.0"
7
+ description: "Guidance for external service integrations in common adapters."
8
+
9
+ requires:
10
+ speckit_version: ">=1.2.1"
11
+
12
+ provides:
13
+ templates:
14
+ - type: template
15
+ name: spec-template
16
+ file: templates/spec-template.md
17
+ strategy: prepend
18
+ - type: template
19
+ name: plan-template
20
+ file: templates/plan-template.md
21
+ strategy: prepend
22
+ - type: template
23
+ name: tasks-template
24
+ file: templates/tasks-template.md
25
+ strategy: prepend
@@ -0,0 +1,28 @@
1
+ ## External service adapters: planning guidance
2
+
3
+ Apply these mandatory rules when the feature needs an external service:
4
+
5
+ 1. Place the technical integration under `lib/common/adapters/<provider>/`.
6
+ Keep provider-specific DTOs and conversions with the integration when
7
+ needed. Group integrations by provider; do not create unused files.
8
+ 2. Describe the external operation, input and output contracts, configuration,
9
+ authentication, data boundaries and expected failures. An adapter translates
10
+ the provider's protocol or SDK and does not own business decisions.
11
+ 3. Use project-approved dependency composition and make clients or SDK
12
+ dependencies replaceable for isolated tests. Reuse an existing configured
13
+ client or adapter when appropriate; do not assume an SDK is installed.
14
+ 4. Define explicit behavior for provider failures and malformed responses,
15
+ including timeouts where relevant and supported. Do not mask failures with
16
+ success-shaped defaults. The consumer of the adapter decides whether any
17
+ retry is appropriate; this preset neither requires nor defines retries.
18
+ 5. Keep credentials and sensitive data in approved configuration or secret
19
+ storage; do not put them in code, logs, artifacts or responses. Capture
20
+ useful diagnostics without exposing provider internals to consumers.
21
+ 6. Plan tests with fake or mocked clients for success, relevant provider
22
+ failures and malformed responses. Any live integration test requires an
23
+ explicitly configured non-production environment.
24
+
25
+ This preset works independently and does not impose a domain architecture,
26
+ database, `common/http` response policy, library or SDK. Preserve existing
27
+ contracts and code unless a change is approved. Record material conflicts with
28
+ other active project rules or presets and seek owner direction.
@@ -0,0 +1,11 @@
1
+ ## External service integration guidance
2
+
3
+ When a feature needs an external service, specify the required capability,
4
+ observable outcomes, applicable authorization, data exchanged, side effects,
5
+ and expected behavior on provider failure. Identify unknown contracts or
6
+ security requirements for clarification; do not invent provider behavior.
7
+
8
+ This guidance applies to external services accessed through HTTP, SDKs or
9
+ other protocols. Databases and the API's `common/http` response handling are
10
+ outside this preset. Apply only relevant guidance; preserve existing behavior
11
+ unless the owner approves a change.
@@ -0,0 +1,17 @@
1
+ ## External service adapters: task guidance
2
+
3
+ For each applicable integration, generate concrete tasks with paths under
4
+ `lib/common/adapters/<provider>/` for the technical adapter, necessary
5
+ provider DTOs and mappings, configuration and dependency composition.
6
+
7
+ Include tasks for explicit failure handling and isolated tests covering
8
+ successful calls, relevant failures and malformed responses. Protect
9
+ credentials and sensitive data. Add live integration tests only when an
10
+ explicit non-production environment is available and required.
11
+
12
+ Do not create database or `common/http` tasks because of this preset. Do not
13
+ add a retry policy or change existing integration behavior without an explicit
14
+ requirement. Do not install dependencies without the project's authorization.
15
+ Identify material conflicts with other active rules before dependent tasks.
16
+ These verification tasks are required when applicable, notwithstanding core
17
+ template examples that describe tests as optional.
@@ -0,0 +1,44 @@
1
+ # Dart Frog Hexagonal Architecture preset
2
+
3
+ Version 0.1.0 provides mandatory ports-and-adapters guidance for Dart Frog API
4
+ specifications, plans and tasks. It prepends focused guidance to the standard
5
+ Spec Kit templates instead of replacing their content. It does not choose a
6
+ database, ORM, schema ownership, migration policy or deployment platform.
7
+
8
+ For external access, a service uses a domain port implemented by a repository;
9
+ the repository is the gateway to the database or to a common external adapter.
10
+ The adapter performs the technical integration with the external service.
11
+
12
+ The preset describes required planning and task-generation constraints; it is
13
+ not a code linter and does not by itself enforce architectural compliance.
14
+ Existing contracts and project rules remain applicable. Material conflicts
15
+ between the preset, the project constitution, approved contracts or DS9
16
+ guidance must be surfaced to the owner before affected work proceeds.
17
+
18
+ ## Manual installation
19
+
20
+ Requires Spec Kit 1.2.1 or later. From the target API repository root, with
21
+ access to this source directory, run:
22
+
23
+ ```sh
24
+ specify preset add --dev /absolute/path/to/.specify_customs/hexagonal
25
+ ```
26
+
27
+ Replace the example path with the actual location. This is an explicit,
28
+ per-project installation; creating this directory does not install the preset.
29
+ The CLI copies the source into the target project's `.specify/presets/` and
30
+ registers it there. Later source changes do not update installed copies;
31
+ review the CLI's `specify preset update --help` or remove and reinstall
32
+ manually when an update is desired.
33
+
34
+ Verify each resolved template in the target project:
35
+
36
+ ```sh
37
+ specify preset resolve spec-template
38
+ specify preset resolve plan-template
39
+ specify preset resolve tasks-template
40
+ ```
41
+
42
+ Project overrides and other presets may take precedence. Check the resolution
43
+ output and the generated template content when troubleshooting. The project
44
+ must still explicitly invoke and approve its own Spec Kit workflows.
@@ -0,0 +1,25 @@
1
+ schema_version: "1.0"
2
+
3
+ preset:
4
+ id: dart-frog-hexagonal
5
+ name: "[DS9] Dart Frog Hexagonal Architecture"
6
+ version: "0.1.0"
7
+ description: "[DS9] Mandatory ports-and-adapters guidance for Dart Frog API artifacts."
8
+
9
+ requires:
10
+ speckit_version: ">=1.2.1"
11
+
12
+ provides:
13
+ templates:
14
+ - type: template
15
+ name: spec-template
16
+ file: templates/spec-template.md
17
+ strategy: prepend
18
+ - type: template
19
+ name: plan-template
20
+ file: templates/plan-template.md
21
+ strategy: prepend
22
+ - type: template
23
+ name: tasks-template
24
+ file: templates/tasks-template.md
25
+ strategy: prepend
@@ -0,0 +1,57 @@
1
+ <!--
2
+ [DS9] Dart Frog Hexagonal Architecture preset: mandatory planning guidance
3
+
4
+ These rules apply to Dart Frog APIs where this preset is installed. Read the
5
+ project constitution, project context, applicable approved specifications and
6
+ contracts, and relevant DS9 guidance. Distinguish existing implementations from
7
+ planned work. If a local rule, approved source contract or DS9 recommendation
8
+ materially conflicts with a rule below, record the exact conflict and request
9
+ owner direction before planning the affected work. Do not silently relax the
10
+ preset or change existing behavior.
11
+
12
+ Include a feature-specific architecture check in the completed plan:
13
+
14
+ 1. Identify affected business contexts and use the applicable parts of
15
+ lib/<context>/domain/{models,ports,services} and
16
+ lib/<context>/adapter/{controllers,dtos,repository}. Identify routes/ and
17
+ test/ paths. Reuse existing components; do not invent unused layers or
18
+ create every directory when the feature does not need it.
19
+ 2. Show the dependency direction: route -> controller -> service -> port <-
20
+ repository -> database or common external adapter -> external service.
21
+ The repository implements the port and is the gateway to the external
22
+ world, including databases and integrations. Services must not call
23
+ common external adapters, SDKs, database clients or other infrastructure
24
+ directly. Domain models, ports and services must not depend on Dart Frog,
25
+ HTTP request/response types, DTOs, database/ORM types, infrastructure
26
+ implementations or external SDKs. Ports expose typed domain contracts;
27
+ services depend on ports, not concrete repositories.
28
+ 3. Assign business rules and orchestration to services; HTTP adaptation and
29
+ input validation to controllers/DTOs; gateway orchestration and mapping to
30
+ repositories; technical external calls to the common adapter or database
31
+ client used by the repository; and only method dispatch and response
32
+ conversion to routes. Unsupported HTTP methods return 405.
33
+ 4. Plan constructor injection for service and repository dependencies and
34
+ runtime composition through scoped Dart Frog middleware/providers.
35
+ Handlers must not construct services or repositories. Shared infrastructure
36
+ may be provided by the project's approved composition root; it does not
37
+ replace injection. Follow local controller and import conventions.
38
+ 5. Plan typed failure contracts for fallible controller, service, repository
39
+ and port operations using fpdart TaskEither: BusinessException for services
40
+ and repositories, ClientException for controllers, and MiddlewareException
41
+ at middleware boundaries. Map failures explicitly and keep 5xx responses
42
+ free of internal details. Pure operations without I/O may return plain
43
+ values. Reuse existing error types and contracts; do not assume they exist.
44
+ 6. Describe endpoint contracts, validation, authentication/authorization,
45
+ error mapping and affected data/integration boundaries. Preserve approved
46
+ behavior and contracts; record unresolved conflicts instead of silently
47
+ introducing exceptions. No database, ORM, schema ownership or migration
48
+ policy is imposed by this preset.
49
+ 7. Plan proportionate verification: service business rules with mocked or fake
50
+ ports, relevant controller and route contracts including 405, failure and
51
+ authorization paths, and isolated external boundaries. Include project
52
+ analysis and test commands when applicable; integration tests must use an
53
+ explicitly configured non-production environment.
54
+
55
+ Do not install or upgrade dependencies without the project's required
56
+ authorization. Document missing prerequisites and required owner decisions.
57
+ -->
@@ -0,0 +1,23 @@
1
+ <!--
2
+ [DS9] Dart Frog Hexagonal Architecture preset: specification guidance
3
+
4
+ This preset establishes mandatory architectural constraints for Dart Frog APIs
5
+ where it is installed. Consult the project's constitution, context, approved
6
+ contracts and applicable DS9 guidance. If they materially conflict with this
7
+ preset, identify the conflict and seek owner direction before making a dependent
8
+ decision; do not silently override either rule or assume an exception.
9
+
10
+ Keep the specification focused on observable behavior rather than prescribing
11
+ classes, files or infrastructure. For each affected API operation, specify the
12
+ method and path, actors and authorization, inputs and validation, successful
13
+ responses, failure behavior, and independently verifiable acceptance criteria.
14
+ Record business rules, relevant data boundaries, side effects and existing
15
+ contracts that must be preserved. Mark unknown material behavior for
16
+ clarification rather than inventing it.
17
+
18
+ The implementation must respect ports and adapters: business rules must be
19
+ independent of HTTP, frameworks, databases and external SDKs. Architectural
20
+ details and affected components belong in the plan and tasks. This preset does
21
+ not select a database, ORM, migration policy or deployment environment, and it
22
+ does not authorize changes to established behavior or public contracts.
23
+ -->
@@ -0,0 +1,34 @@
1
+ <!--
2
+ [DS9] Dart Frog Hexagonal Architecture preset: mandatory task-generation guidance
3
+
4
+ Consult the approved spec, plan, constitution and relevant project context.
5
+ If the plan or another applicable rule materially conflicts with this preset,
6
+ identify the conflict and request owner direction before generating tasks that
7
+ depend on an unresolved decision. Preserve existing behavior and contracts;
8
+ do not infer authorization for a migration, dependency change or refactor.
9
+
10
+ Generate concrete, story-scoped tasks with actual paths and dependencies for
11
+ the applicable work, not a fixed checklist of files:
12
+ - Domain models and typed ports; business rules and orchestration in services.
13
+ - Controllers/DTOs for HTTP adaptation; repositories that implement ports and
14
+ act as gateways to databases and common external adapters, mapping external
15
+ data; thin routes and 405 handling. Services do not call common adapters,
16
+ SDKs or database clients directly.
17
+ - Constructor injection and middleware/provider composition. Reuse the
18
+ project's approved shared infrastructure instead of duplicating it.
19
+ - Fallible layer contracts using TaskEither and the appropriate
20
+ BusinessException, ClientException or MiddlewareException boundary, with
21
+ explicit safe error mapping and preservation of approved HTTP contracts.
22
+ - Tests for changed business rules using mocked or fake ports, plus applicable
23
+ validation, controller, route, 405, authorization and failure-path tests.
24
+ Isolate external systems in unit tests and use a configured non-production
25
+ environment for integration tests.
26
+ - Relevant analysis and test commands and documentation updates. Identify
27
+ missing prerequisites without adding dependencies or migrations implicitly.
28
+
29
+ These verification tasks are required whenever applicable even if the core
30
+ template's sample language describes tests as optional. Keep the existing
31
+ checklist format, user-story grouping and independent acceptance criteria.
32
+ Never generate unused layers or database/ORM-specific tasks solely because
33
+ this preset is installed.
34
+ -->
package/dist/src/index.js CHANGED
@@ -3,7 +3,8 @@
3
3
  * Ponto de entrada do pacote (o `bin` do npm aponta para este arquivo).
4
4
  * Um único executável, dois modos:
5
5
  * - `ds9-mcp` -> sobe o servidor MCP via stdio (é o que a IDE executa);
6
- * - `ds9-mcp init` -> configura a IDE do usuário e sai.
6
+ * - `ds9-mcp init` -> configura a IDE do usuário e sai;
7
+ * - `ds9-mcp presets`-> lista/instala presets Spec Kit (via `specify preset add`).
7
8
  * Manter os dois no mesmo comando permite que o `npx -y @ds9-solutions/mcp` sirva a ambos.
8
9
  */
9
10
  import { createInterface } from "node:readline/promises";
@@ -12,6 +13,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
12
13
  import { loadEntries } from "./content.js";
13
14
  import { createServer } from "./server.js";
14
15
  import { TARGETS, runInit } from "./init.js";
16
+ import { hasSpecify, installHint, installPreset, loadPresets } from "./presets.js";
15
17
  // A versão vem do package.json para existir uma única fonte (o que foi publicado no npm).
16
18
  const pkg = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8"));
17
19
  /** Lê `--nome valor` dos argumentos. Parser mínimo de propósito: evita uma dependência de CLI. */
@@ -44,16 +46,45 @@ async function init(args) {
44
46
  console.log(`✔ Instruções adicionadas em ${result.agentsFile}`);
45
47
  console.log("Reinicie a IDE/agente para carregar o servidor.");
46
48
  }
49
+ /** Modo `presets`: `presets list` ou `presets add <id> [--priority N] [--dir pasta]`. */
50
+ function presets(args) {
51
+ const [action, id] = args;
52
+ const all = loadPresets();
53
+ if (action === "list" || !action) {
54
+ for (const p of all)
55
+ console.log(`- ${p.id} v${p.version}: ${p.description}\n ${installHint(p.id)}`);
56
+ if (!hasSpecify())
57
+ console.log("\n⚠ Spec Kit (`specify`) não encontrado no PATH.");
58
+ return;
59
+ }
60
+ if (action !== "add" || !id) {
61
+ console.error("Uso: ds9-mcp presets list | presets add <id> [--priority N] [--dir pasta]");
62
+ process.exit(1);
63
+ }
64
+ const priority = flag(args, "priority");
65
+ const out = installPreset(all, id, flag(args, "dir") ?? process.cwd(), {
66
+ priority: priority !== undefined ? Number(priority) : undefined,
67
+ });
68
+ process.stdout.write(out);
69
+ console.log(`✔ Preset ${id} instalado`);
70
+ }
47
71
  /** Modo servidor: carrega o conteúdo e fica atendendo a IDE pela entrada/saída padrão. */
48
72
  async function serve() {
49
- const server = createServer(loadEntries(), pkg.version);
73
+ const server = createServer(loadEntries(), pkg.version, loadPresets());
50
74
  await server.connect(new StdioServerTransport());
51
75
  // stderr: o stdout pertence ao protocolo MCP e não pode receber logs.
52
76
  console.error(`[ds9-mcp] v${pkg.version} pronto (stdio)`);
53
77
  }
54
78
  // Qualquer erro vira mensagem curta + código de saída 1, em vez de um stack trace assustador.
55
79
  const [command, ...rest] = process.argv.slice(2);
56
- (command === "init" ? init(rest) : serve()).catch((err) => {
80
+ const run = async () => {
81
+ if (command === "init")
82
+ return init(rest);
83
+ if (command === "presets")
84
+ return presets(rest);
85
+ return serve();
86
+ };
87
+ run().catch((err) => {
57
88
  console.error(err instanceof Error ? err.message : err);
58
89
  process.exit(1);
59
90
  });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Presets do Spec Kit distribuídos pela DS9 (`presets/<id>/preset.yml` + `templates/`).
3
+ *
4
+ * A instalação é delegada ao `specify preset add --dev <pasta>`: é o Spec Kit quem copia os
5
+ * arquivos e mantém o `.specify/presets/.registry` (hash, prioridade). Nunca escrevemos nele.
6
+ */
7
+ import { execFileSync, spawnSync } from "node:child_process";
8
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { parse as parseYaml } from "yaml";
11
+ import { resolveContentRoot } from "./content.js";
12
+ export const PRESET_ID = /^[a-z0-9][a-z0-9-]{0,63}$/;
13
+ /** Lê os presets do conteúdo. Pasta ausente ou manifesto inválido são ignorados, sem quebrar o servidor. */
14
+ export function loadPresets(root = resolveContentRoot()) {
15
+ const base = join(root, "presets");
16
+ if (!existsSync(base))
17
+ return [];
18
+ const presets = [];
19
+ for (const dirent of readdirSync(base, { withFileTypes: true })) {
20
+ const manifest = join(base, dirent.name, "preset.yml");
21
+ if (!dirent.isDirectory() || !PRESET_ID.test(dirent.name) || !existsSync(manifest))
22
+ continue;
23
+ try {
24
+ const meta = parseYaml(readFileSync(manifest, "utf8"))
25
+ ?.preset;
26
+ presets.push({
27
+ id: dirent.name,
28
+ name: String(meta?.name ?? dirent.name),
29
+ version: String(meta?.version ?? "0.0.0"),
30
+ description: String(meta?.description ?? ""),
31
+ dir: join(base, dirent.name),
32
+ });
33
+ }
34
+ catch {
35
+ // manifesto ilegível: o preset simplesmente não é listado
36
+ }
37
+ }
38
+ return presets.sort((a, b) => a.id.localeCompare(b.id));
39
+ }
40
+ /** Comando que o usuário/agente pode rodar manualmente (o caminho real do pacote varia por máquina). */
41
+ export const installHint = (id) => `npx -y @ds9-solutions/mcp presets add ${id}`;
42
+ /** true quando o executável `specify` (Spec Kit) está no PATH. */
43
+ export function hasSpecify() {
44
+ return spawnSync("specify", ["--version"], { stdio: "ignore" }).status === 0;
45
+ }
46
+ /**
47
+ * Instala um preset no projeto com `specify preset add --dev`. Sem shell (execFile), e o id só é
48
+ * aceito se existir na lista carregada, então nada vindo do usuário vira caminho ou comando.
49
+ */
50
+ export function installPreset(presets, id, projectDir, opts = {}) {
51
+ const preset = presets.find((p) => p.id === id);
52
+ if (!preset) {
53
+ throw new Error(`Preset "${id}" não encontrado. Disponíveis: ${presets.map((p) => p.id).join(", ") || "(nenhum)"}`);
54
+ }
55
+ if (!hasSpecify()) {
56
+ throw new Error("Spec Kit (`specify`) não encontrado no PATH. Instale-o (https://github.com/github/spec-kit) e rode de novo.");
57
+ }
58
+ if (!existsSync(join(projectDir, ".specify"))) {
59
+ throw new Error(`${projectDir} não é um projeto Spec Kit (sem .specify/). Rode \`specify init --here\` antes.`);
60
+ }
61
+ const args = ["preset", "add", "--dev", preset.dir];
62
+ if (opts.priority !== undefined)
63
+ args.push("--priority", String(opts.priority));
64
+ return execFileSync("specify", args, { cwd: projectDir, encoding: "utf8" });
65
+ }
@@ -10,6 +10,7 @@ import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mc
10
10
  import { z } from "zod";
11
11
  import { rankByMetadata, searchBodies } from "./search.js";
12
12
  import { isSafeRelativePath, MAX_PATH_LENGTH, SKILL_ID } from "./skill-files.js";
13
+ import { installHint } from "./presets.js";
13
14
  // Enviado ao host no handshake. Hosts sem suporte nativo a skills/agentes dependem disto (e do
14
15
  // bloco no AGENTS.md) para saber que devem consultar o servidor antes de implementar.
15
16
  const INSTRUCTIONS = [
@@ -28,7 +29,7 @@ const text = (t, isError = false) => ({
28
29
  * Cria o servidor sobre uma lista de entradas já carregada. Receber as entradas por parâmetro
29
30
  * (em vez de ler do disco aqui) permite testar o servidor com conteúdo controlado.
30
31
  */
31
- export function createServer(entries, version = "0.0.0") {
32
+ export function createServer(entries, version = "0.0.0", presets = []) {
32
33
  const server = new McpServer({ name: "ds9", version }, { instructions: INSTRUCTIONS });
33
34
  // Helpers de consulta sobre as entradas.
34
35
  const byKind = (kind) => entries.filter((e) => e.kind === kind);
@@ -177,5 +178,14 @@ export function createServer(entries, version = "0.0.0") {
177
178
  }
178
179
  return text(`Skills recomendadas (use get_skill):\n${listing(skills)}\n\nAgentes recomendados (use get_agent):\n${listing(agents)}`);
179
180
  });
181
+ // list_presets — somente leitura: o MCP não instala nada; devolve o comando para o usuário rodar.
182
+ server.registerTool("list_presets", {
183
+ description: "Lista os presets Spec Kit da DS9 disponíveis e o comando para instalá-los no projeto (via `specify preset add`).",
184
+ annotations: { readOnlyHint: true },
185
+ }, async () => text(presets.length
186
+ ? presets
187
+ .map((p) => `- ${p.id} v${p.version}: ${p.description}\n instalar: ${installHint(p.id)}`)
188
+ .join("\n")
189
+ : "(nenhum preset disponível)"));
180
190
  return server;
181
191
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ds9-solutions/mcp",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Servidor MCP da DS9: expõe skills e subagentes oficiais para qualquer IDE/LLM com suporte a MCP",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",