@vitest-agent/mcp 1.0.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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/bin/vitest-agent-mcp.js +93 -0
  4. package/context.js +72 -0
  5. package/index.d.ts +1577 -0
  6. package/index.js +19 -0
  7. package/layers/McpLive.js +30 -0
  8. package/middleware/idempotency.js +128 -0
  9. package/package.json +58 -0
  10. package/prompts/explain-failure.js +27 -0
  11. package/prompts/index.js +89 -0
  12. package/prompts/regression-since-pass.js +28 -0
  13. package/prompts/tdd-resume.js +28 -0
  14. package/prompts/triage.js +24 -0
  15. package/prompts/why-flaky.js +30 -0
  16. package/prompts/wrapup.js +19 -0
  17. package/resources/index.js +155 -0
  18. package/resources/indexes.js +77 -0
  19. package/resources/manifest-schema.js +46 -0
  20. package/resources/paths.js +20 -0
  21. package/resources/patterns.js +22 -0
  22. package/resources/upstream-docs.js +22 -0
  23. package/router.js +74 -0
  24. package/server.js +838 -0
  25. package/tools/_tdd-error-envelope.js +98 -0
  26. package/tools/acceptance-metrics.js +75 -0
  27. package/tools/cache-health.js +83 -0
  28. package/tools/commit-changes.js +64 -0
  29. package/tools/configure.js +107 -0
  30. package/tools/coverage.js +76 -0
  31. package/tools/errors.js +151 -0
  32. package/tools/failure-signature-get.js +73 -0
  33. package/tools/file-coverage.js +106 -0
  34. package/tools/help.js +146 -0
  35. package/tools/history.js +121 -0
  36. package/tools/hypothesis.js +127 -0
  37. package/tools/inventory.js +377 -0
  38. package/tools/note.js +208 -0
  39. package/tools/overview.js +92 -0
  40. package/tools/ping.js +22 -0
  41. package/tools/register-agent.js +135 -0
  42. package/tools/run-tests.js +359 -0
  43. package/tools/settings-list.js +48 -0
  44. package/tools/status.js +74 -0
  45. package/tools/tdd-artifact.js +101 -0
  46. package/tools/tdd-behavior.js +177 -0
  47. package/tools/tdd-goal.js +147 -0
  48. package/tools/tdd-phase-transition-request.js +212 -0
  49. package/tools/tdd-task.js +278 -0
  50. package/tools/test.js +281 -0
  51. package/tools/trends.js +112 -0
  52. package/tools/triage-brief.js +42 -0
  53. package/tools/turn-search.js +60 -0
  54. package/tools/wrapup-prompt.js +49 -0
  55. package/tsdoc-metadata.json +11 -0
  56. package/utils/effect-to-zod.js +81 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 C. Spencer Beggs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @vitest-agent/mcp
