Keep the sensor.
Own the records.
A small, inspectable WSGI middleware package. Run the reference server or wrap your application, collect locally, and inspect aggregate observations.
Install & run.
The OnionLens sensor retains the onion-observatory package identifier and onion_observatory import for compatibility. The installed cepatreaza command and original CLI remain unchanged.
Requires Python 3.10 or newer. Download the wheel above, review its source and compare its hash with SHA256SUMS.txt. The package uses only the Python standard library at runtime. Run these commands from the folder containing the downloaded wheel.
python3 -m venv .venv . .venv/bin/activate python -m pip install onion_observatory-0.1.1-py3-none-any.whl cepatreaza serve --channel clearnet --db observatory.sqlite3 # In a second terminal, from the same folder . .venv/bin/activate cepatreaza summary --db observatory.sqlite3
The reference server binds to 127.0.0.1:8787. It is for local evaluation. Put a production WSGI server in front of the middleware for an operational deployment.
Wrap a WSGI application.
from onion_observatory import Sensor
# Your existing WSGI application
application = Sensor(
application,
db="observatory.sqlite3",
channel="onion",
)Choose the channel from trusted deployment configuration. Use a dedicated loopback listener for onion ingress. An incoming Host or forwarding header is never reliable proof of transport.
/_oo/probe issues a benign natural-language canary. /_oo/demo issues an explicitly labelled demo. Callback tokens keep their original class. Existing response bodies and streaming behaviour pass through unchanged.
Connect a local Tor service.
With the reference server on port 8787, configure Tor to forward your onion service to that loopback listener. Keep the service key private and stable. Tor installation and service management are separate operator steps.
# torrc HiddenServiceDir /var/lib/tor/observatory/ HiddenServicePort 80 127.0.0.1:8787
Run the server with --channel onion only when that listener is exclusively reached through Tor. Follow the Tor Project setup guide for platform-specific permissions and service configuration.
Three real, read-only tools.
This hosted service exposes a stateless MCP Streamable HTTP endpoint at /mcp, using JSON responses. Use /demo/mcp for labelled experiments. Supports protocol versions 2025-03-26 and 2025-06-18; no persistent sessions or SSE stream are required.
| Tool | Result |
|---|---|
validate_onion_address | v3 syntax, version and checksum |
list_resources | Primary-source Tor resource index |
retrieval_fixture | Known UTF-8 specimen |
Send initialization and then tool requests with both accepted response types. Hosted MCP tools are separate from the downloadable middleware.
# 1. Initialize the client.
curl -sS https://onionlens.org/demo/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
"protocolVersion":"2025-06-18","capabilities":{},
"clientInfo":{"name":"my-test","version":"1.0"}}}'
# 2. Discover the available tools.
curl -sS https://onionlens.org/demo/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
--data '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
# 3. Retrieve the known specimen.
curl -sS https://onionlens.org/demo/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
--data '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
"name":"retrieval_fixture","arguments":{}}}'Collection boundaries.
The downloadable middleware stores bounded request paths, methods, user agents, timestamps and token correlations in local SQLite. It never sends telemetry and does not record IP addresses, raw queries, request bodies, cookies or authorization headers. Operators control retention and must protect the database.
The hosted research deployment uses a private PostgreSQL store and additional canary placements. Its clearnet ingress records an edge-observed IP; onion visitor IPs are unavailable. Full records are never public. Read the hosted collection policy and research limits.
The source package includes the licence, full README and tests. Nine hosted canary placements cover comments, hidden text, alternative text, machine-readable documents, API responses and restricted pages.