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.