2
+
3
+ [![npm](https://img.shields.io/npm/v/@vitest-agent/mcp?label=npm&color=cb3837)](https://www.npmjs.com/package/@vitest-agent/mcp)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-4caf50.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript 6.0](https://img.shields.io/badge/TypeScript-6.0-3178c6.svg)](https://www.typescriptlang.org/)
6
+
7
+ > **Part of the [vitest-agent](https://vitest-agent.dev) ecosystem.** Most users want **[@vitest-agent/plugin](https://www.npmjs.com/package/@vitest-agent/plugin)**, which pulls this package in automatically. Install `@vitest-agent/mcp` directly only if you run the MCP server standalone.
8
+
9
+ The `vitest-agent-mcp` MCP server bin. Exposes action-keyed tools over stdio that give LLM agents structured access to test data, coverage, history, failure signatures, TDD lifecycle state and more. Also surfaces four MCP resources (vendored Vitest docs and curated testing patterns) and six framing-only prompts.
10
+
11
+ ## Features
12
+
13
+ - **29 action-keyed tools** — per-CRUD families collapse into single tools dispatching on an `action` discriminator; covers `test_status`, `test_overview`, `test_coverage`, `test_errors`, `run_tests`, `note`, `hypothesis`, `tdd_task`, `tdd_goal`, `tdd_behavior` and more
14
+ - **Four MCP resources** — vendored Vitest documentation (`vitest://docs/`) and curated testing patterns (`vitest-agent://patterns/`) with per-page titles, descriptions and `audience`/`priority` annotations
15
+ - **Six framing prompts** — `triage`, `why-flaky`, `regression-since-pass`, `explain-failure`, `tdd-resume`, `wrapup`
16
+ - **Idempotency middleware** — `tdd_task`, `tdd_goal`, `tdd_behavior` and `hypothesis` create-actions are idempotent on derived keys
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install --save-dev @vitest-agent/mcp
22
+ # or
23
+ pnpm add -D @vitest-agent/mcp
24
+ ```
25
+
26
+ `@vitest-agent/mcp` is a required peer of `@vitest-agent/plugin` and arrives automatically with modern pnpm and npm.
27
+
28
+ ## Quick start
29
+
30
+ ```bash
31
+ npx vitest-agent-mcp
32
+ # starts the MCP server over stdio
33
+ # example output (varies by environment)
34
+ ```
35
+
36
+ The server reads the SQLite database written by `AgentPlugin` via the same XDG-derived path, so a single test run populates data for all tools.
37
+
38
+ ## Documentation
39
+
40
+ MCP reference and tool catalog at [vitest-agent.dev/mcp](https://vitest-agent.dev/mcp).
41
+
42
+ ## License
43
+
44
+ [MIT](LICENSE)
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { createCurrentSessionIdRef, createSessionContextRef, sessionContextFromEnv } from "../context.js";
3
+ import { McpLive } from "../layers/McpLive.js";
4
+ import { startMcpServer } from "../server.js";
5
+ import { CURRENT_MCP_VERSION } from "../index.js";
6
+ import { NodeContext } from "@effect/platform-node";
7
+ import { CURRENT_SDK_VERSION, PathResolutionLive, formatFatalError, resolveDataPath, resolveLogFile, resolveLogLevel } from "@vitest-agent/sdk";
8
+ import { Effect, ManagedRuntime } from "effect";
9
+
10
+ //#region src/bin.ts
11
+ /**
12
+ * Cross-package version drift check. Compares this MCP package's version
13
+ * against @vitest-agent/sdk and writes a single stderr line on mismatch.
14
+ * Observation-only — never throws. The `"0.0.0"` fallback marks a dev
15
+ * build (rslib-builder did not substitute the literal); skip the check
16
+ * to avoid spurious warnings during local source-loaded runs. See the
17
+ * root CLAUDE.md "Cross-package version drift" section.
18
+ *
19
+ * @internal
20
+ */
21
+ function checkVersionDrift() {
22
+ if ("1.0.0" === "0.0.0") return;
23
+ if (CURRENT_SDK_VERSION !== "1.0.0") process.stderr.write(`[@vitest-agent/mcp] version drift: @vitest-agent/mcp@${CURRENT_MCP_VERSION} with @vitest-agent/sdk@${CURRENT_SDK_VERSION}. Reinstall @vitest-agent/* packages so versions match.\n`);
24
+ }
25
+ /**
26
+ * Resolve the user's project directory.
27
+ *
28
+ * Precedence (most explicit wins):
29
+ *
30
+ * 1. `VITEST_AGENT_REPORTER_PROJECT_DIR` — set by the Claude Code plugin
31
+ * loader (`plugin/bin/mcp-server.mjs`) to the resolved project root.
32
+ * The loader controls this end-to-end so the value is reliable when
33
+ * set.
34
+ * 2. `CLAUDE_PROJECT_DIR` — exported by Claude Code for hook scripts and
35
+ * (per docs hints) MCP server subprocesses. Used when the loader is
36
+ * bypassed (e.g. someone wires the MCP binary up manually).
37
+ * 3. `process.cwd()` — fall-through for direct invocation outside Claude
38
+ * Code, where the user is presumably running from their project root.
39
+ */
40
+ function resolveProjectDir() {
41
+ return process.env.VITEST_AGENT_REPORTER_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
42
+ }
43
+ /**
44
+ * Optional first positional argument: an initial Claude Code chat UUID
45
+ * (the host's `chatId`) to seed the MCP server's session association.
46
+ *
47
+ * The plugin manifest (`plugin/.claude-plugin/plugin.json`) can pass this
48
+ * via Claude Code variable substitution if such a variable exists for
49
+ * sessions (the documented substitutions are `${CLAUDE_PLUGIN_ROOT}` and
50
+ * `${CLAUDE_PLUGIN_DATA}`; testing whether `${CLAUDE_SESSION_ID}` or a
51
+ * similar name is honored in `mcpServers.args` is part of the reason
52
+ * this seed path exists). When the seed is empty the agent is expected
53
+ * to recover the chat id at boot. The legacy `set_current_session_id`
54
+ * MCP tool was removed in Phase 3.
55
+ */
56
+ function resolveInitialSessionId() {
57
+ const argv = process.argv[2];
58
+ if (argv === void 0) return null;
59
+ const trimmed = argv.trim();
60
+ if (trimmed.length === 0) return null;
61
+ if (trimmed.startsWith("${") && trimmed.endsWith("}")) return null;
62
+ return trimmed;
63
+ }
64
+ async function main() {
65
+ const projectDir = resolveProjectDir();
66
+ checkVersionDrift();
67
+ const initialSessionId = resolveInitialSessionId();
68
+ const dbPath = await Effect.runPromise(resolveDataPath(projectDir).pipe(Effect.provide(PathResolutionLive(projectDir)), Effect.provide(NodeContext.layer)));
69
+ const logLevel = resolveLogLevel();
70
+ const logFile = resolveLogFile();
71
+ const runtime = ManagedRuntime.make(McpLive(dbPath, logLevel, logFile));
72
+ const recoveredContext = sessionContextFromEnv(process.env);
73
+ const ctx = {
74
+ runtime,
75
+ cwd: projectDir,
76
+ currentSessionId: createCurrentSessionIdRef(initialSessionId ?? recoveredContext?.chatId ?? null),
77
+ sessionContext: createSessionContextRef(recoveredContext)
78
+ };
79
+ const chatIdResolved = initialSessionId ?? recoveredContext?.chatId ?? null;
80
+ console.error("[vitest-agent-mcp] Starting...");
81
+ console.error(`[vitest-agent-mcp] Project: ${projectDir}`);
82
+ console.error(`[vitest-agent-mcp] Database: ${dbPath}`);
83
+ console.error(`[vitest-agent-mcp] Initial chat id: ${chatIdResolved !== null ? "(set)" : "(none — SessionStart hook had not written CLAUDE_ENV_FILE yet)"}`);
84
+ if (recoveredContext !== null) console.error("[vitest-agent-mcp] Recovered session context: agent=(set) conversation=(set)");
85
+ await startMcpServer(ctx);
86
+ }
87
+ main().catch((err) => {
88
+ process.stderr.write(`vitest-agent-mcp: ${formatFatalError(err)}\n`);
89
+ process.exit(1);
90
+ });
91
+
92
+ //#endregion
93
+ export { };
package/context.js ADDED
@@ -0,0 +1,72 @@
1
+ import { initTRPC } from "@trpc/server";
2
+
3
+ //#region src/context.ts
4
+ /**
5
+ * Creates a new {@link CurrentSessionIdRef} with an optional initial value.
6
+ *
7
+ * @param initial - the starting chat id, or `null` when unknown at construction time
8
+ * @returns a mutable ref holding the current session id
9
+ * @public
10
+ */
11
+ const createCurrentSessionIdRef = (initial = null) => {
12
+ let value = initial;
13
+ return {
14
+ get: () => value,
15
+ set: (id) => {
16
+ value = id;
17
+ }
18
+ };
19
+ };
20
+ /**
21
+ * Creates a new {@link SessionContextRef} with an optional initial value.
22
+ *
23
+ * @param initial - the starting session context, or `null` when not yet recovered
24
+ * @returns a mutable ref holding the current session context
25
+ * @public
26
+ */
27
+ const createSessionContextRef = (initial = null) => {
28
+ let value = initial;
29
+ return {
30
+ get: () => value,
31
+ set: (ctx) => {
32
+ value = ctx;
33
+ }
34
+ };
35
+ };
36
+ /**
37
+ * Resolve the boot-time SessionContext from `process.env` (the
38
+ * primary path: SessionStart wrote the exports to `CLAUDE_ENV_FILE`
39
+ * and Claude Code auto-sources that file into the MCP server child).
40
+ *
41
+ * Returns `null` when any required value is absent — callers can
42
+ * still attempt the session-map fallback before giving up.
43
+ */
44
+ const sessionContextFromEnv = (env = process.env) => {
45
+ const chatId = env.VITEST_AGENT_CHAT_ID;
46
+ const conversationId = env.VITEST_AGENT_CONVERSATION_ID;
47
+ const mainAgentId = env.VITEST_AGENT_MAIN_AGENT_ID ?? env.VITEST_AGENT_AGENT_ID;
48
+ if (chatId === void 0 || conversationId === void 0 || mainAgentId === void 0) return null;
49
+ if (chatId.length === 0 || conversationId.length === 0 || mainAgentId.length === 0) return null;
50
+ return {
51
+ chatId,
52
+ conversationId,
53
+ mainAgentId
54
+ };
55
+ };
56
+ const t = initTRPC.context().create();
57
+ const router = t.router;
58
+ const publicProcedure = t.procedure;
59
+ /**
60
+ * Factory for creating server-side tRPC callers for the MCP router.
61
+ *
62
+ * Use with {@link appRouter} in tests or programmatic contexts to invoke
63
+ * tool procedures without starting the MCP server.
64
+ *
65
+ * @public
66
+ */
67
+ const createCallerFactory = t.createCallerFactory;
68
+ /** Exported so middleware modules can attach to the same tRPC instance. */
69
+ const middleware = t.middleware;
70
+
71
+ //#endregion
72
+ export { createCallerFactory, createCurrentSessionIdRef, createSessionContextRef, middleware, publicProcedure, router, sessionContextFromEnv };