Skip to main content
Glama

TT Agent Bridge

Let external CLI agents (ZCode / Claude Code, etc.) directly operate TauriTavern through MCP: read runtime data (chat / variables / World Info activation / logs / raw LLM requests / iframe status bar runtime), execute actions (STScript / send messages / write variables / switch character / jump to World Info entries), and run arbitrary JS in the main document or inside the message iframe to diagnose tavern cards.

Architecture

外部 Agent(ZCode / Claude Code)           dev 脚本(tteval / ttdiag / regress)
      ↕  MCP over stdio                           ↕  agent 角色直连(ws + JSON)
bridge server(Node,仅监听 127.0.0.1,token 鉴权,支持常驻 daemon)
      ↕  WebSocket(扩展/agent 主动连出,多 agent 并存)
TauriTavern 扩展「TT Agent Bridge」
      ├─→ window.__TAURITAVERN__.api   检测:日志 / 世界书激活 / LLM 请求 / 聊天搜索 / console 捕获
      └─→ SillyTavern.getContext()     操作:STScript / 变量 / 消息 / 事件
  • Single source of truth for the protocol contract: src/core/protocol.ts (the bridge imports it directly; don't copy it).

  • The extension only uses public boundaries (TT host ABI + upstream getContext() public members), never touching internal modules.

  • bind-or-attach: when the MCP server starts and a live hub (daemon) with the same token already exists on the port, it automatically mounts as an agent — concurrent MCP clients no longer conflict over the port.

Related MCP server: macOS Companion MCP Server

Install the extension (inside TauriTavern)

  1. Open TauriTavern → top "Extensions" drawer → Manage ExtensionsInstall Extension

  2. Enter this repository's Git URL (TauriTavern only accepts anonymous https Git remotes), e.g.: https://github.com/<your username>/tt-agent-bridge.git

  3. After installation, a "Bridge" status badge appears in the bottom-right corner (turns green once hello is accepted)

Manually placing the directory (data/extensions/third-party/tt-agent-bridge/) also works, but Git installation is recommended for later updates. Upgrade note: the protocol version evolves with the repo (currently v2); the extension and the bridge ship together from the same repo — after pulling the new repo, update the TT extension at the same time (Git update, or sync dist/ + manifest.json and reload the page), otherwise the extension gets rejected with 4003 (red badge, periodic retries).

Startup

Recommended: persistent daemon (the extension keeps a long-lived connection; scripts/MCP attach in seconds, no more waiting for the extension to reconnect each time):

cd bridge
npm install
npm run daemon -- --port 18789 --token <你的token>   # 或 TTAB_PORT / TTAB_TOKEN 环境变量

Or run the MCP server directly (auto-binds when no daemon is present; auto-attaches when a daemon is present):

npm run start                          # 随机 token,打印在 stderr,并写入 .bridge-token
# 或固定 token:
npm run start -- --port 18789 --token <你的token>

Pairing token

Click the Bridge badge at TT's bottom-right → paste the token (token: ... from the server startup log) → click "Reconnect" → the badge turns green when connected. If the token is rejected (4001), the extension keeps slow-retrying every 30 seconds and self-heals once the token is fixed.

Attach to an agent (ZCode / Claude Code)

Register via stdio MCP (example commands — adjust to your client's syntax):

zcode mcp add tt-agent-bridge -- npm run start --prefix <bridge目录绝对路径>

MCP tools at a glance (21)

Detection (read)

Tool

Purpose

tt_status

Capabilities / current character / chat length / chatMetadata keys

tt_read_messages

Floor messages (incl. swipes, optional floor variables, that floor's status bar iframe name)

tt_get_variables

Chat-level or specified-floor variables (MVU stat_data, resolved by swipe_id)

tt_get_character

Character card: summary / full / regexes / scripts / character_book sectioned reads

tt_worldinfo_last

Most recent World Info activation batch

tt_llm_logs

AI request list / preview / raw payload

tt_logs

Frontend (incl. console capture) / backend logs

tt_iframes

Full iframe list + floor→iframe mapping (same-origin / script count / Vue / visibility)

tt_mvu_stat

MVU quick reference: latest stat_data / initvar floor / most recent <UpdateVariable> raw text

tt_search_chat

Host-side full-text chat search

tt_find_message

Locate the last matching message by structural criteria (key name / role)

Operations (write)

Tool

Purpose

tt_exec_stscript

Execute STScript

tt_send_message

Send a message (can trigger generation)

tt_set_variables

Write chat / global variables

tt_switch_character

Switch character

tt_worldinfo_open

Open the World Info entry editor inside the host

tt_llm_keep

Read/set the AI log retention cap (raise it for long debug sessions)

tt_console_capture

Toggle host-wide full console capture (prerequisite for iframe errors to reach tt_logs)

Debug

Tool

Purpose

tt_eval

Execute arbitrary JS in the main document or a specified iframe (frame= param) — getAllVariables/Mvu/eventOn only exist in the message iframe; reading the status bar runtime requires frame

Bridge local

Tool

Purpose

tt_poll_events

Pull the event stream (new messages / World Info activations / frontend & backend errors / LLM request completions / extension logs)

tt_bridge_status

Bridge status (owned/attached mode, extension connection, tool list)

Typical debug scenarios (tavern cards)

  1. Empty status bar / can't read variables: tt_mvu_stat to check whether stat_data exists → tt_iframes to find the status bar frame → tt_eval frame=TH-message--0--2 to inspect getAllVariables() and the DOM inside the iframe → tt_console_capture {enabled:true} then tt_logs kind=frontend to see errors (SyntaxError is usually HTML entity double-decoding).

  2. Broken interactions (tabs won't click / buttons unresponsive): inside tt_eval frame=..., read the script source, check Vue mounting (el.__vue_app__), and dispatchEvent a simulated click as a controlled experiment.

  3. World Info not taking effect: tt_worldinfo_last to check the activation batch → tt_llm_logs raw to see what was actually assembled into the prompt → tt_worldinfo_open to jump straight to that entry.

  4. Verify after editing a card: tt_exec_stscript to trigger a /go reload → tt_read_messages to check the rendered result.

  5. Card structure review: tt_get_character section=regexes|scripts|character_book to read embedded components per section, avoiding dumping the whole card JSON into context.

Dev scripts (bridge/scripts/)

Script

Purpose

lib/agent.mjs

Agent direct-connect client (attach preferred; spawns a daemon as fallback when none is running)

tteval.mjs <file.js>

Execute file contents as the tt_eval code body (supports multiple files)

ttdiag.mjs inspect|switch

Built-in diagnostic sequence

regress.mjs

Regression suite: daemon / attach / 21 tools / dual-agent concurrency

cdp-reload.mjs

Reload the TT page via WebView2 CDP (9222)

pngscan.cjs <png> [unpack <dir>]

Character card PNG unpack inspection / full dump to disk

smoke.mjs

MCP stdio full-path smoke test

Security boundaries

  • WS only listens on 127.0.0.1; the handshake must carry the token (--token / TTAB_TOKEN, randomly generated by default).

  • No arbitrary filesystem / command proxying — file operations are left to the agent's own local tools.

  • Write operations and tt_eval are marked destructive; rely on the agent-side confirmation policy.

  • The token is stored in plaintext in the extension's localStorage and the bridge's .bridge-token, both local files.

Known limitations

  • /send text is passed through pipe escaping; when it contains extreme characters, fall back to tt_eval to operate the context directly.

  • set_variables scope=global depends on /setvar scope=global's object serialization behavior.

  • In attached mode, tt_poll_events only contains events after attach (historical events live in the daemon's ring buffer and aren't replayed through the MCP attach path); tt_bridge_status's extConnected is a snapshot taken at attach time.

  • TauriTavern's context.characterId measures as a numeric string (upstream ST is number); the bridge is already compatible internally.

  • When the daemon dies, attached MCP server calls fail (the error message clearly tells you to restart the daemon); there's no automatic fallback to bind.

Development

npm install && npm run build     # 构建扩展(typecheck + vite -> dist/)
cd bridge && npm install         # bridge 依赖
cd bridge && npm run typecheck   # bridge 侧类型检查

The repo root is the extension (manifest.json + dist/); dist build artifacts are committed with the repo and load directly after TT Git installation. After changing source, run npm run build and commit, and TT's extension update will pull it.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

  • OCR, transcription, file extraction, and image generation for AI agents via MCP.

  • A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ywclgl258/tt-agent-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server