test-inventory-mcp
Reads Vitest test files via test-inventory so AI agents can discover tests, count tests by state/tag/annotation, find skipped tests and reasons, retrieve test details, and inspect scan diagnostics without running the tests.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@test-inventory-mcpwhich tests are skipped in my Playwright project and why?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
test-inventory-mcp
An MCP server for test-inventory: AI agents ask which tests a project has, which are skipped and why, without running them.
It reads Playwright and Vitest test files with test-inventory and answers from their source code. Nothing runs, nothing is written, and nothing leaves your machine.
Setup
Node.js 22.12 or newer. The client starts the server with npx and talks to it over standard input and output. Give
it the globs of your test files and the framework, as you would to test-inventory's command line.
Claude Code, in the project folder. --scope project writes .mcp.json, for everyone who works on the project:
claude mcp add --scope project test-inventory -- npx -y test-inventory-mcp@0.1 "tests/**/*.spec.ts" --framework playwrightCursor, in .cursor/mcp.json:
{
"mcpServers": {
"test-inventory": {
"command": "npx",
"args": ["-y", "test-inventory-mcp@0.1", "tests/**/*.spec.ts", "--framework", "playwright"]
}
}
}VS Code, in .vscode/mcp.json:
{
"servers": {
"test-inventory": {
"type": "stdio",
"command": "npx",
"args": ["-y", "test-inventory-mcp@0.1", "tests/**/*.spec.ts", "--framework", "playwright"]
}
}
}Without globs, as in a configuration shared by every project, the agent passes framework and patterns in each
call; the tools say so when they are missing.
The project is the folder given with --root, otherwise the one Claude Code names in CLAUDE_PROJECT_DIR, otherwise
the folder the client starts the server in.
Related MCP server: AEE MCP Server
Command line
test-inventory-mcp [<glob...> --framework <playwright|vitest>] [--root <dir>]Option | Meaning |
| The test files, relative to the project. A tool call can pass others. |
|
|
| The project. Tool calls can scan folders inside it, never outside. |
| Print the help or the version. |
Tools
Tool | Answers |
| Counts by state, tag and annotation; with |
| The tests that match |
| Every key of up to 20 tests by id, with the scan's diagnostics about them. |
| The problems the scan found, such as a file that failed to parse, by level, code or path. |
Every tool also takes directory, a folder inside the project to scan, and framework and patterns to override
the command line. Records have the keys of test-inventory's
output format.
Answers are JSON, sent both as structured content and as text. Lists come 50 items at a time (limit takes up to
200), and an answer stays under about 30,000 characters; nextCursor gets the next page. scanErrors counts the
problems that may leave tests out, and hint says what to do next when there is something to say.
Security
The server reads the test files its globs match inside the project, and, for Vitest, the files that symbolic links
among them point to, as Vitest does. It refuses a directory or pattern that reaches outside the project. It runs no code from the project, writes no files, and opens no network connections.
Answers hold text from the project's files, such as test titles, skip reasons and comments. A client should treat it as content of that project, not as instructions. To report a vulnerability, see SECURITY.md.
Versioning
Tool names, their arguments and their answers are the server's API. Before 1.0, a change that breaks them raises the
minor version, so test-inventory-mcp@0.1 in the setup above gets fixes only.
License
Available Tools
4 toolsfind_testsFind testsARead-onlyIdempotent
Lists a project's tests that match filters, read from the test files without running them: each with its id, full name, file and line, state, skip reason and condition, and tags by default. Use it for questions such as which tests are skipped and why, which tests carry @smoke, or where a .only was left in; use test_summary for counts and get_tests for every key of a few ids. Filters combine with AND; a list matches any of its values. fields picks other keys of the test records (id is always there). Answers are paged: follow nextCursor, or narrow the filters. Example: {"states": ["skip"], "withoutReason": true}.
| Name | Required | Description | Default |
|---|---|---|---|
| grep | No | Keeps tests whose fullName (describe titles and title joined with " > ") matches this regular expression, ignoring case. | |
| only | No | true keeps tests that use .only, or are in a describe that does. | |
| tags | No | Keeps tests with one of these tags, written as in the titles, such as "@smoke". | |
| limit | No | The most items to return. | |
| cursor | No | nextCursor from the previous answer, for the next page. Keep the other arguments the same. | |
| fields | No | Keys of each test record to return, besides id. Default: fullName, relativeFilePath, lineStart, state, reason, condition, tags. | |
| states | No | Keeps tests in one of these states. | |
| patterns | No | Globs of the test files, relative to `directory`, such as ["tests/**/*.spec.ts"]. Default: the ones the server was started with. | |
| directory | No | A folder inside the project to scan, relative to its root, such as "packages/web". Default: the root. | |
| framework | No | The test runner. Default: the one the server was started with. | |
| withoutReason | No | true keeps tests that don't run and give no reason. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | Yes | |
| tests | Yes | One page of matching tests, in file and line order. |
| total | Yes | All matching items, on every page. |
| framework | Yes | |
| nextCursor | Yes | |
| scanErrors | Yes | Problems of level error in the scan, which may leave tests out of the answer. |
| frameworkVersion | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds value beyond them: tests are parsed from files without executing them, results are paged ('follow nextCursor'), and filters combine with AND while list values OR. It does not discuss performance or scan scope limits, but for a local read-only tool this is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the core behavior and default return shape come first, then usage triggers, then alternatives, then filter/paging mechanics, then an example. No filler sentences, though the opening sentence packs a lot into one clause chain.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be re-explained, and the description covers purpose, filtering semantics, paging, and alternative selection. For an 11-parameter filter tool with 100% schema coverage, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (baseline 3), and the description still adds semantics the schema does not state: AND combination across filters, OR within a list, that 'fields' picks other record keys and that 'id' is always present, plus a concrete example object. This genuinely reduces invocation error.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists a project's tests that match filters') plus the key behavioral distinction that they are read from files 'without running them', and enumerates the default returned fields. It also explicitly differentiates from siblings: test_summary for counts, get_tests for every key of a few ids.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete trigger questions ('which tests are skipped and why', 'which tests carry @smoke', 'where a .only was left in') and names the two alternative tools with the condition that selects each. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_testsGet testsARead-onlyIdempotent
Returns every key of the tests with the given ids, with the scan diagnostics about them, read from the test files without running them: location, describe path, state and where it is set, condition, reason, tags, annotations, comments above the test, parameters and body hash. Use it after find_tests or test_summary, for the details of up to 20 tests. Ids come from find_tests and stay the same when a test moves to another line, but change when its title, describe or file changes; ids not in the current scan are returned in notFound. Example: {"ids": ["3f9a0c1d2e4b5a69"]}.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Test ids, as find_tests returns them. | |
| patterns | No | Globs of the test files, relative to `directory`, such as ["tests/**/*.spec.ts"]. Default: the ones the server was started with. | |
| directory | No | A folder inside the project to scan, relative to its root, such as "packages/web". Default: the root. | |
| framework | No | The test runner. Default: the one the server was started with. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | Yes | |
| tests | Yes | The tests found, in the order of ids. |
| notFound | Yes | Ids that are not in this scan. |
| framework | Yes | |
| scanErrors | Yes | Problems of level error in the scan, which may leave tests out of the answer. |
| diagnostics | Yes | Problems the scan reports about these tests. |
| frameworkVersion | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, non-destructive), and the description still adds real behavioral contract: no test execution, the id lifecycle ('stay the same when a test moves to another line, but change when its title, describe or file changes'), and that unknown ids surface in notFound rather than erroring. That is exactly the extra context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and workflow lead, with the id rules and example trailing, so it is front-loaded correctly and reads in one pass. The long enumeration of returned fields (location, describe path, state, condition, reason, tags, annotations, comments, parameters, body hash) is partly redundant against the existing output schema, which costs it a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, an annotations-covered safety profile, and 100% schema coverage, the description only needs to carry purpose, workflow, and the id contract — all present. The one gap is guidance on when to override patterns/directory/framework versus accepting the server defaults.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline would be 3, but the description adds semantics the schema does not: the provenance and mutability rules for `ids` plus a concrete example call, and the 20-id ceiling phrased as a usage constraint. The optional patterns/directory/framework overrides are left entirely to the schema, which is why this is not a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (returns) and resource (tests by id, with scan diagnostics), and explicitly frames it as static analysis ('read from the test files without running them'). The sibling set (find_tests, test_summary, scan_diagnostics) is addressed directly by naming the tools it follows, so an agent can place it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit sequencing: 'Use it after find_tests or test_summary, for the details of up to 20 tests,' which tells the agent both the workflow position and the batch size limit. It does not state when *not* to use it (e.g. prefer test_summary for bulk aggregate views), so it falls short of the 5 bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_diagnosticsScan diagnosticsARead-onlyIdempotent
Lists the problems test-inventory found while reading the test files: level error means tests may be missing from the other answers (a file that failed to parse, an import it could not follow), level warning means a value is missing or approximate (a title built at run time, a tag that is not a string). They are about reading the code, not test failures. Use it when another tool reports scanErrors, or to check why a test is missing or notLoaded. Answers are paged: follow nextCursor. Example: {"levels": ["error"]}.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Keeps problems in this file, or in the files under this folder, relative to `directory`. | |
| codes | No | Keeps problems with these codes. | |
| limit | No | The most items to return. | |
| cursor | No | nextCursor from the previous answer, for the next page. Keep the other arguments the same. | |
| levels | No | Keeps problems of these levels. | |
| patterns | No | Globs of the test files, relative to `directory`, such as ["tests/**/*.spec.ts"]. Default: the ones the server was started with. | |
| directory | No | A folder inside the project to scan, relative to its root, such as "packages/web". Default: the root. | |
| framework | No | The test runner. Default: the one the server was started with. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | Yes | |
| total | Yes | All matching items, on every page. |
| framework | Yes | |
| nextCursor | Yes | |
| diagnostics | Yes | One page of problems, in file order. |
| frameworkVersion | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description still adds real behavioral context beyond that: the semantic difference between error and warning levels, concrete causes for each, and the fact that answers are paged via nextCursor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core definition before diving into level semantics, then usage, then paging, then an example. Dense but every sentence carries information; length is justified for a tool with two enum levels the agent must interpret.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety and an output schema covering return shape, the description needn't explain results. It competently covers purpose, triggers, level semantics, and paging, though it says nothing about how the path/patterns/directory/framework parameters interact, which an agent might occasionally need.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the 8 parameters are well documented inline, so the baseline is 3. The description's example ({'levels': ['error']}) and its 'follow nextCursor' note restate what the schema already specifies for levels/cursor, adding marginal value only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists the problems test-inventory found while reading the test files') and explicitly demarcates scope versus siblings: 'They are about reading the code, not test failures.' An agent can tell this apart from test_summary/find_tests/get_tests without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggering conditions tied to sibling outputs: 'Use it when another tool reports scanErrors, or to check why a test is missing or notLoaded.' It also disambiguates the common confusion (reading problems vs test failures), leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_summaryTest summaryARead-onlyIdempotent
Counts a project's tests by state (active, skip, fixme, todo, expectedToFail, notLoaded) and by tag and annotation, from the test files, without running them. Use it first, for questions such as how many tests are skipped, or which files or tags have the most skipped tests; use find_tests to list the tests themselves. states, tags and grep count only the tests they match. groupBy "file" or "tag" adds the counts of each file or tag, sorted by name and paged with limit and cursor; a test with no tag is in no tag group. Example: {"states": ["skip", "fixme"], "groupBy": "file"}.
| Name | Required | Description | Default |
|---|---|---|---|
| grep | No | Keeps tests whose fullName (describe titles and title joined with " > ") matches this regular expression, ignoring case. | |
| tags | No | Keeps tests with one of these tags, written as in the titles, such as "@smoke". | |
| limit | No | The most items to return. | |
| cursor | No | nextCursor from the previous answer, for the next page. Keep the other arguments the same. | |
| states | No | Keeps tests in one of these states. | |
| groupBy | No | Adds the counts of each file or each tag. | |
| patterns | No | Globs of the test files, relative to `directory`, such as ["tests/**/*.spec.ts"]. Default: the ones the server was started with. | |
| directory | No | A folder inside the project to scan, relative to its root, such as "packages/web". Default: the root. | |
| framework | No | The test runner. Default: the one the server was started with. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | Yes | |
| total | Yes | |
| groups | Yes | |
| summary | Yes | Counts over the matching tests; fileCount is every file scanned. |
| framework | Yes | |
| nextCursor | Yes | |
| scanErrors | Yes | Problems of level error in the scan, which may leave tests out of the answer. |
| frameworkVersion | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive, closed-world), so the bar is lower. The description still adds real behavior: counting happens 'without running them', filters are conjunctive ('states, tags and grep count only the tests they match'), grouping is sorted by name and paged, and untagged tests fall into no tag group.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the primary use case, then semantics, then an example. Dense but nearly every clause carries information; only the example and the tag-edge-case sentence push it toward run-on length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained. For a 9-parameter, zero-required aggregation tool the description covers counting semantics, filter conjunction, grouping, pagination and the alternative tool, leaving no significant gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes beyond the schema: it explains what groupBy does (adds per-file/per-tag counts, sorted by name, paged), that cursor paging requires keeping other arguments the same, and the no-tag edge case. That is genuine added meaning over the field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Counts a project's tests by state... and by tag and annotation, from the test files, without running them') and scopes the source of truth. It also names find_tests as the sibling that lists tests, so an agent can distinguish the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: 'Use it first, for questions such as how many tests are skipped, or which files or tags have the most skipped tests; use find_tests to list the tests themselves.' Both the when-to-use and the when-to-use-something-else are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
find_tests - First observed
get_tests - First observed
scan_diagnostics - First observed
test_summary
TDQS
Scored across 4 tools
Each tool has a clearly distinct role: test_summary for aggregate counts, find_tests for filtered lists, get_tests for full details on specific ids, and scan_diagnostics for parsing problems. The descriptions explicitly cross-reference each other ('use test_summary for counts', 'use find_tests to list the tests themselves'), leaving no ambiguity about which tool to pick.
Three tools follow a clean verb_noun pattern (find_tests, get_tests, scan_diagnostics), making intent predictable. test_summary deviates by being noun-first, a minor inconsistency but still readable and unambiguous.
Four tools is well-scoped for a read-only test inventory server, with each tool covering a distinct access pattern (aggregate, list, detail, diagnostics). It is slightly lean but nothing is missing that an agent would need.
The surface covers the lifecycle of inspection well: summarize, list, drill into details, and surface scan errors, all without running tests as intended. Minor gaps exist (no direct tag/file enumeration), but find_tests and test_summary with groupBy make these workarounds available.
Maintenance
Related MCP Connectors
Approved test intent, reviewed Playwright automation and run evidence, inside your editor.
Scan any URL for AI agent readability — Vercel Spec, llmstxt.org, and agent-protocol manifests.
Stateless TS/JS compiler facts for agents: references, imports, impact. No repo index or OAuth.
Public AI web-readiness scanner and machine-facing observability discovery service.
Related MCP Servers
- AlicenseAqualityDmaintenanceWraps existing test frameworks (Jest, Vitest, Pytest) and exposes structured, LLM-optimized results via MCP tools with progressive disclosure and diff-aware execution.111MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI-first accessibility testing by investigating pages, explaining findings, and applying fixes via natural language, integrated with Playwright tests and local or cloud AI models.MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to drive Playwright-based browser automation for UI testing, returning JSON/HTML reports with screenshots without server-side LLM or test scripts.1MIT
- FlicenseAqualityBmaintenanceAllows LLM agents to query Playwright JSON test results for run summaries and failure information.2-