← All docs

MCP server in TestO

TestO can expose its ECU/diagnostic functionality over the Model Context Protocol (MCP) so external AI clients (Claude Desktop, Cursor, mcp-cli, custom scripts) can drive TestO using your own AI subscription. Unlike the built-in AI chat, MCP doesn't require an API key — the user's MCP client uses their existing Claude Pro / ChatGPT Plus / local model.

Enabling the server

Edit testo.ini (next to testo.exe) and add:

[mcp]
enabled=true
bindHost=127.0.0.1
httpPort=13721
endpointPath=/mcp
bearerToken=

Restart TestO. On startup you'll see in the log:

[McpHttpTransport] listening at http://127.0.0.1:13721/mcp

Defaults are safe: bound to localhost, no auth required because nothing off-machine can reach it. If you need LAN access set bindHost=0.0.0.0 and put a non-empty bearerToken in (otherwise any host on the network could drive your car).

Quick health probe:

curl http://127.0.0.1:13721/health
# -> ok

Connecting Claude Desktop

Edit %APPDATA%\Claude\claude_desktop_config.json (Windows) or the equivalent on your platform. Add:

{
  "mcpServers": {
    "testo": {
      "transport": {
        "type": "http",
        "url": "http://127.0.0.1:13721/mcp"
      }
    }
  }
}

Restart Claude Desktop. TestO's tools appear under the tools menu (the small hammer icon). Tools prefixed testo_* come from this server.

Connecting Cursor

~/.cursor/mcp.json:

{
  "mcpServers": {
    "testo": {
      "url": "http://127.0.0.1:13721/mcp"
    }
  }
}

Connecting from a script (mcp-cli, custom Python, etc.)

The endpoint accepts standard JSON-RPC 2.0 POSTs. Example with curl:

# 1. initialize handshake
curl -s -X POST http://127.0.0.1:13721/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'

# 2. list tools
curl -s -X POST http://127.0.0.1:13721/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

# 3. call one
curl -s -X POST http://127.0.0.1:13721/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"testo_list_jobs","arguments":{"ecu":"MSD80"}}}'

Available tools

The current toolset:

Tool Safety Description
testo_get_loaded_dll read Inspect the loaded EDIABAS api64.dll (path, version, implementation)
testo_get_ediabas_config read Full EDIABAS config: DLL identity + active Interface, port, ECU path, ini file paths
testo_api_state read EDIABAS API state and last error
testo_list_ecus read List all ECU (.prg) files available; optional name filter
testo_list_jobs read All jobs on an ECU
testo_describe_job read Arguments, result fields, description for one job
testo_search_jobs read Fuzzy search across an ECU's jobs
testo_list_sessions read List logged sessions for an ECU/job
testo_get_session read Time-series samples from a session
testo_run_job vehicle Execute one job (talks to vehicle)
testo_read_fault_codes vehicle Read DTCs
testo_clear_fault_codes dangerous Clear DTCs (modifies ECU state)
testo_run_script write Execute arbitrary JS in TestO's scripting context

Each tool advertises its safety and readOnlyHint / destructiveHint annotations. Well-behaved MCP clients (Claude Desktop) prompt the user before invoking vehicle or dangerous tools.

Example conversation

In Claude Desktop with the TestO MCP server connected:

User: My MSD80 is throwing a P0420. Pull recent O2 sensor data and tell me what's wrong.

Claude: [calls testo_search_jobs ecu=MSD80 keyword=lambda] [calls testo_run_job ecu=MSD80 job=STATUS_MESSWERTBLOCK_LESEN params={MESSWERTBLOCK:"LAMBDA"}] [calls testo_get_session ecu=MSD80 job=LAMBDA_VOR_KAT limit=200]

Looking at the last 200 samples, your pre-cat lambda is swinging normally around 1.0 (0.95–1.05) but the post-cat sensor is also swinging — it should be stable around 0.8–0.9 if the cat is healthy. Combined with the P0420, this points to a degraded catalyst rather than an O2-sensor issue.

The model used your Claude Pro subscription; TestO billed nothing.

Security notes