trafficmorph-gif

TrafficMorph MCP Server

Community trafficmorph-gif
Updated

MCP SDK

TrafficMorph MCP Server

████████╗██████╗  █████╗ ███████╗███████╗██╗ ██████╗
╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██╔════╝██║██╔════╝
   ██║   ██████╔╝███████║█████╗  █████╗  ██║██║
   ██║   ██╔══██╗██╔══██║██╔══╝  ██╔══╝  ██║██║
   ██║   ██║  ██║██║  ██║██║     ██║     ██║╚██████╗
   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝     ╚═╝ ╚═════╝
        ███╗   ███╗ ██████╗ ██████╗ ██████╗ ██╗  ██╗
        ████╗ ████║██╔═══██╗██╔══██╗██╔══██╗██║  ██║
        ██╔████╔██║██║   ██║██████╔╝██████╔╝███████║
        ██║╚██╔╝██║██║   ██║██╔══██╗██╔═══╝ ██╔══██║
        ██║ ╚═╝ ██║╚██████╔╝██║  ██║██║     ██║  ██║
        ╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝  ╚═╝

PyPIPython versionsLicense

Drive TrafficMorph from Claude Desktop, Claude Code, Cursor, or anyother host that speaks the Model Context Protocol.

The flagship use case is CI-failure triage:

"My TrafficMorph CI step just failed on run 1234 — whatregressed vs the baseline?"

→ Claude calls the right tools, fetches the relevant runs, computesthe per-metric delta, and produces a human-readable triage reportin seconds.

Current release: 1.2.0 — 25 tools + 4 prompts + 5 resources(34 catalog entries total). See CHANGELOG.md forthe per-release history and STABILITY.md for what1.x commits to keeping stable. See MCP-USAGE.md forworked example conversations.

Quick start

Four steps from zero to "Claude is driving my TrafficMorphaccount":

1. Get an API key

Open the TrafficMorph app → Settings → API Keys → clickGenerate. Copy the tm_… value.

2. Install (or skip — uvx runs without install)

# Permanent install:
pip install tm-mcp

# OR — no install at all. The MCP host config below uses `uvx`,
# which downloads + caches the package on first run. Confirm
# uvx itself is on your PATH:
uvx --version

Note: tm-mcp is a long-running MCP server, not a CLI witha --help flag. Invoking it directly without env vars exits 2with a configuration error. The host (Claude Code / Desktop)subprocesses it and pipes JSON-RPC over stdio — you don't runit yourself unless you're debugging.

3. Register with your MCP host

Both Claude Code and Claude Desktop use the same env-var protocol:TM_API_KEY for the API key, TM_BASE_URL for the base URL. Theserver reads both at startup and fails fast with a clean"couldn't start" message if either is missing — your host's logshows that instead of opaque "tool call failed" errors later.

In all snippets below, replace two placeholders with your own values:

  • TM_API_KEY=tm_xxxxxxxxxxxxxxxx → the API key from Step 1.
  • TM_BASE_URL=https://YOUR-TRAFFICMORPH-HOST → the URL of yourTrafficMorph server. Common values:
    • Local dev: http://localhost:8080
    • Self-hosted prod: https://trafficmorph.your-company.com(or whatever URL your install lives at)
    • Cloud SaaS: the URL shown in your TrafficMorph app'sbrowser address bar
    • Do not copy the literal YOUR-TRAFFICMORPH-HOST placeholder— it won't resolve and every tool call will fail.

Claude Code — one command:

claude mcp add trafficmorph \
  -e TM_API_KEY=tm_xxxxxxxxxxxxxxxx \
  -e TM_BASE_URL=https://YOUR-TRAFFICMORPH-HOST \
  -- uvx tm-mcp

Project-scope alternative — drop this at the repo root:

// .mcp.json
{
  "mcpServers": {
    "trafficmorph": {
      "command": "uvx",
      "args": ["tm-mcp"],
      "env": {
        "TM_API_KEY": "tm_xxxxxxxxxxxxxxxx",
        "TM_BASE_URL": "https://YOUR-TRAFFICMORPH-HOST"
      }
    }
  }
}

Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or the equivalent on your OS, then restart Claude Desktop:

{
  "mcpServers": {
    "trafficmorph": {
      "command": "uvx",
      "args": ["tm-mcp"],
      "env": {
        "TM_API_KEY": "tm_xxxxxxxxxxxxxxxx",
        "TM_BASE_URL": "https://YOUR-TRAFFICMORPH-HOST"
      }
    }
  }
}

4. Verify

In Claude Code:

> /mcp

You should see trafficmorph listed with 25 tools, 4 prompts,and 5 resources. If you see red / error, check:

