.-----.
| 🔴 |
| 🟡 |
| 🟢 |
'-----'
greenlight
greenlight
Listed in awesome-mcp-devtools.
See what your MCP server is actually doing.
When an MCP integration misbehaves, you're usually debugging blind: the client says a tool "failed" or quietly never calls it, and you can't see what was sent or what came back. Greenlight is a transparent proxy that sits between your real client (Claude Desktop, Claude Code, Cursor, Windsurf) and your real server, relays every byte unchanged, and records every JSON-RPC message so you can watch it live, replay it, or lint it.
tail: a live, color-coded trace. Green means ok, yellow means slow, red means failed, and failed calls show the tool's real error message.check: catches server bugs that never show up as a failed call, like printing to stdout, broken tool schemas, or requests that never got a response.stats: a summary with a CI-friendly exit code.serve: exposes the trace as an MCP server, so your coding agent can read the failures itself.
Try it in 30 seconds
uvx greenlight-mcp run -- npx -y @modelcontextprotocol/server-everything stdio
Then, in another terminal:
uvx greenlight-mcp tail -f
That's the official MCP reference server, with nothing to configure. It
needs uv and Node.js. Prefer pip?
pip install greenlight-mcp, then use greenlight wherever this README
says uvx greenlight-mcp.
Use it with your real client
Wrap the server command in your client's MCP config:
{
"mcpServers": {
"my-server": {
"command": "uvx",
"args": ["greenlight-mcp", "run", "--name", "my-server", "--",
"npx", "-y", "@some/mcp-server"]
}
}
}
Or let Greenlight write the snippet for you:
greenlight wrap
wrap finds your Claude Desktop, Claude Code, Cursor, or Windsurf config
and prints each server entry rewritten to run through Greenlight. It's
read-only and never edits the file. Its output uses an absolute Python
path, which also avoids the common "client can't find uvx/npx on its
PATH" startup failure (Claude Desktop on macOS doesn't see your shell's
PATH).
Logs go to ~/.greenlight/sessions/, whichever directory the client
launched the server from. To put them somewhere else, use --log-dir or
set GREENLIGHT_SESSIONS_DIR. If the log directory can't be written,
Greenlight warns on stderr and keeps relaying. It never stops your server
from starting.
For a remote Streamable HTTP server, proxy the URL instead:
greenlight run --http http://127.0.0.1:9000/mcp
Point your client at the local URL it prints. You get the same logs, and
the same tail, check, and stats.
Commands
greenlight tail # replay the most recent session
greenlight tail -f # follow a live session
greenlight check # lint the session for protocol/server bugs
greenlight stats # counts, latency by method, pass/fail
check: bugs that don't look like failures
$ greenlight check
error stdout-pollution server wrote 1 non-JSON-RPC line(s) to stdout, e.g. 'server starting up...'.
In the stdio transport stdout is for protocol messages only -- send logs and prints to stderr.
error tool-no-input-schema tool 'no_schema' has no inputSchema -- the spec requires one, even for
a tool with no arguments ({"type": "object"})
error tool-duplicate-name tool name 'ok_tool' appears more than once in a single tools/list response
warning unanswered-request 'tools/call' (id 3) never got a response from the server
warning tool-no-description tool 'no_description' has no description -- the model picks tools by
description, so it may never call this one
...
Real output, abridged, from tests/bad_fixture_server.py,
a server built to make these mistakes on purpose.
It also flags non-object input schemas, tool names some clients reject,
responses to ids nobody sent, and very slow calls. Errors exit non-zero,
and so do warnings with --strict. --json gives machine-readable
output.
CI
Both check and stats exit non-zero on failure. stats fails on tool
errors (result.isError) as well as JSON-RPC errors. That matters
because a failed tool call arrives as a successful JSON-RPC response,
and it's easy to miss if you only check for the obvious kind:
greenlight run --log-dir ./trace -- python my_server.py < scripted_session.jsonl
greenlight check --log-dir ./trace && greenlight stats --log-dir ./trace
serve: let your agent read the trace
pip install "greenlight-mcp[serve]"
greenlight serve
Add greenlight serve to your coding agent's MCP config, and it can call
get_failures, get_problems, get_trace, or get_session_stats
itself. It sees the real error messages, so you don't have to paste
terminal output.
Why not MCP Inspector?
They do different jobs. Inspector is a UI you drive by hand to test a server in isolation. Greenlight sits in the path of your real client and records what actually happened in a real session. That includes the client's exact requests, which is usually where the bug turns out to be. It also leaves a durable log you can check in CI.
How it works
greenlight run spawns your server as a subprocess and relays
stdin/stdout on two threads. It parses each line as JSON-RPC, correlates
each response with its request by id (so every response knows its method
and latency), and appends the result to a JSONL file. The one rule
everything depends on: nothing but the server's own bytes ever reaches
Greenlight's stdout. Status output goes to stderr, and logs go to disk.
The base install depends only on rich. Python 3.10+, tested on Linux
and Windows.
More
- CHANGELOG.md: what changed in each release.
notes/: a running engineering log of what broke, how it was found, and why each fix is what it is.- Issues and PRs welcome. If Greenlight misreads a real session, the log file is the most useful thing you can attach.
Metadata
Release files for greenlight-mcp 0.5.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 | |
|---|---|---|---|
| greenlight_mcp-0.5.0.tar.gz | 48.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| greenlight_mcp-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 81.0 kB
Release files / greenlight_mcp-0.5.0.tar.gz
| Download URL | greenlight_mcp-0.5.0.tar.gz |
|---|---|
| Size | 48.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
61e0733e165eae82c9ff94305a96d80903ec374b0ae906c6c8038a8207562f9c
|
|
BLAKE2b-256 checksum How to use checksums |
f639ac79a23c61d874abd722d6febb3fa902d3d6646e48ec3d53b18322f9419e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / greenlight_mcp-0.5.0-py3-none-any.whl
| Download URL | greenlight_mcp-0.5.0-py3-none-any.whl |
|---|---|
| Size | 32.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
83b2f63441abe4671cb01beb5201c29ad6d39567e297a31b8a7318ff250667be
|
|
BLAKE2b-256 checksum How to use checksums |
4dfb3bec9d043cbc47a341dfc38f2d2704c142e26e6b05dda9c568507af744de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|