MCP Prompt usage_guide
What the AST service (ast/src/ast_service/api/routes.py) hands a connecting agent when it reads the
usage_guide prompt — served here from GET /prompt.
# How to use the dev-vault-mcp server
This MCP server is a **read-only** window onto the **Code Vault** for a multi-repo workspace: an
indexer (the AST service, run by the user) scans service
repos for FastAPI routes and client call sites, and maintains a cross-service interface +
dependency graph (the "Code Vault") plus an auto-generated per-service knowledge base. Use it to
answer questions like "what routes does service X expose", "who calls this endpoint", or "what
changed since the last index" — without cloning or grepping the repos yourself.
**Use the code map first.** To find code — "where is X", "what does Y touch", "what breaks if I
change Z" — call `get_code_map` / `search_code_map` *before* grepping or opening files. The map
lists every service, unit, client method and route with its `file:line`, and draws how they connect
as trees, so you can open only the few files that matter instead of scanning the codebase:
```
CustomerService
│
├──uses──> CustomerModel
│
└──uses──> DatabaseUtils
```
## Tools
- **`get_code_map(repo, service=None, symbol=None, depth=1)`** — start here. With no arguments:
the index (services, most depended-on units, links between services). With `service`: that
service's units/routes/clients. With `symbol` (a unit, class, client method, route function or
path): that one thing and what it `uses` / is `used by` (Delphi units) or `calls` / is
`called by` (HTTP clients and routes, any language); `depth` (1-5) follows the relations
further. Every entry carries `file:line`. Only units indexed in the repo are drawn as nodes;
framework units are listed as `external`.
- **`search_code_map(repo, query, limit=30)`** — find symbols whose name or path contains
`query` when you don't know the exact name, then pass one to `get_code_map(symbol=...)`.
- **Syncing/clearing the vault is not available to you.** There are no `sync_repo`/`clear_vault`
tools: only the user can re-index or wipe the vault (from the dashboard or the `ast-service` CLI).
If the data looks stale or missing, report how stale it is (see "Typical workflow" below) and
let them decide.
- **`get_interfaces(repo, kind=None)`** — that repo's indexed routes, client methods
(`*_client.py` and Delphi HTTP callers), Delphi/Python units, and UI pages (Jinja2 templates,
Delphi `.dfm` forms/frames/datamodules), keyed by source file.
`kind="routes"`, `"clients"`, `"units"` or `"ui_pages"` narrows the result; omit it for all four. Equivalent
to reading `vault://code-vault/{repo}` and picking out those keys.
- **`get_docs(repo, file=None)`** — that repo's documentation files (markdown, Word, Excel,
PowerPoint, pdf) collected on every pull, keyed by source file with title/type/size/`github_url`.
Pass `file` to get that document's extracted text as a markdown note with uniform front matter
(also on disk under `data/vaults/knowledge-base/<repo>/docs/`). Legacy `.doc/.xls/.ppt` are listed
but `extraction: metadata-only`.
- **`get_dependencies(repo, route_path=None, client_method=None)`** — that repo's dependency
edges (client call site → route it calls). Pass `route_path` to answer "who depends on this
endpoint", `client_method` to answer "what does this client call", or neither for the whole
graph.
- **`find_circular_dependencies(repo, language=None, limit=50)`** — circular dependencies between
the repo's units/modules, from the indexed `uses`/import graph. Each cycle has its members, one
shortest example path and a `severity`: `error` = Delphi interface-section cycle (a compile
error), `info` = Delphi cycle closed only through implementation `uses` (legal), `warning` =
Python/Java cycle. `summary` counts every cycle; `limit` caps the list. `language` is
"delphi", "python" or "java". Each member carries a `github_url` permalink (share it with the
user).
- **`find_dead_code(repo, language=None, kind=None, min_confidence="medium", path_prefix="", limit=50)`**
— functions, methods and classes nothing reachable mentions, plus orphan files. Reachability is
by name from entry points (routes, decorated handlers, `main`, dunder methods, tests), so it is
conservative. `confidence`: `certain` (private, never mentioned), `high` (orphan file), `medium`
(public, never mentioned in the repo — may be used from outside it), `low` (dynamic access, a
possible framework/base-class hook, or a script). `kind` is function/method/class/module. If the
result has a `note` (repo indexed before symbol support), tell the user — don't sync yourself.
Each finding has a `github_url` permalink to the exact lines (share it with the user).
- **`get_service_status(repo)`** — index-freshness status: whether/when the repo was last
indexed, and its current route/client/ui_pages/dependency counts. There's no live health-check or
deploy-tracking infrastructure behind this yet, so it answers "how current is the vault", not
"is the service actually up" — pair it with `get_ci_status` for the closest available signal on
that.
- **`get_languages(repo)`** — the repo's languages (Delphi, Java, Python, SQL) with file count, lines
of code and indexed units each, plus the SQL tables/views/procedures from `.sql` files (columns,
references, and which code units use each table — embedded SQL in Delphi/Java/Python is linked
too). Use it first for a technical specification: it gives the stack and the data model. Older
indexes have no language data until their next full index — tell the user, don't sync yourself.
- **`get_ci_status(per_page=5)`** — the most recent CI runs for the configured repo, queried
live from the provider's API: GitHub Actions workflow runs, or GitLab pipelines. Best-effort:
returns `{"available": False, "reason": ...}` instead of raising if it can't reach the host (no
`GITHUB_TOKEN` / `GITLAB_TOKEN` set and the repo is private, rate-limited, or offline) — never treat
`available: false` as an error worth surfacing loudly, it's an expected degraded mode.
- **`notify_team(route_path)`** — manually re-runs the alert step for one route: looks up which
client methods depend on it and logs an alert for each (the AST service log only for now — no real
alert channel exists yet). Useful for "who breaks if I change this endpoint" without waiting for
the next sync to detect the change itself.
## Resources
Read-only, browsable without calling a tool first:
- `vault://code-vault` — every indexed repo, with its route/client/ui_pages/dependency counts. Start here
to discover which repo name(s) to use below; don't assume a fixed name.
- `vault://code-vault/{repo}` — that repo's full index: `routes`, `clients`, `units`, `ui_pages`
(Jinja2 templates linked back to the route(s) that render them, and Delphi `.dfm`
forms/frames/datamodules linked to their paired unit),
`dependencies` (edges linking a client call site to the route it calls), `unit_edges` (Delphi
`unit A uses unit B` edges between units in the repo), and `state` (last indexed commit).
Every route/client/ui_page entry and dependency edge carries a `github_url` permalink pinned to the
commit it was last scanned at — prefer that link over re-deriving one yourself.
- `vault://knowledge-base` — every repo with generated notes, and each one's note filenames.
- `vault://knowledge-base/{repo}` — that repo's generated per-service markdown notes (routes,
client interfaces, and cross-service "depends on" / "depended on by" tables), keyed by filename.
Prefer these over the raw `code-vault` resource when you want a prose summary of a service
instead of raw JSON.
## Typical workflow
1. Before doing anything else, tell the user the vault's freshness — the last indexed date and
commit ID (via `get_service_status(repo)`, or the `state` key of `vault://code-vault/{repo}`)
— for the repo(s) involved, and the repo's URL (from `GITHUB_URLS` or `GITLAB_URLS` in
`.env`) so the user knows which repo it's tracking. Never try to sync the vault yourself — you cannot.
2. Read `vault://code-vault` to see which repos exist, then call `get_code_map(repo)` for the
index, `get_code_map(repo, service=...)` or `get_code_map(repo, symbol=...)` (use
`search_code_map` to find the name) to locate the relevant code, and open only the files it
lists. Fall back to `get_interfaces`/`get_dependencies` (or the raw `vault://` dumps) only for
data the map doesn't show, e.g. exact `called_paths` or per-entry `github_url` permalinks.
3. To answer "what depends on route X", call `get_dependencies(repo, route_path=X)` rather than
filtering the full edge list yourself.
4. If the index looks stale or inconsistent, tell the user; they re-index it manually.