claude mcp list                # is `trafficmorph` registered?
claude mcp get trafficmorph    # what env vars + command?

The most common gotcha: forgetting TM_BASE_URL. The serverrefuses to start without it and surfaces a clear "$TM_BASE_URLis not set" error in your MCP host's log. Set it in the hostconfig (see step 3).

What you can do

Conversational examples — try any of these once the server is wired up:

  • "List my TrafficMorph profiles."
  • "Show me the last 5 runs for profile 42."
  • "Start a run on profile 42 and wait for the verdict."
  • "Create a profile 'smoke-test' hitting https://api.example.com/health at 50 RPS for 60s."
  • "What domains am I cleared to load-test against?"
  • "Add api.example.com as a new domain and walk me through verification."
  • "Compare run 1234 against run 1198."

Or invoke a slash-command prompt for a guided workflow:

  • /tm_triage 42 — find the most recent failed run for profile 42, diff against the latest PASS baseline, narrate the regression.
  • /tm_setup_loadtest https://api.example.com 100 60 — handle domain verification + profile creation + optional immediate run.
  • /tm_compare_baseline 42 — quick regression check vs the last green.
  • /tm_import_capture_guided ~/.trafficmorph/captures/my.jsonl — analyse → preview → import workflow.

Or @-mention a resource to pull pre-baked context into the chat:

  • @tm://profiles — your full profile list as session-start context.
  • @tm://history/recent — the last 20 runs across all profiles.
  • @tm://domains — verified domain list.
  • @tm://profiles/42 or @tm://history/1234 — one specific entity by id.

See MCP-USAGE.md for end-to-end worked conversationsincluding failure triage, new-test setup, and capture-driven profileimport.

Full catalog

Tools (25) — AI-invoked actions

Tool Action
Read
tm_list_profiles List all profiles owned by the authenticated user
tm_get_profile Full config + run status for one profile
tm_list_history Paginated past runs with filters (auto_verdict=FAIL is the CI-triage filter)
tm_get_run Full metric set + verdict for one run
tm_list_domains All registered domains + verification status
tm_compare_runs Side-by-side metric diff of two runs (synthetic)
tm_analyse_capture Per-endpoint analysis of a JSONL capture file
Run control
tm_start_run Start a run; with wait=True + fail_on_verdict=["FAIL","WARN"] mirrors tm runs start --wait in the CLI
tm_stop_run Stop the in-flight run for a profile (idempotent)
tm_pause_run Pause without losing position (idempotent)
tm_resume_run Resume a paused run from where it left off
Profile lifecycle + capture import
tm_create_profile Create a new profile (fails fast on name collision to prevent silent upsert wipe)
tm_update_profile Partial update by id (read-modify-write internally — only pass the fields you want to change)
tm_delete_profile Remove a profile
tm_import_capture Persist analysed-capture groups as profiles
Domain management
tm_add_domain Register a domain for verification (idempotent)
tm_verify_domain_dns Check the TXT challenge record
tm_verify_domain_http Check the /.well-known/trafficmorph-verify.txt file
tm_delete_domain Remove a domain
Variables-set lifecycle
tm_list_variables_sets List all variables sets owned by the user
tm_get_variables_set Single set's metadata (id, name, mode, columns, row count)
tm_create_variables_set Upload a CSV-style set (inline csv_content string, mode is one of "ROW" / "COLUMN" / "SEQUENTIAL")
tm_rename_variables_set Rename without touching content (idempotent)
tm_change_variables_set_mode Switch between ROW / COLUMN / SEQUENTIAL without re-uploading
tm_delete_variables_set Remove a set; 400s if still attached to any profile (detach via tm_update_profile first)

Prompts (4) — user-invoked slash commands

Slash command Workflow
/tm_triage <profile_id> Find the most recent FAIL → diff vs latest PASS → narrate the regression
/tm_setup_loadtest <url> <rps> <duration_seconds> Domain verification (if needed) + profile creation + optional run
/tm_compare_baseline <profile_id> Quick regression check: latest run vs latest PASS
/tm_import_capture_guided <path> Analyse → present groups → user picks → import

Prompts return a templated user message that steers the AI througha specific tool sequence. They're how you kick off a known workflowwithout typing the full natural-language description every time.

Resources (5) — @-mention URIs

URI What it returns
tm://profiles All your profiles, JSON
tm://profiles/{id} One profile's full config
tm://history/recent Last 20 runs across all profiles
tm://history/{run_id} One run's full metrics
tm://domains All registered domains + verification status

Resources are read-only data the host pulls into context — usuallyat session start via @-mention. They wrap the corresponding readtools 1:1; the difference is who decides when to read (AI fortools, host for resources).

