Semantic map of a .NET test-automation solution for AI agents — search, impact, endpoints
io.github.Karzone/TestAtlas.Mcp — MCP Server
This MCP server provides a semantic map of a .NET test-automation solution intended for AI agents. It supports capabilities described as “search,” “impact,” and “endpoints,” based on the server description provided.
🛠️ Key Features
Semantic map of a .NET test-automation solution
Search
Impact
Endpoints
🚀 Use Cases
Discover and navigate .NET test-automation components for AI agents
Find related elements via search
Identify how changes affect (“impact”) system parts
Work with defined access points (“endpoints”) within the solution
⚡ Developer Benefits
Topic-focused structure aligned with a .NET test-automation domain
Semantics for search, impact analysis, and endpoint discovery
⚠️ Limitations
Provided data does not include tool count, topics list, or detailed capabilities beyond “search, impact, endpoints.”
Large test-automation solutions are hard to navigate — for humans and for AI agents. Asked to
automate a new story, an agent can't see which steps already exist, where similar code lives, or
what conventions the solution follows — so it duplicates steps and misplaces code. TestAtlas
indexes the solution once into a single SQLite map and answers those questions precisely:
deterministically, offline, without a model or a network call.
See it
One command over the bundled 8-project sample (testatlas index samples/SampleShop/SampleShop.sln),
then testatlas report — every number below is real output:
…or let your agent ask them over MCP. Here an agent checks whether a step it is about to write
already exists — resolve_step answers with the definitions that would bind it, or the closest
near-misses to reuse instead:
jsonc
// agent → testatlas: resolve_step { "text": "I add the product to my cart" }{"status":"none",// nothing binds this exact text — don't invent it from scratch:"suggestions":[// these existing steps are the closest, ranked by shared terms{"expression":"product (.*) is added to the cart with quantity (.*)","keyword":"When","location":"SampleShop.Tests.Api/Steps/CatalogApiSteps.cs:34"},{"expression":"the cart is not empty","keyword":"Then","location":"SampleShop.Tests.Api/Steps/CatalogApiSteps.cs:43"}// …8 more]}
Live sample outputs, committed from that same solution:
HTML report (features, scenarios, bindings, class kinds, endpoints) ·
dependency map (the eight projects and their edges).
(GitHub serves .html as source, so the links route through htmlpreview.github.io — or download from docs/ and open locally.)
What you get
TestAtlas statically analyses the solution and emits codemap.db — projects and their dependency
edges, Gherkin features/scenarios/steps, step definitions and their bindings (bound / unbound /
ambiguous), page objects, API clients, helpers, test classes, and the call/usage edges connecting
them — then turns that map into answers:
Capability
What you get
🧩
Reuse-first authoring
resolve_step — would this phrase bind an existing definition? step_catalog — the reusable step vocabulary with placeholders + allowed values
💥
Impact
Blast radius — the scenarios affected by changing a class, method, step, or endpoint
🔍
Search
FTS5 over step definitions + scenarios — "does a step for this already exist?"
🔌
MCP
All of it served to an AI agent over stdio — precise answers in a few hundred tokens, no context stuffing
📊
Report & map
Self-contained HTML drill-down of the whole map + project-dependency graph
2 — Index your solution. This produces the map (./codemap.db) that every query, report, and
MCP answer reads — nothing works without it:
bash
testatlas index path/to/YourSolution.sln
No need to build or restore the solution first — indexing is a syntax-only pass, so an unrestored
checkout maps fine. Point index at a folder (or nothing) and it auto-discovers a single
.sln/.csproj there.
…and to serve it to your AI agent, continue to MCP setup.
Or run from source (no install)
bash
git clone https://github.com/Karzone/TestAtlas.git
cd TestAtlas
dotnet build TestAtlas.sln
dotnet run --project src/CodeMap.Cli -- index path/to/YourSolution.sln
🔌 Use it from an AI agent (MCP)
TestAtlas ships an MCP server — testatlas-mcp — that serves the map to any MCP-aware client
(Visual Studio / VS Code Copilot, Claude Code, and others) over stdio JSON-RPC. The agent asks a
precise question and gets an exact, structured answer straight from the .db — instead of
stuffing source files into its context window.
Prerequisites: both tools installed and a map built — steps 1–2 of the
Quick start. Then register the server:
Visual Studio / VS Code (GitHub Copilot agent mode) — add to your .mcp.json
(%USERPROFILE%\.mcp.json or <SolutionDir>\.mcp.json):
Pass the map path explicitly (as above, or via a TESTATLAS_DB env var) — most agents launch
the server from their own working directory, not your solution folder, so relying on auto-discovery
makes the server exit with code 2. In Visual Studio you can also use Tools picker → + → Add
custom MCP server to write this entry for you. On the .NET 10 SDK you can skip the install and
use "command": "dnx", "args": ["TestAtlas.Mcp", "--yes", "C:\\path\\to\\codemap.db"] — dnx
fetches and runs the server on demand.
Claude Code:
bash
claude mcp add testatlas -- testatlas-mcp path/to/codemap.db
claude mcp list # the testatlas row should read: ✔ Connected
By default the server is registered for the current project (--scope local). Add
--scope user to make it available in every project on your machine, or --scope project to
share the registration with your team via a committed .mcp.json.
IMPORTANT
MCP clients load servers at session start — if you register mid-session, restart your agent
session before the testatlas tools appear. To confirm it's actually being used (and not
silently ignored), run the checks in
docs/troubleshooting.md.
Tools exposed:
resolve_step — resolve a Gherkin phrase to the existing step definition(s) that would bind it (regex/cucumber, keyword-agnostic). exact / ambiguous / none (+ near-match suggestions ranked by shared terms). Reuse-first authoring: don't write a step that already exists.
step_catalog — the reusable step vocabulary with extracted placeholders and allowed values (cucumber {type}, regex (a|b) enums). Compose scenarios from what exists.
impact — blast radius of a change: the scenarios affected by a given class, method, step definition, or endpoint.
search_steps — full-text search over step definitions (expression text + method + class name).
search_scenarios — full-text search over scenarios (feature + scenario name + step text + tags).
get_scenario — full detail of scenario(s) by name: feature, tags, kind, example-row count, and the ordered steps.
get_step_definition — full detail of step definition(s) by expression: keyword, params, C# class/method/signature, and the scenarios that use it.
list_tags — the tag taxonomy with per-tag scenario counts, most-used first — tag new scenarios consistently.
list_endpoints — the HTTP endpoints the suite calls, each with verb, route, and scenario blast radius (highest-reach first).
project_dependencies — the implied project dependency graph (depends-on / depended-on-by), e.g. "what depends on the Party project?".
Retrieval runs locally against the SQLite file — deterministic, offline, and a few hundred tokens
per answer. Protocol details in specs/codemap-mcp.md; registration from
source and every failure mode in docs/troubleshooting.md.
📖 Commands
Command
What it does
index [<path>]
Analyse a .sln/.csproj and write the map (default ./codemap.db).
stats [<db>]
Entity counts per project, unbound/ambiguous steps, diagnostics.
search [<db>] <query>
FTS5 full-text search over step definitions and scenarios.
Exit codes0 ok · 1 completed with warnings · 2 fatal · 3 bad arguments
Run testatlas --help for the full usage text.
A typical session
bash
# Index the solution (no build needed — the pass is syntax-only)
testatlas index YourSolution.sln --output atlas.db
# Before writing a new step — does one already exist?
testatlas search atlas.db "add a product to the cart" --steps
# About to change a shared client — what will it hit?
testatlas impact atlas.db --class ProductsApiClient
# Share human-readable snapshots
testatlas report atlas.db --html atlas.html
testatlas map atlas.db --html atlas-map.html
About the bundled sample (SampleShop)
samples/SampleShop is a self-contained 8-project solution mixing API
tests and UI tests, so the map has plenty of connected nodes — real HttpClient API clients, real
Selenium IWebDriver page objects, and Reqnroll suites driving both:
Answers are deterministic — but only as fresh as the map, so re-index on change, not on a timer.
A full re-index is a single static pass (seconds), and its cost scales with solution size, not
with how much changed:
Locally — python scripts/check-map-age.py tells you when your map drifted; a
version-controlled post-merge git hook can warn automatically after every pull.
In CI — re-index on every merge to main and publish the .db as a build artifact.
Details — the staleness checker, the git hook, and copy-paste CI recipes for GitHub Actions /
Azure DevOps — in docs/keeping-the-map-fresh.md.
🎯 Design tenets
Zero config — a useful map on an unseen solution, no config file required.
Solution agnostic — heuristic, overridable detection; no company-specific assumptions.
Deterministic & offline — same input ⇒ byte-equivalent logical content; no network, no AI.
Graceful degradation — solutions without Gherkin still yield a useful map.
Public schema as contract — a versioned SQLite schema, so downstream consumers keep working
even if a third party swaps in their own indexer.
HTML visualization — self-contained report + project map generated from the db
MCP server — testatlas-mcp exposes the map to AI agents over stdio JSON-RPC (11 tools)
Second-language indexer — same schema, contract-tested
Deliberately not planned (see design tenets): LLM-assisted analysis inside
the indexer, network calls at index/query time, running or generating tests, and semantic
(compilation-based) analysis that would require a restored build. Releases and per-version notes
live on the releases page; current distribution
channels in docs/DISTRIBUTION.md.