LogRocket MCP Replay
Records the requests your MCP server handles as LogRocket sessions so you can see how users' agents interact with your product: which tools they call and with what arguments, which resources and prompts they fetch, what they got back, and where errors happen.
Works with MCP servers built on the official mcp SDK, both 2.x (MCPServer, low-level Server) and 1.x (FastMCP, low-level Server), and on the standalone fastmcp package (2.x, 3.x, 4.x), over any transport (stdio, SSE, Streamable HTTP).
Installation
uv add logrocket-mcp-replay
# or: pip install logrocket-mcp-replay
Usage
import os
from logrocket_mcp_replay import instrument
server = build_my_mcp_server()
instrument(
server,
api_key=os.environ["LOGROCKET_INGEST_KEY"],
get_user=lambda ctx: {"id": ctx.request.headers["x-user-id"]} if ctx.request else None,
)
instrument records every request the server handles - tool calls, resource reads, prompt gets, listings, and any handler registered afterwards - and uploads batched request events to LogRocket from a background thread. Errors raised by handlers will be surfaced as LogRocket issues.
API key
Create an API key for your app in the LogRocket dashboard and pass it as api_key. The key both authenticates uploads and determines which LogRocket app sessions are recorded to. There is no separate appID to configure.
Short-lived processes
Events are buffered and flushed when the buffer fills, on a timer, and at interpreter exit. On platforms that freeze the process as soon as a response is sent (e.g., AWS Lambda), pass a recorder and flush it before returning:
from logrocket_mcp_replay import InstrumentOptions, RecorderOptions, create_recorder, instrument
recorder = create_recorder(RecorderOptions(api_key=os.environ["LOGROCKET_INGEST_KEY"]))
instrument(server, InstrumentOptions(api_key=os.environ["LOGROCKET_INGEST_KEY"], recorder=recorder))
def handler(event, context):
try:
return run_server(event)
finally:
recorder.shutdown()
Sessions and identity
LogRocket assigns requests to sessions server-side, emulating web visits: one person using one MCP client is one session, ended by 30 minutes of inactivity. Requests are grouped per client app (name and version) by the best available identity signal:
- The identified user, when
get_useris provided. - A SHA-256 hash of the bearer token, for OAuth-protected servers. The token itself is never sent.
- The client IP and user agent, for unauthenticated servers.
- A random per-process ID, for transports with no HTTP request (e.g., stdio), where one server process serves one user.
If your app has its own notion of a session, like a conversation or chat ID, return it from get_session_id, which receives the same context as get_user. Requests that would share a session based on the signals above are then split by session ID, so each conversation gets its own session. A session ID never groups requests that the signals above would separate, so provide get_user too, or a conversation will split if the client's bearer token changes partway through. Sessions still end after 30 minutes of inactivity.
Provide get_user for the best results. It receives the SDK's per-request context (mcp.server.context.ServerRequestContext on mcp 2.x, mcp.shared.context.RequestContext on 1.x). On both, ctx.request is the Starlette Request on HTTP transports (None on stdio), so the user can be resolved from headers, the validated OAuth token (ctx.request.scope["user"].access_token), or whatever your auth middleware attached.
W3C trace context (traceparent/baggage in _meta) is captured on every request and shown with the request's headers in the replay, so requests can be correlated with your tracing backend. It is not used for session grouping.
Options
| Option | Description |
|---|---|
api_key (required) |
LogRocket API key; identifies the app recorded to (see above) |
server_url |
Ingest server origin override |
release |
Your server's release (e.g., version, git SHA) for release tracking |
get_user |
Resolve the LogRocket user from the request context |
get_session_id |
Resolve an app-defined session ID (e.g., a conversation ID) |
capture_params |
Capture request params (default True) |
capture_results |
Capture request results (default True) |
capture_headers |
Capture HTTP request headers (default True) |
redact_headers |
Additional header names to redact |
max_value_length |
Max JSON-serialized length of captured values (default 100000) |
sanitize_event |
Transform or drop (return None) events before upload |
recorder |
Share one recorder across instrument() calls |
max_batch_size |
Flush when the buffer reaches this many events (default 25) |
flush_interval_ms |
Timer-based flush interval (default 5000) |
upload_timeout_ms |
Abort an ingest upload after this long (default 10000) |
on_error |
Callback for upload/serialization errors |
Options can be passed as keyword arguments to instrument() or as an InstrumentOptions instance.
Sanitization
HTTP request headers are captured so they appear alongside each request in the Network view. Credential-bearing headers (Authorization, Cookie, X-Api-Key, and similar) are always replaced with [REDACTED]. This can't be disabled. Use redact_headers to redact additional headers, or capture_headers=False to skip header capture entirely.
Params and results are truncated to max_value_length by default. To handle requests containing sensitive data, use sanitize_event to redact fields or drop events entirely:
def sanitize(event):
if event["method"] == "tools/call" and event.get("target") == "create_payment":
return {**event, "params": None}
return event
instrument(server, api_key=os.environ["LOGROCKET_INGEST_KEY"], sanitize_event=sanitize)
Metadata
Release files for logrocket-mcp-replay 0.2.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 | Provenance | Actions |
|---|---|---|---|---|
| logrocket_mcp_replay-0.2.0.tar.gz | 13.5 kB | Without provenance | Details for logrocket_mcp_replay-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| logrocket_mcp_replay-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for logrocket_mcp_replay-0.2.0-py3-none-any.whl |
Total release size: 27.9 kB
Release files / logrocket_mcp_replay-0.2.0.tar.gz
| Download URL | logrocket_mcp_replay-0.2.0.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
427c2700311c57c494c0ca6cb4b655b5988c29fd458676d65dad1e608a813c48
|
|
BLAKE2b-256 checksum How to use checksums |
91edad5e3eaa0fb1f4e18d184213dce7e9261c2f291755736fc19bf49fe4811b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / logrocket_mcp_replay-0.2.0-py3-none-any.whl
| Download URL | logrocket_mcp_replay-0.2.0-py3-none-any.whl |
|---|---|
| Size | 14.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3cfb6d1ccdf49634ed6f2566634bd3995e35a52c3fcd42b40a87f5358d894352
|
|
BLAKE2b-256 checksum How to use checksums |
500545be5d699771a117f8f8804afc67ebfacfccb23cb4740e19c62722d3ffa0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for logrocket-mcp-replay 0.2.0
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.