Configuration

Env var Required Notes
TM_API_KEY yes Full tm_… value provisioned from in-app Settings → API keys
TM_BASE_URL yes URL of your TrafficMorph install (http://localhost:8080 for local dev, your hosted URL otherwise). No built-in default — the server refuses to start without it
TM_MCP_CAPTURE_ROOT no Defaults to ~/.trafficmorph/captures/. Allow-listed root for tm_analyse_capture + tm_import_capture file paths

Capture-file path validation

tm_analyse_capture and tm_import_capture accept a server-sidefile path. The MCP server validates each path before passing itthrough:

Rule Why
Must resolve inside $TM_MCP_CAPTURE_ROOT (default ~/.trafficmorph/captures/) Prevents AI invocation from probing ~/.ssh/, ~/.aws/, ~/Documents/…
Symlinks resolving outside the root are rejected Classic symlink-escape defense
.. segments rejected at parse time Path-traversal defense
Only .jsonl extension The capture parser reads plain JSONL (no gzip wrapping)

Override the root via TM_MCP_CAPTURE_ROOT in your MCP host'sserver config:

"env": {
  "TM_API_KEY": "...",
  "TM_BASE_URL": "...",
  "TM_MCP_CAPTURE_ROOT": "/path/to/your/captures"
}

Troubleshooting

Server fails to start with $TM_API_KEY is not set or$TM_BASE_URL is not set. One of the required env vars wasn'tdelivered to the subprocess by your MCP host. The error names themissing variable; add it to the env block in your host config(see Step 3).

Server starts, but every tool call hits a network / DNS error.TM_BASE_URL is set to something that doesn't resolve — typicallya placeholder like https://YOUR-TRAFFICMORPH-HOST that wasn'tedited, a typo in the hostname, or an internal URL not reachablefrom where the MCP host runs. Read the URL back fromclaude mcp get trafficmorph and confirm it resolves withcurl -I "$TM_BASE_URL/api/v1/profiles".

Tools work, but specific ones return 404. Your TrafficMorphserver is running an older build that doesn't expose thoseendpoints yet. Upgrade the server.

PLAN_UPGRADE_REQUIRED on every call. Your TrafficMorphaccount doesn't have API access enabled. Check your accountsettings, or point the MCP server at a deployment where youraccount has API access.

tm_create_profile refuses with "A profile named X alreadyexists". The server's POST endpoint is upsert-by-name and wouldsilently replace the existing profile (including scripts /callbacks / alerts the MCP tool surface doesn't expose). Usetm_update_profile(profile_id=<id from error>) instead, or picka unique name.

tm_update_profile refuses to rename. A rename would collidewith another profile under your account. The error names bothids; either pick a unique new name OR call tm_update_profileagainst the OTHER profile if you actually meant to edit that one.

Domain verify returns 400 immediately. That's the fail-fastcontract — verification is NOT polling-style. The 400 messageincludes the expected TXT record / URL + token; read it back tothe user, wait for them to install the record / file, then retry.

Versioning

Source Notes
MCP server release tm-mcp on PyPI Pin via pip install 'tm-mcp==X.Y.Z'. See CHANGELOG.md.
API version tm_mcp.__version__ matches the PyPI version Use to identify what's installed in support tickets

The MCP server is a thin layer over the trafficmorph Python SDK.The dependency pin in pyproject.toml constrains the SDK rangethis release is tested against; updating the SDK ships as a newtm-mcp release.

See also

  • MCP-USAGE.md — comprehensive user guide with worked example conversations
  • CHANGELOG.md — per-release history
  • STABILITY.md — v1.0 stability promise (what tools / prompts / resources stay stable across 1.x)
  • examples/ — full conversation transcripts (triage, setup, capture import)
  • TrafficMorph Python SDK — the HTTP layer this MCP server uses

MCP Server · Populars

MCP Server · New

    MarcellM01

    TinySearch

    Shrink the web for your local LLMs!

    Community MarcellM01
    DomDemetz

    Claude Soul

    Self-improving learning engine for Claude Code. Not memory. Growth.

    Community DomDemetz
    chinawsb

    Daofy for Delphi

    Daofy for Delphi — MCP Server that compiles Delphi projects and queries knowledge base for AI assistants.

    Community chinawsb
    Patdolitse

    Engram

    AI identity layer for Claude Code, Codex and Cursor — stores who you are, not just what you did. Local-first, MCP-compatible.

    Community Patdolitse
    heymrun

    Heym

    Self-hosted AI workflow automation platform with visual canvas, agents, RAG, HITL, MCP, and observability in one runtime.

    Community heymrun