.-----.
| 🔴 |
| 🟡 |
| 🟢 |
'-----'
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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| greenlight_mcp-0.5.1.tar.gz | 50.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| greenlight_mcp-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.7 kB
Release files / greenlight_mcp-0.5.1.tar.gz
| Download URL | greenlight_mcp-0.5.1.tar.gz |
|---|---|
| Size | 50.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cdea8c1f4768ae4e63014acf515d33659f80d8d12c201495b526db683e4fa95d
|
|
BLAKE2b-256 checksum How to use checksums |
6538b07820f7c804ccc11eed6a4b3415f9047ab608bf6a6a8423a0473bdaa26d
|
| 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.1-py3-none-any.whl
| Download URL | greenlight_mcp-0.5.1-py3-none-any.whl |
|---|---|
| Size | 32.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
46dcb76e6c40f3eefbd3c3e658da8b1863d65f2d90091b1fb1c141b5eba2204d
|
|
BLAKE2b-256 checksum How to use checksums |
915cdbc530890c9f75c2aefc48233ab9da5fa2420bb4bb50bd6818827ba143c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for greenlight-mcp 0.5.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.