Skip to main content

Undercover Agent

A drop-in OpenAI-compatible chat completions server that sits between a coding harness (GitHub Copilot, OpenCode, or anything that speaks the OpenAI API) and a real model — and logs everything that flows through it.

Point your harness's "OpenAI base URL" at Undercover Agent, and every request and response is recorded into clean, browsable, per-conversation logs.

What it's for

When you're building or debugging an agent, the most useful thing you can have is the exact traffic the harness sends to the model: the full message history, system prompts, declared tools, sampling params, and the responses. Undercover Agent captures all of it without requiring any changes to the harness beyond a base-URL swap.

Two modes

  • Dumb mode (default) — never contacts a real model. It returns well-formed, intentionally boring canned responses (correct choices, finish_reason, a plausible faked usage block) so the harness keeps working while you inspect what it's sending.
  • MITM mode — forwards each request to a real upstream LLM via the official OpenAI SDK, relays the answer back unchanged, and logs everything in between.

Both modes stream when the request asks for it (stream: true), passing SSE through transparently.

Sessions

The OpenAI chat API is stateless — every request resends the whole conversation and carries no session id. Undercover Agent reconstructs sessions by prefix matching: if a stored conversation is a prefix of an incoming request's messages, the request is treated as a continuation of that session (longest match wins); otherwise a new session is born.

Each session gets a timestamped id like 20260630T101345Z-a1b2c3d4, so logs sort chronologically and any session can be opened directly by its id.

Install & run

Requires Python 3.9+.

pip install undercover-agent

Or, from a checkout of this repository:

pip install -r requirements.txt

Dumb mode (default)

python -m undercover_agent

Then point your harness at http://localhost:8000/v1.

MITM mode

python -m undercover_agent --mode mitm \
  --base-url https://api.openai.com/v1 \
  --api-key sk-...

The harness's own Authorization header is logged but never forwarded — Undercover Agent authenticates upstream with the --api-key you pass here.

CLI flags

Flag Default Description
--mode {dumb,mitm} dumb Logging-only or forward-upstream.
--host 0.0.0.0 Bind address.
--port 8000 Bind port.
--model undercover-agent Model id advertised to the harness.
--logs-dir logs Where per-session JSON logs are written.
--base-url — Upstream base URL (MITM only).
--api-key — Upstream credential (MITM only).

HTTP API

Undercover Agent implements the slice of the OpenAI REST API that harnesses actually use:

  • POST /v1/chat/completions — the main endpoint (streaming and non-streaming).
  • GET /v1/models — returns the advertised model id(s).
  • GET /health — liveness check.

Viewing the logs

Logs are written as one JSON file per session under logs/<session-id>.json. That JSON is the machine-readable report. There's also a human-readable HTML view, available two ways:

Live, while the server runs

  • GET / — index of all sessions, newest first (timestamp, mode, model, turn count, token usage).
  • GET /sessions/<session-id> — the full conversation rendered like a normal chat UI.
  • GET /sessions/<session-id>.json — the raw JSON log.

Static export

python -m undercover_agent report

Writes reports/index.html plus one reports/<session-id>.html per session. Open reports/index.html and click through, or open a session file directly.

How it's built

  • Flask for the HTTP server (streaming via generator responses).
  • openai — the official SDK, used to forward requests upstream in MITM mode.

Entrypoint is python -m undercover_agent.

Metadata

Release files for undercover-agent 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for undercover-agent 0.1.0
File Size Uploaded
undercover_agent-0.1.0.tar.gz 22.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for undercover-agent 0.1.0
File Interpreter ABI Platform
undercover_agent-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.8 kB

Release files / undercover_agent-0.1.0.tar.gz

Download URL undercover_agent-0.1.0.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
2e115c6a9bb4d375c4c5f3820b78b4fb7ce464030c8ccf02c4db398d9f059ee4
BLAKE2b-256 checksum
How to use checksums
afa88446a39b4ed7400f6122378f9f3d496d2d3fb7cc6619641fec73df7664fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / undercover_agent-0.1.0-py3-none-any.whl

Download URL undercover_agent-0.1.0-py3-none-any.whl
Size 24.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e0380bbdbafac6b21ac17124675835b5aeff8669bf2194c3588782538ec29802
BLAKE2b-256 checksum
How to use checksums
4e4346662010e6a9bc2123fb0cd9928bcca3860900aae06e1e9ac202999a9d76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page