Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Copy this into your coding agent:

```text
Set up t3poll from https://github.com/eimexdev/t3poll.
Use an existing checkout if available; otherwise clone into ~/code/t3poll.
Use an existing checkout if available; otherwise choose an appropriate local installation folder.
Read docs/agent-setup.md in that checkout and follow it.
Find my local T3 connection settings where possible and configure MCP.
Configure MCP to launch t3poll; it discovers local T3 and manages its credential.
Preserve my running T3 server and ongoing conversations.
Verify setup without sending a message to a thread or starting a watch.
```
Expand All @@ -21,15 +21,15 @@ The [agent setup guide](docs/agent-setup.md) covers discovery, credentials, conf

## Manual setup

You need Linux, Node.js 24.10+, GitHub CLI signed in, and a compatible T3 server. Setup consists of building this checkout, supplying a T3 address and credential file, and adding one MCP configuration entry. Follow the [manual steps](docs/setup.md).
You need Linux, Node.js 24.10+, GitHub CLI signed in, and a compatible T3 server. Build this checkout and add one MCP configuration entry. The first thread-listing or watch call finds local T3 and creates its credential. Follow the [manual steps](docs/setup.md).

The address identifies your T3 instance; the credential lets t3poll read thread state and deliver notifications. These are one-time settings. Local addresses can often be discovered during setup, but automatic discovery is not built into t3poll yet. A destination thread is selected when registering each watch.
No URL or token settings are needed for a standard local installation. If multiple instances are found, select one with `T3POLL_BASE_DIR`. Choose the destination thread when registering each watch.

## Daily use

Ask your agent to watch a PR, list watches, or stop one. It can find destination IDs with `list { "threads": true }`.

The CLI provides the same operations. From the checkout, with your connection variables set:
The CLI provides the same operations. From the checkout, with T3 running:

```sh
node dist/cli.js watch https://github.com/owner/repo/pull/123 --thread THREAD_ID
Expand All @@ -55,7 +55,7 @@ Reconnect the t3poll MCP server or use a new provider session to load the new co

If you need to update sooner, record your watch destinations, stop those watches, wait for the worker to exit, then update and register them again. Re-registering starts a fresh baseline, so changes during the gap will not generate notifications. State lives outside the checkout in `~/.local/share/t3poll` by default.

Credentials have their own expiration. The manual example issues a 30-day token; replacing its file renews access without restarting active watches.
Automatically created credentials last 30 days. t3poll replaces them on use during their last day or after expiration, including from the background worker. Explicitly supplied token files remain your responsibility.

## Development

Expand Down
45 changes: 8 additions & 37 deletions docs/agent-setup.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,14 @@
# Agent setup

Use this guide when asked to install or configure t3poll. For an existing installation update, follow [README updates](../README.md#updates).
Use this guide when asked to install or configure t3poll. For updates, follow [README updates](../README.md#updates).

Keep the running T3 server and ongoing conversations intact. Setup does not require restarting T3, interrupting a provider, registering a watch, or sending a test message. Follow the user's session constraints on configuration and credential changes.
Keep the running T3 server and ongoing conversations intact. Setup creates a credential but does not require a watch, a test message, or a T3 restart.

## 1. Locate and build
1. Reuse an existing checkout of `https://github.com/eimexdev/t3poll`, or choose a suitable installation directory. Follow [installation](setup.md#install). Verify Node and authenticated GitHub CLI are available to the MCP process. Build successfully before configuring it.
2. Add the minimal entry from [MCP registration](setup.md#register-mcp) to the Codex configuration home used by T3's provider. Preserve unrelated entries. Use absolute executable/script paths where needed. Existing explicit credentials can remain configured; they stay user-managed. A new standard installation needs no connection variables.
3. Run [verification](setup.md#verify). `list` with `threads=true` automatically discovers T3 and creates a credential. If discovery reports multiple instances, ask the user to select the reported home and set `T3POLL_BASE_DIR`. For unsupported layouts, follow [manual overrides](setup.md#select-an-instance-or-use-manual-credentials). Do not guess the destination conversation.
4. Verify the client exposes `watch`, `list`, and `stop` after a reconnect or new provider session. Preserve ongoing work while it loads. Report the installation directory, changed config file, and verification result. If only the CLI was tested, say that MCP verification is still pending.

Reuse an existing checkout of `https://github.com/eimexdev/t3poll`; otherwise clone into `~/code/t3poll`. Preserve local changes. Check the prerequisites and run the build from [manual setup](setup.md#manual-setup). Verify GitHub authentication with `gh auth status`; ask the user to sign in only if needed. MCP does not require `npm link`.
If saved watches exist, `list` may restart monitoring. Use an isolated `T3POLL_HOME` for testing when restarting those watches is outside the user's requested scope. Such a test creates credentials in the isolated directory and does not configure the production state directory.

Done when `dist/cli.js` exists and Node and authenticated GitHub CLI are available to the intended MCP process.

## 2. Find the T3 connection

Reuse an existing t3poll MCP entry when it targets the user's intended server. Otherwise inspect the selected T3 installation's runtime state. Recent T3 source writes `server-runtime.json` beneath its state directory. Common candidates are:

- `$T3CODE_HOME/userdata/server-runtime.json`, if that home is configured.
- `~/.t3/userdata/server-runtime.json` for the default installation.
- A T3 worktree's `.t3/userdata/server-runtime.json`, or a home with `dev/server-runtime.json`, for development instances.

Read `origin` and `pid`. Verify the process is alive and belongs to the selected T3 instance; a leftover file or reused PID is not sufficient. For development instances, inspect the matching version's configuration to distinguish the backend origin from the browser URL. Ask the user to choose if multiple instances are plausible. For a remote server, or an installation without runtime state, obtain the URL from its existing configuration or the user. Do not guess the port.

Set the discovered origin as `T3POLL_URL` in the eventual MCP entry. Discovery is a setup step; t3poll itself currently requires that variable.

Reuse a suitable credential file if one is already configured. Otherwise follow [credential issuance](setup.md#connect-t3) using the CLI matching that T3 installation and its actual data directory. The documented command targets `userdata`; a development instance using `dev` requires the matching CLI's supported directory selection. Resolve that before issuing a token. Keep token contents out of chat, logs, and Git. Preserve any existing credential until its replacement succeeds.

Done when the intended origin and an owner-only credential file are identified. Record token expiration for the user.

## 3. Register MCP

Use the entry in [manual MCP setup](setup.md#register-mcp), with absolute paths to the built script and credential file. Use an absolute Node path if the provider's PATH differs from the interactive shell.

Merge only the t3poll entry into the Codex configuration home used by T3's provider. Preserve unrelated settings. If the provider uses a different account, container, or configuration home, configure that environment rather than assuming the interactive shell's defaults. Leave `T3POLL_THREAD_ID` unset unless the user wants one fixed destination for all watches.

Done when the intended client's configuration points to this checkout and the selected T3 instance. Let the client load it through an MCP reconnect or a new provider session; do not interrupt an ongoing conversation to force a reload.

## 4. Verify and report

Run the [verification steps](setup.md#verify) using the same connection settings. If an existing state directory contains active watches, remember that `list` may restart monitoring. Use a temporary `T3POLL_HOME` for connection verification when monitoring is outside the authorized scope, then remove that temporary directory.

If the client can load MCP now, verify it exposes exactly `watch`, `list`, and `stop`. Otherwise report that MCP verification awaits a reconnect or new session. A successful CLI connection alone does not prove the client loaded MCP.

Report the checkout path, selected T3 address, changed configuration file, credential path and expiration, and verification result. Never include the token. Explain any remaining user action in one sentence. Setup is complete when the client exposes the tools and a connection check lists T3 threads without sending a message.
Setup is complete when the client exposes the tools and a connection check lists T3 threads without sending a message. Managed credentials remain in t3poll's private state directory and renew on use; never include their contents in the report.
6 changes: 6 additions & 0 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,9 @@ This proves the protocol and process flow without spending model tokens. It does
## Steering evidence

[Codex 0.153.2's active-turn test](https://github.com/openai/codex/blob/rust-v0.153.2/codex-rs/app-server/tests/suite/v2/turn_start.rs) includes `turn_start_steers_active_turn_and_returns_active_turn_id`. T3's `CodexSessionRuntime.sendTurn` forwards normal message commands to that operation. The isolated proof also sends a second update while its scripted provider is running. That verifies T3 forwarding; the upstream Codex test establishes same-turn semantics.

## Automatic setup

Tested against an isolated copy of T3 `0.0.41-nightly.20260910.1507` on Linux. The proof starts MCP without URL/token configuration, discovers the instance, creates and verifies its credential, and forces credential renewal from the detached worker before a second delivery. A fresh CLI process then reuses the connection. No running user server or real model is used.

Unit/process tests additionally cover simultaneous first use across processes, expired credential replacement, failed issuance/verification preserving the token, stale process state, ambiguous instances, and manual credential overrides. Discovery requires Linux `/proc` and an installed T3 `dist/bin.mjs` process with `userdata` runtime state. Other layouts retain the manual connection path.
80 changes: 39 additions & 41 deletions docs/setup.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Manual setup

Requires Node.js 24.10 or newer, [GitHub CLI](https://cli.github.com/), and a T3 server with the orchestration HTTP API. Linux is the initial supported platform.
Requires Linux, Node.js 24.10+, [GitHub CLI](https://cli.github.com/) signed in, and a running local T3 installation. Nothing is published to npm yet.

## Install

Reuse your checkout, or clone into a directory of your choosing:

```sh
git clone https://github.com/eimexdev/t3poll.git
Expand All @@ -9,67 +13,61 @@ npm ci
npm run build
```

Run `gh auth login` if GitHub CLI is not already signed in. Only GitHub reads are used.
Run `gh auth login` if needed. t3poll only reads GitHub.

## Connect T3
## Register MCP

Set the T3 server origin and the path to a file containing its bearer token:
Add this entry to the Codex configuration used by T3's provider:

```sh
export T3POLL_URL="http://127.0.0.1:3773"
export T3POLL_TOKEN_FILE="$HOME/.config/t3poll/token"
```toml
[mcp_servers.t3poll]
command = "node"
args = ["/absolute/path/to/t3poll/dist/cli.js", "mcp"]
```

Use your server's actual port. A local setup agent can often discover it; see [agent setup](agent-setup.md). t3poll currently requires this setting explicitly. Remote origins require HTTPS; a local tunnel can use HTTP on loopback. Tokens stay in the protected file, never in MCP arguments or watch output.
Use an absolute Node path if the provider's PATH differs from your terminal. Load the entry in a new provider session or reconnect MCP. T3 itself does not need restarting.

If you need a token, T3 v0.0.40 can issue one using the following command. Set `T3_BASE_DIR` to the **existing T3 data directory**, the directory containing `userdata`. This command creates a credential in that environment. Its token has administrative scopes in this T3 release, although t3poll only uses orchestration read/operate access.
## Verify

Call `list` with `threads=true` through MCP, or run from the checkout:

```sh
export T3_BASE_DIR="/path/to/your/existing/t3-home"
mkdir -p "$HOME/.config/t3poll"
chmod 700 "$HOME/.config/t3poll"
umask 077
t3 auth session issue --base-dir "$T3_BASE_DIR" --label t3poll --ttl 30d --token-only > "$T3POLL_TOKEN_FILE"
chmod 600 "$T3POLL_TOKEN_FILE"
node dist/cli.js list --threads
```

Use the CLI matching your installed T3 release. If you already have a credential with `orchestration:read` and `orchestration:operate`, use that instead. Replacing the token file rotates credentials for active watches without restarting them.
This discovers T3 and creates a credential if needed, then lists destination threads. It sends no messages. `list` can also restart existing saved watches. The MCP client should expose `watch`, `list`, and `stop`.

## Register MCP
Ask the agent to watch a PR and select its destination thread. Thread selection remains explicit; cwd does not identify a conversation.

Add this to your Codex MCP configuration, using absolute paths. T3's Codex provider must use the same Codex configuration home. Load the configuration in a new provider session, or reconnect MCP if your client supports it. Keep ongoing work intact.
## Automatic connection

```toml
[mcp_servers.t3poll]
command = "node"
args = ["/absolute/path/to/t3poll/dist/cli.js", "mcp"]
Discovery checks `T3CODE_HOME`, or `~/.t3` by default, and `.t3` directories in the current directory and its parents. It reads `userdata/server-runtime.json` and verifies the live process, its owner, installed T3 CLI, and data directory. Stale files are ignored.

[mcp_servers.t3poll.env]
T3POLL_URL = "http://127.0.0.1:3773"
T3POLL_TOKEN_FILE = "/absolute/path/to/.config/t3poll/token"
```
The matching T3 CLI issues a 30-day credential. t3poll verifies it before saving it with owner-only permissions under `T3POLL_HOME/credentials`. It replaces managed credentials on use within one day of expiration, or after expiration. MCP and the worker coordinate replacement across processes. Failed replacement preserves the previous token and continues using it until expiration, retrying renewal after five minutes; no other service needs to run. Previous successfully used sessions expire naturally. A newly issued session that fails verification is revoked. Failed revocation is recorded and retried before issuing another session.

After the client loads the tools, ask the agent to watch your PR. Tool calls look like this:
This T3 CLI issues administrative scopes. t3poll uses orchestration read/operate access. Manual token files are neither adopted nor renewed automatically.

```text
list { "threads": true }
watch { "pr": "https://github.com/owner/repo/pull/123", "threadId": "<chosen T3 thread ID>" }
list {}
stop { "id": "<watch ID>" }
```
## Select an instance or use manual credentials

`list` with `threads=true` shows available thread IDs and titles. Select the destination explicitly. Neither MCP nor cwd reliably identifies the current T3 thread. For a dedicated installation you can set `T3POLL_THREAD_ID` to a fixed destination, then omit `threadId` from calls.
For multiple local instances, add the selected home, the directory containing `userdata`:

The MCP call returns after the initial GitHub/T3 checks and worker startup. It does not stay open while monitoring. The worker continues when the MCP client disconnects. A skill is unnecessary because the tool descriptions explain the workflow.
```toml
[mcp_servers.t3poll.env]
T3POLL_BASE_DIR = "/absolute/path/to/t3-home"
```

## Verify
`T3POLL_URL` can also select a discovered instance by origin. Credentials for different homes/origins are stored separately. Saved watches stay attached to their original origin; a server port change requires registering the watch again.

From the checkout, with the two environment variables above set:
Automatic setup supports installed T3 Node CLI processes with the `userdata` layout. Source runners, the older `dev` layout, and remote connections use explicit settings instead:

```sh
node dist/cli.js list --threads
```toml
[mcp_servers.t3poll.env]
T3POLL_URL = "http://127.0.0.1:3773"
T3POLL_TOKEN_FILE = "/absolute/path/to/token"
```

This checks the credential and lists available destinations without sending a message. `list` also restarts any saved active watches; on a fresh installation there are none. Verify that the MCP client exposes `watch`, `list`, and `stop` after loading its configuration.
For a standard `userdata` installation, the matching CLI can issue a manual token with `t3 auth session issue --base-dir /path/to/t3-home --label t3poll --ttl 30d --token-only`. Capture stdout directly into an owner-only file, never chat or Git. Other layouts require that version's directory options. Remote origins require HTTPS.

## Optional terminal command

For a global `t3poll` terminal command, optionally run `npm link`. MCP uses the absolute script path and does not need it. Your terminal needs the connection variables too; the MCP configuration only supplies them to MCP.
Run `npm link` if you want a global `t3poll` command. MCP does not need it. Optional connection overrides must also be set in the terminal when using the CLI.
Loading
Loading