Claude Code Bridge
The Claude Code Bridge connects TouchDesigner to a local Claude Code CLI instance over WebSocket, giving you access to Anthropic’s agentic coding assistant directly from within your TD project. It manages the full bridge lifecycle — launching the server process, establishing the WebSocket connection, sending queries with context and tools, handling streaming responses, routing tool execution requests back to TouchDesigner operators, and persisting session history across restarts.
Key Features
Section titled “Key Features”- One-toggle connection that auto-launches the bridge server, exports embedded code, and connects via WebSocket
- Full Claude Code CLI model selection including Opus 4.6, Sonnet 4.5, Haiku 4.5, and custom model IDs
- Session management with create, resume, fork, and destroy — sessions persist across TD restarts
- External LOP tool integration that exposes TouchDesigner tools to Claude Code as MCP tools
- SDK-compliant permission system with per-tool approval dialogs, presets, and persistent permission storage
- Context injection from a Context Grabber operator (text and images)
- Query queue and interrupt system for batch workflows
- Structured JSON output mode with schema validation
- Resumable CLI sessions — pick up previous Claude Code conversations from any working directory
- System prompt customization (default, append, replace, or blank)
Requirements
Section titled “Requirements”- Claude Code CLI: Must be installed and authenticated on your system. The bridge communicates with the CLI via its SDK.
- uv package manager: Required to launch the bridge server process. Install from astral.sh/uv.
Input/Output
Section titled “Input/Output”Inputs
Section titled “Inputs”None — queries are entered via the Prompt parameter on the Input page, or sent programmatically.
Outputs
Section titled “Outputs”- Output 1: The
conversation_dattable — the full conversation history for the current session with columnsrole,message,id,timestamp. - Output 2: The
output_dattext DAT — the most recent assistant response, updated in real time during streaming.
Additional internal tables (per-session):
session_log_dat: Comprehensive log of all events (queries, responses, tool use, costs, interrupts)tool_history_dat: Record of every tool execution with inputs, outputs, and statustool_schemas_dat: Currently registered tool schemas for the active session
Global tables:
tool_permissions: Persistent tool permission rules (synced to disk)session_history: Cross-session history with turn counts, costs, and resume IDs
Usage Examples
Section titled “Usage Examples”Connecting to Claude Code
Section titled “Connecting to Claude Code”- On the Input page, pulse Connect to launch the bridge server and establish the WebSocket connection. The Status parameter shows the connection state.
- The bridge auto-exports its embedded code to disk if needed, launches via
uv run, and connects the WebSocket. Once connected, the status shows “Connected”. - Enter a prompt in the Prompt field and pulse Send Query. The response streams into the output DATs.
Selecting a Model
Section titled “Selecting a Model”On the Session page, use the Model menu to choose a Claude model:
- (CLI Default): Uses whatever model the Claude Code CLI is configured to use.
- Opus 4.6, Sonnet 4.5, Haiku 4.5, Opus 4.1, Sonnet 4: Specific model selections.
- You can also type a custom model ID directly into the field since it is a string menu.
Set Fallback Model if you want automatic fallback when the primary model is unavailable.
Managing Sessions
Section titled “Managing Sessions”On the Session page:
- Pulse New Session to start a fresh conversation. The previous session is saved to history automatically.
- Each session gets its own conversation table, session log, and tool history stored in a dedicated session base inside the operator.
- Set a Session Name for easy identification in the session history.
- Pulse Save Session Log to write the current session log to a persistent file.
- Pulse Destroy Session to clear the current session entirely.
Resuming CLI Sessions
Section titled “Resuming CLI Sessions”The operator can resume previous Claude Code CLI sessions from your working directory:
- On the Session page, set Working Directory to the project folder where Claude Code sessions are stored.
- Pulse Refresh Sessions to scan for available CLI sessions.
- Select a session from the Resume Session dropdown — each entry shows a timestamp and message preview.
- Pulse Resume Selected to continue that conversation.
Using Tools from Other LOPs
Section titled “Using Tools from Other LOPs”- On the Tools page, enable Enable Tools.
- In the External Op Tools sequence, add a row and drag a tool-providing LOP (such as a Tool DAT, MCP Server, or any operator with a
GetTool()method) into the OP field. - Set the tool’s Active state to
enabled,disabled, orforced. - Pulse Update Tools to manually re-parse tool schemas, or let the operator send them automatically on the first query of a new session.
Tools are automatically namespaced with a td_ prefix to avoid conflicts with Claude Code’s built-in tools (Bash, Read, Write, etc.).
Controlling Built-in Claude Code Tools
Section titled “Controlling Built-in Claude Code Tools”On the Tools page, the Tool Preset menu provides quick configurations for Claude Code’s native tools:
| Preset | Description |
|---|---|
| All Enabled | Every built-in tool is available |
| No Bash | Disables shell command execution |
| No Filesystem | Disables Bash, Read, Write, Edit, Glob, Grep, NotebookEdit |
| Read Only | Allows Read, Glob, Grep but disables Write, Edit, Bash |
| Custom | Set individual tool toggles manually |
Each built-in tool (Bash, Read, Write, Edit, Glob, Grep, WebFetch, WebSearch, Task, NotebookEdit, TodoWrite) has its own toggle below the preset menu.
Permission Modes
Section titled “Permission Modes”The Permission Mode setting on the Tools page controls how the operator handles tool approval:
- Default (TouchDesigner): Uses the built-in permission table. Tools without a stored rule trigger an approval dialog. Users can approve once, always, or for the current session.
- Accept Safe Edits: Auto-approves Read, Glob, Grep, Edit, Write, and
td_tools without dialogs. - Plan Mode: Denies all tool execution — Claude presents its plan without acting.
- Bypass All (Dev Only): Approves everything without dialogs. Use only during development.
Enable Show Approval Dialogs to see TouchDesigner message boxes when tool permission is needed. Enable Reset Permissions on New Session to clear stored approvals when starting a fresh session.
Sending Context with Queries
Section titled “Sending Context with Queries”- On the Input page, set Context Operator to a Context Grabber LOP.
- When a query is sent, the operator automatically gathers text and image content blocks from the Context Grabber and includes them with the prompt.
Structured JSON Output
Section titled “Structured JSON Output”- On the Input page, set Output Format to “JSON Schema”.
- Point the JSON Schema DAT parameter to a Text DAT containing your JSON schema.
- Claude Code will return responses conforming to the specified schema.
Query Queue and Interrupt
Section titled “Query Queue and Interrupt”- Send Queue: If a query is already processing, this queues the current prompt to send automatically after the active query completes. Useful for batch workflows.
- Send Interrupt: Interrupts the active query and queues the current prompt to send next.
- Interrupt/Stop: Sends an interrupt signal (equivalent to pressing ESC in the CLI) without queuing a new prompt.
System Prompt Customization
Section titled “System Prompt Customization”On the Session page, the System Prompt Mode setting controls how the system prompt is handled:
- Default (Claude Code): Uses the standard Claude Code system prompt.
- Append to Default: Adds your custom text after the default prompt. Point System Prompt Text to a DAT containing your additions.
- Custom Replace: Replaces the entire system prompt with your DAT’s content.
- None (Blank): No system prompt at all.
Advanced Session Options
Section titled “Advanced Session Options”On the Session page:
- Max Turns: Limit how many agentic turns Claude can take per query (0 = unlimited).
- Max Budget (USD): Cap the dollar cost per query.
- Max Thinking Tokens: Control the token budget for extended thinking blocks.
- Extended Context (1M): Enable the 1 million token context window beta for supported models.
- File Checkpointing: Track file changes so agent edits can be rewound.
- Sandbox: Run commands in a sandboxed environment. Enable Auto-approve Bash in Sandbox to skip approval dialogs for Bash when sandboxed.
- Stream Partial Messages: Include streaming partial events for real-time UI updates.
- Setting Sources: Control which Claude Code configuration sources are loaded (user, project, local).
- Additional Directories: Add extra project directories for context.
- Environment Variables: Pass custom environment variables to the agent process.
- Extra CLI Args: Escape hatch for unsupported SDK options.
Subagent Definitions
Section titled “Subagent Definitions”Point the Agent Definitions DAT parameter on the Session page to a Table DAT with columns: name, description, prompt, tools (comma-separated), model. These define subagents that Claude Code can spawn using its Task tool.
Best Practices
Section titled “Best Practices”- Use the Connect toggle rather than manually managing bridge launch and WebSocket connection separately. It handles the full lifecycle including auto-export, launch, connect, and health monitoring.
- Set a Working Directory on the Session page that matches your project root. This ensures session resume finds previous Claude Code conversations correctly.
- Start with the “All Enabled” tool preset and restrict tools only when you need tighter control over what Claude can do.
- Use “Accept Safe Edits” permission mode during active development to reduce approval fatigue while still protecting against destructive operations.
- Queue multiple prompts using Send Queue when you have a batch of tasks — the operator processes them sequentially without losing any.
- Name your sessions with the Session Name parameter for easy identification when resuming later.
Troubleshooting
Section titled “Troubleshooting”- “uv not found”: The bridge requires the
uvpackage manager. Install it from astral.sh/uv. On macOS, ensure it is in a standard install location (~/.local/bin/,/opt/homebrew/bin/, or/usr/local/bin/). - Bridge launches but WebSocket never connects: The WebSocket connection is delayed to give the bridge time to start accepting connections. If it still fails, check that the Bridge Port is not in use by another process and that no firewall is blocking localhost connections.
- “Cannot send message - not connected to bridge”: The WebSocket has disconnected. Toggle Connect off and on again, or check the bridge process status.
- Tools not appearing in Claude Code: Ensure Enable Tools is on and tool operators are wired into the External Op Tools sequence with their Active state set to
enabled. Pulse Update Tools to force a re-parse. - Tool execution fails with “Operator not found”: The tool operator may have been deleted or moved since tools were last parsed. Pulse Update Tools to refresh operator paths.
- Permission dialog blocks the interface: Set Permission Mode to “Accept Safe Edits” or “Bypass All” to reduce or eliminate approval dialogs. Alternatively, use Add Safe Tools to pre-approve common read-only tools.
- Session resume shows “(no preview)”: The CLI session file exists but has no user messages yet, or the first message was a command. This is normal for system-initiated sessions.
- Empty responses after streaming: Check that the bridge process is still running. If the bridge crashed mid-stream, the operator may show a partial buffer. Reconnect and retry.
- Query queue not draining: Errors clear the queue as a safety measure. Check the bridge log and session log for error details, then resend your queries.
Parameters
Section titled “Parameters”op('claude_code').par.Status Str Current connection status
- Default:
"" (Empty String)
op('claude_code').par.Bridgehost Str Claude Code Bridge server host
- Default:
"" (Empty String)
op('claude_code').par.Bridgeport Int Claude Code Bridge server port
- Default:
0- Range:
- 0 to 1
- Slider Range:
- 0 to 1
op('claude_code').par.Connect Pulse Connect to Claude Code Bridge
- Default:
False
op('claude_code').par.Disconnect Pulse Disconnect from Claude Code Bridge
- Default:
False
op('claude_code').par.Prompt Str The prompt to send to Claude Code
- Default:
"" (Empty String)
op('claude_code').par.Sendquery Pulse Send the prompt to Claude Code Bridge
- Default:
False
op('claude_code').par.Sendqueue Pulse Queue prompt to auto-send after current query completes (batch mode)
- Default:
False
op('claude_code').par.Sendinterrupt Pulse Interrupt current query and send this prompt next
- Default:
False
op('claude_code').par.Interrupt Pulse Interrupt/stop the current active session (equivalent to ESC in CLI)
- Default:
False
op('claude_code').par.Contextop OP Reference to a Context Grabber operator for injecting images and text context
- Default:
"" (Empty String)
op('claude_code').par.Connected Toggle WebSocket connection status
- Default:
False
op('claude_code').par.Currentsession Str Active session ID
- Default:
"" (Empty String)
op('claude_code').par.Lastresponse Str Last Claude response
- Default:
"" (Empty String)
op('claude_code').par.Jsonschema DAT DAT containing JSON schema (only when Output Format = JSON Schema)
- Default:
"" (Empty String)
op('claude_code').par.Enabletools Toggle Enable external tool operators via Tool sequence blocks
- Default:
False
op('claude_code').par.Updatetools Pulse Parse tool sequence and update schemas
- Default:
False
op('claude_code').par.Tool Sequence - Default:
0
op('claude_code').par.Tool0op OP - Default:
"" (Empty String)
op('claude_code').par.Enablebash Toggle Shell command execution
- Default:
False
op('claude_code').par.Enableread Toggle Read files from disk
- Default:
False
op('claude_code').par.Enablewrite Toggle Write/create files on disk
- Default:
False
op('claude_code').par.Enableedit Toggle Edit existing files (find/replace)
- Default:
False
op('claude_code').par.Enableglob Toggle Search for files by pattern
- Default:
False
op('claude_code').par.Enablegrep Toggle Search file contents
- Default:
False
op('claude_code').par.Enablewebfetch Toggle Fetch and process web pages
- Default:
False
op('claude_code').par.Enablewebsearch Toggle Search the web
- Default:
False
op('claude_code').par.Enabletask Toggle Launch subagent tasks
- Default:
False
op('claude_code').par.Enablenotebookedit Toggle Edit Jupyter notebooks
- Default:
False
op('claude_code').par.Enabletodowrite Toggle Task list management
- Default:
False
op('claude_code').par.Showapprovals Toggle Show TouchDesigner message box for tool approvals
- Default:
False
op('claude_code').par.Resetpermissions Toggle Clear tool approvals when creating new session
- Default:
False
op('claude_code').par.Clearallpermissions Pulse Reset all stored tool permissions to default state
- Default:
False
op('claude_code').par.Addsafetools Pulse Quick-add commonly safe tools (Read, Glob, Grep) to permissions
- Default:
False
op('claude_code').par.Updatepermissions Pulse Send permission configuration to Claude Code SDK
- Default:
False
Session
Section titled “Session”op('claude_code').par.Fallbackmodel Str Fallback model if primary fails (empty = none)
- Default:
"" (Empty String)
op('claude_code').par.Systemprompttext DAT Text for Append or Custom system prompt modes
- Default:
"" (Empty String)
op('claude_code').par.Newsession Pulse Create a new conversation session
- Default:
False
op('claude_code').par.Sessionid Str Current session ID (auto-generated if empty)
- Default:
"" (Empty String)
op('claude_code').par.Sessionname Str Friendly name for the current session
- Default:
"" (Empty String)
op('claude_code').par.Workingdir Folder Directory for Claude Code session storage
- Default:
"" (Empty String)
op('claude_code').par.Destroysession Pulse Destroy current session
- Default:
False
op('claude_code').par.Savesessionlog Pulse Save current session log to file
- Default:
False
op('claude_code').par.Refreshsessions Pulse Refresh list of resumable CLI sessions for current working directory
- Default:
False
op('claude_code').par.Resumepulse Pulse Resume the selected session
- Default:
False
op('claude_code').par.Maxturns Int Max agentic turns per query (0 = unlimited)
- Default:
0- Range:
- 0 to 200
- Slider Range:
- 0 to 50
op('claude_code').par.Maxbudget Float Max USD budget per query (0 = unlimited)
- Default:
0.0- Range:
- 0 to 100
- Slider Range:
- 0 to 10
op('claude_code').par.Maxthinkingtokens Int Max tokens for extended thinking blocks (0 = SDK default)
- Default:
0- Range:
- 0 to 128000
- Slider Range:
- 0 to 32000
op('claude_code').par.Enableextendedcontext Toggle Enable 1M token context window beta (Opus 4.6, Sonnet 4.5, Sonnet 4)
- Default:
False
op('claude_code').par.Settingsources Str Comma-separated CLI setting sources (user,project,local). Controls CLAUDE.md, skills, MCP config.
- Default:
"" (Empty String)
op('claude_code').par.Adddirs Str Comma-separated additional project directories for context
- Default:
"" (Empty String)
op('claude_code').par.Enablecheckpoints Toggle Track file changes so agent edits can be rewound
- Default:
False
op('claude_code').par.Enablesandbox Toggle Run commands in a sandboxed environment
- Default:
False
op('claude_code').par.Sandboxautobash Toggle Automatically approve Bash commands when sandbox is enabled
- Default:
False
op('claude_code').par.Streampartials Toggle Include partial/streaming message events for real-time UI
- Default:
False
op('claude_code').par.Envvars Str Key=value pairs (newline-separated) passed as env vars to the agent process
- Default:
"" (Empty String)
op('claude_code').par.Extraargs Str Additional CLI arguments as key=value pairs (escape hatch for unsupported SDK options)
- Default:
"" (Empty String)
op('claude_code').par.Agentdefinitions OP DAT table defining subagents. Columns: name, description, prompt, tools (comma-sep), model
- Default:
"" (Empty String)
Changelog
Section titled “Changelog”v2.1.12026-03-26
- Change default bridge port from 8765 to 43609
v2.1.02026-03-16
- add _find_uv_path() to search common macOS install locations when uv not on GUI PATH - use resolved uv path when launching bridge process
- Clear tools-sent tracking on websocket reconnect (fixes tools not re-registering after bridge restart) - Remove temp disconnect debug logging
- Add Bridge parameter page (connect toggle, host, port, debug, VFS management) - Add bridge process lifecycle (Launchbridge, Stopbridge, PID tracking, stale process detection) - Add bridge file export/import from VFS to disk - Add Checkbridge timer for health polling and auto-reconnect - Show bridge CMD window for debugging (CREATE_NEW_CONSOLE) - Remove duplicate Connect convenience method that shadowed parameter callback - Remove temp debug logging from _get_bridge_vfs and Exportbridge - Move connection parameters from Input page to Bridge page
- Consolidate parameter pages from 8 to 3 (Input, Tools, Session) - Move Output Format and JSON Schema to Input page (per-message settings) - Convert JSON Schema and System Prompt from string pars to DAT op references - Add proper slider ranges for Max Turns, Max Budget, Max Thinking Tokens - Move Permissions controls into Tools page - Move Interrupt button to Input page - Add conditional enableExpr for System Prompt DAT, Sandbox auto-bash, JSON Schema - Fix strmenu empty string crash (use 'none' placeholder for empty session menu)
- Add query queue system (Sendqueue, Sendinterrupt pulses) - Add _build_query_options() shared helper (fixes _send_resume_query using deleted pars) - Add built-in tool toggles with presets (replaces Allowedtools/Disallowedtools strings) - Add Advanced parameter page: extended context, file checkpointing, sandbox, output format, env vars, extra args, agent definitions - Add ForkSession() and GetAgentDefinitions() methods - Fix stale websocket reference in tool/permission handlers
- Add Context parameter page with Contextop OP reference - Add _get_context_blocks() to gather images/text from context_grabber - Convert context_grabber image format to Anthropic content blocks - Include content_blocks in query message when context is available
- Initial commit
v2.0.02025-12-06
## Changes from v1.0.0
Breaking Changes
- Migrated from claude-code-sdk to claude-agent-sdk (0.1.10) - New SDK package with improved API
- Removed monkey patch for CLI protocol compatibility (no longer needed with new SDK)
- Updated
ClaudeCodeOptionstoClaudeAgentOptionsthroughout
New Features - Session Resume System
- Added session_id tracking via PreToolUse hooks for proper thread routing
- Added HookManager CLI-to-TouchDesigner session mapping for multi-session support
- Added continuation_id tracking - Sessions now store CLI resume IDs for conversation continuity
- Resume Session dropdown - Select and resume previous CLI sessions from working directory
- Automatic resume on reconnect - When reconnecting with same session ID, automatically resumes conversation
Improvements
- Fixed thread isolation - Don't use
continue_conversationwhen resume is set - Use stored cli_session_id to resume correct conversation thread
- Update session options on each query for resume support
- Prioritize hook-based session routing over last_activity fallback in
_find_session_for_tool - Mark sessions as active during queries for proper permission routing
- Register CLI session mappings when receiving ResultMessage
Bridge Server Updates (Nov 29, 2025)
- Added colored console output with ANSI support for Windows
- Added
--debugflag for verbose logging - Moved verbose logs from INFO to DEBUG level (tool schemas, permissions, hooks, tool execution)
- Suppress noisy websockets/asyncio loggers
- Clean up SystemMessage logging (remove verbose tools/mcp_servers debug output)
- Updated documentation from Claude Code SDK to Claude Agent SDK
Impact
- Conversations can now be resumed across TouchDesigner sessions
- Proper multi-session support when using multiple claude_code operators
- Cleaner console output with optional debug mode
- More reliable tool permission routing
v1.0.02025-09-12
Initial release