Observe and Control Agent Context is All You Need.
ctxpress is a local context control plane for agent workflows. It lets you inspect, assemble, and intervene in the context your agents use.
It runs as a local proxy between an agent client and an upstream LLM API. The proxy observes every request, builds a structured view of the context, stores the useful traces locally, and exposes a TUI for inspection, memory retrieval, context assembly, and human-in-the-loop review.
ctxpress is TUI-first, local-first, and designed for developers who want to see and control what actually goes into an agent's prompt.
Agent context is becoming a runtime surface. It decides what the model sees, what it remembers, what it ignores, and what it spends tokens on. But in many agent clients, that context is still a black box.
ctxpress gives you a control plane for that surface:
- Observe context: inspect sessions, turns, raw request structure, token budgets, cache hints, block boundaries, request pipelines, and payload rewrites.
- Assemble context: retrieve memory events, project them into context cards, plan under a token budget, preserve recent turns, and materialize a provider-compatible request.
- Intervene manually: hold the next request, review candidate context, choose full or summarized depth, pin or omit blocks, preview the rewrite, and release the request when it looks right.
ctxpress parses OpenAI Chat Completions-style and Anthropic Messages-style payloads, then records a structured view of each turn:
- session and conversation grouping
- model, streaming mode, request kind, and upstream status
- input and output usage where available
- estimated token breakdown by system, tools, history, and current message
- raw request inspection with optional secret scrubbing
- compact block and atom views for large context payloads
- pipeline traces for summaries, memory, retrieval, and assembly decisions
ctxpress can build a local memory layer from observed agent turns:
- canonical turn tracking
- logical turn segmentation
- memory event extraction
- embeddings with hashing or sentence-transformers providers
- LLM-assisted summaries and facts
- relation scoring between memory events
- retrieval over prior events and turns
- greedy, budget-aware context assembly
- replacement-based materialization for assembled payloads
The goal is not just to retrieve memory. The goal is to decide what content enters the next prompt, at what depth, in what placement, with provenance.
ctxpress can pause selected requests before they are sent upstream:
- manually arm "hold next" from the TUI
- inspect the pending request
- browse retrieved memory events
- add context cards at full, summary, preview, metadata, or stub depth
- omit or pin existing context blocks
- preview token impact and payload changes
- release, cancel, or fall back to the automatic plan
This makes ctxpress useful both as a debugger and as an active context editing surface.
flowchart LR
A["Agent client"] --> B["ctxpress proxy"]
B --> C["Upstream LLM API"]
B --> D["Event bus"]
D --> E["Local store"]
E --> F["Summaries and memory"]
F --> G["Retrieval and assembly"]
G --> B
H["TUI"] --> I["Control REST API"]
I --> E
I --> J["HITL coordinator"]
J --> B
Main packages:
ctxpress.proxy: transparent proxy, provider format detection, streaming forwarding, auto assembly, and HITL forwarding.ctxpress.observe: request analysis, token accounting, event bus, and stage logs.ctxpress.store: local in-memory and SQLite-backed persistence.ctxpress.memory: canonical turn history, segmentation, embeddings, facts, relations, and memory event scheduling.ctxpress.retrieval: memory retrieval and reranking.ctxpress.assembly: projected cards, assembly budgets, greedy planning, and payload materialization.ctxpress.hitl: context cards, manifests, compilation, and review models.ctxpress.tui: the terminal control surface.ctxpress.api: REST endpoints used by the TUI and local automation clients.
ctxpress requires Python 3.11 or newer.
git clone https://github.com/h2h2h/ctxpress.git
cd ctxpress
python -m venv .venv
. .venv/bin/activate
pip install -e .Create a config file:
cp ctxpress.full.yaml ctxpress.yaml
$EDITOR ctxpress.yamlAt minimum, update:
upstream.url: the upstream LLM API base URL ctxpress should forward tolisten.hostandlisten.port: the local address used by your agent client- any API key environment variables used by memory or summary providers
- any local embedding
model_pathvalues if you use sentence-transformers
Start the proxy:
ctxpress proxy -c ctxpress.yamlIn another terminal, start the TUI:
ctxpress tui -c ctxpress.yamlThen point your agent client's provider base URL at the ctxpress listener, for example:
http://127.0.0.1:5757
ctxpress forwards the incoming request path to the configured upstream base URL, so your agent can keep using its usual provider endpoints while ctxpress observes and controls the context in the middle.
You can also run the TUI without a backend:
ctxpress tui --demoThis is enough for transparent local observability:
listen:
host: 127.0.0.1
port: 5757
upstream:
url: https://api.openai.com/v1
timeout_s: 600
observe:
persist:
enabled: true
path: ~/.ctxpress/store.db
scrub_secrets: true
mode:
default: transparentEnable automatic context assembly and HITL once persistence is enabled:
memory:
enabled: true
auto:
enabled: true
memory_retrieval_enabled: true
memory_assembly_max_tokens: 8192
hitl:
enabled: true
manual_only: true
trigger:
manual_hold_next: trueauto, hitl, and memory modes require observe.persist.enabled=true so
ctxpress can recover original payloads and preserve provenance.
# Run proxy and TUI API backend
ctxpress proxy -c ctxpress.yaml
# Run proxy with an ANSI status line
ctxpress proxy -c ctxpress.yaml --status
# Override listen address or upstream URL
ctxpress proxy -c ctxpress.yaml --listen 127.0.0.1:5757
ctxpress proxy -c ctxpress.yaml --upstream https://api.openai.com/v1
# Run the TUI against the configured listener
ctxpress tui -c ctxpress.yaml
# Run the TUI against an explicit backend
ctxpress tui --base-url http://127.0.0.1:5757
# Smoke-test the TUI render path
ctxpress tui --demo --once --size 120x36
# Print version
ctxpress versionThe TUI is organized around three working surfaces:
- Overview: proxy status, active sessions, recent requests, HITL state, and context cache state.
- Inspector: turn-level context inspection, wire view, block view, rewrite view, payload diff, and pipeline trace.
- HITL: pending request review, context card selection, memory event browsing, block depth editing, preview, release, and fallback actions.
Useful keys include:
?: show help/: open the view menuh: toggle hold-nextw,b,r,p: switch inspector viewsSpace: cycle selected block depthf,s,v,m,t: choose full, summary, preview, metadata, or stub deptho: omit selected blockp: pin selected blockP: preview the current draftEnter: release a HITL draft or expand the selected itemu: use the automatic plan
The TUI talks to a local REST API under /_api.
Useful endpoints:
GET /_api/healthGET /_api/sessionsGET /_api/sessions/{session_id}/turnsGET /_api/turns/{turn_id}GET /_api/turns/{turn_id}/messagesGET /_api/turns/{turn_id}/inspectorGET /_api/tui/overviewGET /_api/tui/requestsGET /_api/hitl/hold-nextPOST /_api/hitl/hold-nextGET /_api/hitl/pending
These endpoints are intended for local control surfaces and automation. Do not expose the ctxpress listener to an untrusted network.
ctxpress can store raw prompts, tool outputs, model responses, and derived memory artifacts. Treat the local store as sensitive.
Recommended defaults:
- keep
listen.hoston127.0.0.1 - keep
observe.persist.scrub_secrets=true - store data under a user-owned path such as
~/.ctxpress/store.db - avoid pointing untrusted clients at the proxy
- review config files before committing them
pip install -e ".[dev]"
pytest
python -m compileall -q ctxpress
hatch buildMIT