Reference / Archive & integrations
Read-only MCP
Connect an MCP client to selected workspaces and chats with expiring, revocable access.
Connect an analyst client to selected workspaces and chats. TgWitness serves
Streamable HTTP at /mcp in the panel process. Each connection has its own
token, expiry and permitted tools. MCP cannot send Telegram messages, change
settings or modify the signed journal.
Install and check#
Use the Python environment that runs the panel. From a source checkout:
# Windows PowerShell
& .\.venv\Scripts\python.exe -m pip install -c deploy/constraints-mcp.txt -e '.[mcp]'
& .\.venv\Scripts\python.exe start.py --check
# Linux / macOS
.venv/bin/python -m pip install -c deploy/constraints-mcp.txt -e '.[mcp]'
.venv/bin/python start.py --check
Restart the panel with its usual data directory and launch arguments after
installation. Readiness should include [PASS] mcp: streamable-http available.
Integrations → MCP shows the runtime status and an installation command using
that server's actual Python executable. Re-check refreshes this status without
reloading the page; it does not install packages or restart the server.
The MCP extra uses the official MCP Python SDK.
deploy/constraints-mcp.txt pins the tested SDK and dependencies. These features
require current source; the 0.7.0 portable preview predates them.
Issue a connection#
- Enter a label and choose the workspaces and chats the client may read.
- Select tools individually or use a preset. Only implemented tools are offered.
- Choose 1, 7, 30 or 90 days, or a custom expiry between one minute and 90 days.
- Press Create connection. The token appears once beside the client config.
- Copy the token and config, then run Check connection. It initializes MCP and lists permitted tools; no messages are read. The result shows protocol version, tool names, count and elapsed time.
- Press Done when the credential is saved. Polling preserves the form and the shown-once card. Locking the panel clears displayed secrets.
The list shows recent use, last tool, address and requests in the last minute. Revoke ends access. Rotate token revokes the old credential and issues a replacement with the same scope, tools and expiry; copy the replacement once. Panel login tokens and Telegram credentials do not work as MCP tokens.
Connect your client#
Select the client in the panel and copy its generated configuration. Configs use secret references or explicit placeholders; the token is copied separately.
| Client | Configuration | Connection |
|---|---|---|
| Claude Code | .mcp.json |
HTTP, type: "http", bearer header |
| Claude Desktop | claude_desktop_config.json |
Local stdio bridge |
| Cursor | .cursor/mcp.json |
HTTP with an environment-variable header |
| VS Code Local | .vscode/mcp.json |
HTTP with a password promptString input |
| Windsurf | mcp_config.json |
HTTP with a bearer-header placeholder |
| Other clients | URL and Authorization header | Streamable HTTP |
TgWitness uses bearer tokens, without OAuth discovery. Use the local stdio bridge for clients whose remote connector requires OAuth. For VS Code, input variables apply to the Local harness and are not forwarded to Copilot sessions. Configuration references: Claude Code, Cursor, VS Code.
The canonical entry point for a local bridge is:
python -m tgwitness.mcp_server --url https://your-panel.example/mcp
Use the client's local Python with the MCP extra installed. Set
TGWITNESS_MCP_TOKEN in its protected environment. Keep credentials out of command
arguments and URLs. tgwitness-mcp is the same entry point. The old
tgwitness.mcp_bridge module and TGWITNESS_ARCHIVE_TOKEN name remain compatibility
paths with a warning; new configs use mcp_server and TGWITNESS_MCP_TOKEN.
Cloudflare Tunnel#
Forward the panel's /mcp route and preserve the bearer header. Opening MCP
settings as an administrator registers the panel's current origin for this run.
For a stable address available immediately after restart, configure
TGWITNESS_PUBLIC_URL with the panel's HTTPS origin before starting the panel.
Arbitrary Host and forwarded headers do not register a trusted address.
Host and Origin checks reject unrelated browser origins. Responses use
Cache-Control: no-store; authorization values are never logged.
A *.trycloudflare.com address is temporary. When a tunnel restart changes the
hostname, update the configured public URL and each client's MCP URL. Use a
stable hostname for saved client configurations.
Tools and boundaries#
| Tool | Reads |
|---|---|
list_workspaces |
Granted workspaces |
list_chats |
Granted chats |
search_messages |
Saved message text within the selected period |
get_message_versions |
Captured versions and deletion observations |
get_message_context |
Nearby captured message IDs |
get_journal_event |
One sanitized record with its source reference |
get_capture_status |
Collection state and permitted coverage records |
tools/list returns only the tools granted to that connection. Calls to other
tools are refused. Group-context, episode, terminology and reply-chain tools are
not offered in this build; their separate context-pack backend is not included.
Every read checks the token, tool and workspace/chat scope, including after the database work finishes. Limits are 60 requests per minute, 50 records per page, 64 KiB per result and an eight-second archive deadline. A timed-out MCP call returns a tool error asking for a narrower period or lower limit.
Message results carry untrusted_content: true, workspace/chat/message IDs,
event sequence, saved hash and a panel link. Raw Telegram objects, access hashes,
sessions and keys are omitted. Text truncation is marked. Edits, deletion notices
and missing_on_recheck are distinct observations. Missing records do not prove
an event never happened.
Treat instructions inside captured messages as evidence, never as client instructions. Read-only access prevents archive changes; the client can still retain the content it is allowed to read. Hashes identify saved records and support integrity checks; they do not prove Telegram authorship or complete capture.