Connect any MCP client — Claude Code, Claude Desktop, Cursor — to the Tomosu governance layer. Your assistant scans the code it just wrote, shows you the fixes, records what you accepted, and returns a Production Reliability Index score with the full report behind it.
The hosted server needs no install. Point your client at https://mcp.tomosu.ai/mcp and it negotiates the rest. Pick the client you actually use:
claude mcp add --transport http tomosu https://mcp.tomosu.ai/mcp --scope user
Then run /mcp inside Claude Code to sign in. --scope user makes the server available in every project on this machine; drop it to add the server to the current project only.
Open Settings → Developer → Edit Config and add the server to claude_desktop_config.json:
{
"mcpServers": {
"tomosu": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.tomosu.ai/mcp"]
}
}
}
Quit and reopen Claude Desktop. The Tomosu tools appear under the tools icon in the composer.
Any client that speaks streamable HTTP can use the same URL. Where the client asks for a command rather than a URL, use the mcp-remote bridge shown above.
Every tool is scoped to your account, so nothing works until you sign in. In Claude Code, run:
/mcp
Pick the Tomosu server and follow the browser prompt. The server issues your token and your client stores it; other clients run the same OAuth flow on first tool call.
/mcp and sign in again.This is the whole loop. Steps 3 to 7 are one conversation with your assistant — you are not calling these tools by hand.
The scan is recorded against your GitHub URL, so the assistant resolves it first. It runs git remote get-url origin, converts an SSH remote (git@github.com:owner/repo.git) to HTTPS, and strips the trailing .git. If there is no git remote, the local directory path is used instead.
Say what you want checked. The assistant calls suggest_code with every file in a single call — the backend batches internally and merges the streamed chunks, so one call covers the whole set and produces one scan_uuid.
suggest_code(
files=[{"filepath": "src/checkout.ts", "filecontent": "..."}],
message="Analyze for reliability issues: crashes, race conditions, "
"missing error handling, unhandled promise rejections",
project_name="storefront",
repo_path="https://github.com/acme/storefront",
context=["reliability", "error", "data_integrity"]
)
Each one comes back with a severity, a category, the line range, and complete before/after code blocks. The scan also returns <scan_uuid> — every step after this needs it.
This is the part that moves your score. Accepting marks the matching category rules as passed; rejecting only records the decision. Call it once per recommendation.
save_recommendation(
scan_uuid="…",
accepted=True,
filename="src/checkout.ts",
before_code="…",
after_code="…",
project_name="storefront",
severity="high"
)
The report is where the score lives. You get a presigned URL, valid one hour, for a PDF carrying the PRI score and every sub-index behind it — Fragility, Governance Compliance, Code Volatility, Deployment Velocity, Drift, Runtime Signals and Escalation — plus category scores and the findings summary.
get_scan_report(
scan_uuid="…",
repo_path="https://github.com/acme/storefront"
)
The URL expires after an hour. Call get_scan_report again with the same scan_uuid for a fresh one — the report itself does not change.
curl -L "{returned_url}" -o tomosu-report.pdf
Scores are only useful as a trend. get_dashboard_analytics returns what the VisionBoard shows: scans over time, dev and prod request counts, accepts, and the category breakdown — for one project or all of them.
get_dashboard_analytics(project_name="storefront")
suggest_code calls to “help” the backend — you would get several unrelated scans and several partial scores instead of one PRI for the codebase.Seven tools, all scoped to the authenticated account.
suggest_codeScan files and return reliability recommendations
| Parameter | Type | Notes | |
|---|---|---|---|
files | list[{filepath, filecontent}] | required | The files to analyse. Send them all in one call — the backend batches internally and merges the chunks into one response. |
message | string | required | What to focus on, e.g. “Analyze for reliability issues: crashes, race conditions, missing error handling”. |
project_name | string | optional | Project or repo name. Used for dashboard tracking. |
repo_path | string | optional | GitHub URL, e.g. https://github.com/owner/repo. Run git remote get-url origin first, normalise SSH to HTTPS, strip .git. |
context | list[string] | optional | 1–3 analysis categories from the table below. |
scan_all | boolean | optional | Defaults to false. |
workflow_uuid | string | optional | Ties the scan to an existing workflow run. |
Returns XML-wrapped markdown: a before/after code block per recommendation, with severity, line numbers and category — plus <scan_uuid>, which every later call needs.
save_recommendationAccept or reject one recommendation
| Parameter | Type | Notes | |
|---|---|---|---|
scan_uuid | string | required | The UUID returned by suggest_code. |
accepted | boolean | required | true accepts, false rejects. |
filename | string | required | Relative path the recommendation applies to. |
before_code | string | required | The original block, verbatim from the Before section. |
after_code | string | required | The recommended replacement, verbatim from the After section. |
project_name | string | required | Same value you passed to suggest_code. |
categories | list[string] | optional | Categories this recommendation belongs to. |
title | string | optional | Short label for the dashboard. |
severity | string | optional | high, medium or low. |
Returns A confirmation string. Accepting marks the matching category rules as passed, which moves the scan’s category scores. Rejecting logs the decision without changing scores.
get_scan_reportGet the PDF report, including the PRI score
| Parameter | Type | Notes | |
|---|---|---|---|
scan_uuid | string | required | The scan to report on. |
repo_path | string | required | GitHub URL of the repo. Appears on the report. |
Returns A presigned S3 URL, valid one hour. The PDF carries project meta, the PRI score and every sub-index (FI, GC, CV, DV, DI, RS, EEI), category scores and a findings summary. Call it again with the same UUID for a fresh URL.
get_dashboard_analyticsRead your VisionBoard dashboard
| Parameter | Type | Notes | |
|---|---|---|---|
project_name | string | optional | Filter to one project. Omit for every project you own. |
Returns The same analytics that power the VisionBoard dashboard: total scans, dev/prod request counts, code accepts, category breakdown, recent observability logs and best practices, plus the raw JSON. Scoped to your account by your token.
get_ticketsRead Help Portal tickets
| Parameter | Type | Notes | |
|---|---|---|---|
ticket_number | string | optional | A single ticket id such as 001. Omit for all of them. |
Returns JSON per ticket: id, ticket_id, title, priority, status, source, file_path, current_code, recommended_fix, reasoning, supportability_impact and telemetry_signal.
get_zendesk_ticketsRead synced Zendesk tickets
| Parameter | Type | Notes | |
|---|---|---|---|
status_filter | string | optional | open, pending, solved, closed. |
priority_filter | string | optional | urgent, high, normal, low. |
Returns Zendesk tickets synced after you connect the account. Connect it first under Settings → Integrations, or this returns nothing.
get_support_agent_dataRead everything on the Support Agent page
No parameters.
Returns One JSON object: Support Agent issues, signal and overall summaries, TomosuScore and extended scores (FI, DI, GC, RS, CV, DV), ticket statistics, accept/reject statistics, server configuration, and a per-issue array with category, severity, component, file, issue, root_cause, suggestion, before_code, after_code, confidence, impact_details and telemetry_signal.
Pass one to three of these in context to steer suggest_code. For the reliability workflow, ["reliability", "error", "data_integrity"] is the useful default.
| Context | Focus |
|---|---|
reliability | Crashes, null refs, race conditions |
error | Error handling, missing try/catch |
performance | Latency, memory, CPU efficiency |
security | Auth, injection, data exposure |
maintainability | Code clarity, complexity |
logs | Logging gaps, unstructured logs |
compliance | Regulatory, data handling |
testing | Test coverage, flaky tests |
api_observability | API tracing, response monitoring |
service_resilience | Retry logic, circuit breakers |
data_integrity | DB consistency, transaction safety |
traffic_management | Rate limiting, load handling |
asynchronous_messaging | Queue reliability, message loss |
infrastructure_efficiency | Resource utilisation |
security_supportability | Auth audit trails |
knowledge_ops | Documentation quality |
configuration_hygiene | Config drift, hardcoded values |
database_performance | Query optimisation, N+1 |
observability | Metrics, tracing, alerting |
dataops_integrity | Pipeline reliability |
knowledgeops_maintainability | Knowledge base quality |
iac_finops | Infrastructure cost and drift |
user_facing_diagnostics | User-visible error messages |
drift_resistance | Config/state drift prevention |
state_volatility | State mutation safety |
architectural_governance | Structural compliance |
support_agent_readiness | Support workflow quality |
The server also ships three prompts. They take code and an optional filepath, and drive suggest_code with the right contexts already chosen.
code_reviewA full review across every quality category, returned as a summary table, before/after diffs per recommendation, and a score card with the top three actions.
security_auditSecurity only: vulnerabilities, hardcoded secrets, PII exposure, injection risk, and authentication or authorisation gaps.
performance_reviewBottlenecks and optimisation: performance, database queries, caching, resource efficiency and infrastructure.
The hosted endpoint suits most teams. Run your own when code must not leave your network.
The server sits alongside the python, node and agent backends and listens on 8080:
docker compose up -d
Then point Claude Desktop at your instance:
{
"mcpServers": {
"tomosu": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8080/sse"]
}
}
}
Requires Python 3.10+ and uv.
cd ai-dev/mcp-server
uv sync
uv run server.py
To reach a local instance from a client that needs a public URL, tunnel port 8080 and set MCP_ISSUER_URL to the generated address — OAuth breaks if the issuer does not match what the client connected to. Then point the client at <your-url>/mcp.
brew install cloudflared
cloudflared tunnel --url http://localhost:8080
| Variable | Default | Purpose |
|---|---|---|
NODE_BACKEND_URL | http://localhost:8001 | Node backend the tools call for scans, tickets and analytics. |
AGENT_BACKEND_URL | http://localhost:8002 | Agent backend for Support Agent data. |
MCP_TRANSPORT | stdio | stdio, sse or streamable-http. |
MCP_HOST | 0.0.0.0 | Bind address for the HTTP transports. |
MCP_PORT | 8080 | Port for the HTTP transports. |
MCP_ENABLE_AUTH | true | Set false only for local development without OAuth. |
MCP_ISSUER_URL | http://localhost:8080 | Public URL of this server. Must match what clients connect to. |
GOOGLE_CLIENT_ID | — | Google OAuth client, shared with the node backend. |
GOOGLE_CLIENT_SECRET | — | Google OAuth secret. |
GOOGLE_CALLBACK_URL | http://localhost:8080/google/callback | OAuth redirect target. |
npx @modelcontextprotocol/inspector uv run server.py
The OAuth flow did not finish, or the token expired. Run /mcp again and sign in.
Presigned URLs last one hour. Call get_scan_report again with the same scan_uuid.
get_zendesk_tickets returns nothingZendesk has to be connected first, under Settings → Integrations in the VisionBoard. Tickets sync at connection time.
It should. suggest_code runs real model calls and allows up to 30 minutes; the client, not the server, is usually what gives up first. Keep sending all files in one call — splitting them is slower and fragments the score.
Applying a fix in your editor changes nothing on its own. Scores move when save_recommendation records the decision with accepted=true.
MCP_ISSUER_URL must exactly match the URL the client connects to, tunnel address included.
The MCP server is included with Tomosu. If you are running AI-assisted development at scale and want the merge gate inside the loop, we are opening a small design partner cohort.
Book a call
