Find the latency in your AI agent, before your users do.
Relay is an open-source MCP server + CLI that audits AI agent and voice-agent codebases for latency bottlenecks. It reads your real source with an AST engine, ranks issues by impact, runs a verification pass to drop false positives, and can apply fixes directly from Claude Code.
No account. No API key. No backend. It runs entirely on your machine.
Quickstart · MCP tools · CLI · What it detects · Contributing
Why Relay
Agent latency is rarely one slow model call. It is a streaming response that was never
streamed, three awaits that should have been one asyncio.gather, an HTTP client
rebuilt on every request, a requests.post sitting inside an async def. These are
structural, they are invisible in a profiler flame graph averaged over a request, and
they are obvious in the AST.
Relay finds them, then argues with itself about each one so you don't get a wall of false positives.
Quickstart
In Claude Code (MCP)
claude mcp add relay -- uvx relay-mcp
Or add it to your MCP config (~/.claude/claude_code_config.json) by hand:
{
"mcpServers": {
"relay": {
"command": "uvx",
"args": ["relay-mcp"]
}
}
}
Then, in Claude Code, just say:
Audit this codebase for latency issues
That's it - there is no key to configure.
As a CLI
pip install relay-mcp # or: uv tool install relay-mcp
relay scan . # structural pass - candidate latency patterns
relay verify . # semantic pass - only the confirmed gaps
relay report . # write relay-report.json
Requires Python 3.11+.
Features
- AST-based detection. Parses Python with the real grammar, not regexes, so it
understands
async/await, call targets, keyword arguments, and**kwargsforwarding. - Six latency detectors. Streaming gaps, sequential tool calls, cache misses, blocking I/O in async code, per-request client construction, and prefetch opportunities - see What it detects.
- Verification pass. Every candidate is re-read in context and either confirmed as a real gap or dismissed as a false positive, each with a one-line reason.
- Impact ranking. Findings are scored and sorted so the highest-impact fixes surface first.
- Apply fixes from Claude Code.
apply_fixrewrites the flagged site (dry-run by default) so you review before anything is written. - MCP and CLI share one engine. Agent output and terminal output never diverge.
- CI gate.
relay verify --fail-on highexits non-zero when a confirmed high-impact gap remains, so it can fail a pipeline. - Dashboard reports. Each audit writes a
relay-report.jsonyou can drop into the Relay dashboard for a visual view. - Essentially no dependencies. Just the
mcppackage - no network calls, no telemetry, nothing leaves your machine. - Persistent state. The last audit is cached at
~/.relay/last-audit.json, soget_findings,verify_audit, andapply_fixkeep working across MCP restarts.
MCP tools
| Tool | Description |
|---|---|
audit_codebase(directory, write_report=true) |
Reads Python files in a directory, returns ranked findings (each with a verification verdict) and writes relay-report.json. |
get_findings(severity?, finding_type?, status?) |
Filters findings from the last audit. |
verify_audit() |
Shows which findings the semantic pass confirmed vs dismissed, with reasons. |
apply_fix(finding_rank, file_path?, dry_run=true) |
Applies a fix. Dry run by default; file path defaults to the finding's file. |
The last audit is cached at ~/.relay/last-audit.json, so the read-only tools keep
working after an MCP server restart.
CLI
relay scan <dir> # structural pass - flag candidate latency patterns
relay verify <dir> # semantic pass - keep only confirmed gaps
relay report <dir> [-o f] # write relay-report.json for the dashboard
relay mcp # run the MCP server (same as relay-mcp)
| Flag | Applies to | Meaning |
|---|---|---|
--json |
scan, verify |
Print the full report as JSON (for CI, jq). |
--fail-on {none,high,any} |
verify |
Exit non-zero when confirmed gaps remain. Default none. |
-o, --output |
report |
Output path. Default <dir>/relay-report.json. |
Use in CI
- run: pip install relay-mcp
- run: relay verify . --fail-on high
--fail-on high fails the job only when a confirmed high-impact gap remains, so a
noisy structural match will not break your build.
What it detects
| Detector | What it flags |
|---|---|
| SyncOutput | LLM calls missing streaming (stream=True), including calls that forward **kwargs. |
| SequentialTools | Consecutive data-independent awaits that should run under asyncio.gather(). |
| CacheMiss | The same fully-static LLM call repeated at multiple call sites with no caching. |
| BlockingIO | Sync requests / DB calls, plus time.sleep and blocking subprocess calls inside async functions. |
| ColdStart | API clients (OpenAI, httpx.Client, aiohttp.ClientSession, …) built per request instead of at startup. |
| Prefetch | Predictable tool-call pairs that could be started speculatively. |
The verification pass
Every finding is re-read in context and either confirmed as a real latency gap or
dismissed as a false positive, with a one-line reason either way - for example
"one branch (lookup) is in-memory - nothing to parallelize" or
"structured/JSON output - not streamable". The summary counts
(flagged, confirmed, dismissed, confirmed_high_impact) drive both the CLI output
and the --fail-on CI gate.
This is the difference between a linter you mute after a week and one you keep in CI.
The dashboard
Relay itself is fully local. If you want a visual view of a report, the
Relay dashboard lets you drag in any
relay-report.json and browse findings, severity breakdown, and time-lost aggregates.
The report never leaves your browser - it is parsed client-side.
Configuration
None. Relay needs no environment variables, no config file, and no API key. It reads your source, writes a report, and does nothing else.
Repository structure
relay-mcp/
├── mcp_server/ # MCP server + CLI (ships as relay-mcp on PyPI)
│ ├── server.py # entry point, exposes the MCP tools
│ ├── cli.py # `relay` command (scan / verify / report / mcp)
│ └── engine/ # audit engine (detectors, scorer, verify, code_parser)
├── tests/ # end-to-end engine tests
├── assets/ # logo and screenshots
├── run.sh / run.ps1 # dev runners (install / register / test / serve)
└── pyproject.toml # package config for uvx / pip install
Development
pip install -e ".[dev]" # install relay + relay-mcp in editable mode
pytest # run the test suite
ruff check . # lint
relay scan . # dogfood the engine on itself
See RUNNING.md for the full dev workflow and CONTRIBUTING.md for how to add a detector or open a PR.
Project
- Contributing - CONTRIBUTING.md
- Code of conduct - CODE_OF_CONDUCT.md
- Security policy - SECURITY.md
- Changelog - CHANGELOG.md
Relay is a product of the Arclat studio. Learn more at relay.arclat.com.
License
Metadata
Release files for relay-arclat 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| relay_arclat-0.3.0.tar.gz | 28.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| relay_arclat-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 60.4 kB
Release files / relay_arclat-0.3.0.tar.gz
| Download URL | relay_arclat-0.3.0.tar.gz |
|---|---|
| Size | 28.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d12641a8c16148869942666384d248593a7cdb4e5abb53715c7d9dfc738e5fe0
|
|
BLAKE2b-256 checksum How to use checksums |
52043354a205be331be547988a8289309ac5c215d0b5c87666efac6fbd4f1144
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency logRelease files / relay_arclat-0.3.0-py3-none-any.whl
| Download URL | relay_arclat-0.3.0-py3-none-any.whl |
|---|---|
| Size | 31.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6e711b59744b227f60f309d509756431473b83270470944d411121b317b9bbad
|
|
BLAKE2b-256 checksum How to use checksums |
aa0b872682fb7b66425b0cf1ffc39dac79f33d749cc454d9c205e0713e9356a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency log