Skip to content

7. Let an agent watch

Connect Claude Code, or any MCP client, to the runtime so an agent can read the motion reports, look at frames and change the running streams.

The runtime speaks MCP, the protocol AI assistants use to call tools. Connect an agent to it and the agent can do what you did in step 4: list streams, read the graph, sample a port, look at a frame, read the logs. It can also change a running stream: add a node, connect it, remove it.

Terminal window
claude mcp add tatolab -- tatolab mcp

Run it in the motion-watcher folder, or add --scope user to have it in every folder, and start a new Claude Code session. When Claude Code starts, it runs tatolab mcp, which connects to the runtime through its local socket. The runtime’s tools appear in Claude Code’s tool list.

Other MCP clients use the same command. In a client configured with JSON, such as Claude Desktop or Cursor, add:

{
"mcpServers": {
"tatolab": { "command": "tatolab", "args": ["mcp"] }
}
}

Check that tatolab streams shows both streams as kept (if you removed motion_watcher to edit it, tatolab run -d in its folder brings it back), then try:

  • “What streams are running on this machine, and what does each one do?” The agent calls list_streams and graph, and reads each stream’s nodes and the catalog’s descriptions of them.
  • “Is anything moving in front of the camera right now?” The agent samples motion_watcher/detector/motion with tap, decodes a few reports, and tells you.
  • “Which streams read the motion reports?” The agent reads each stream’s graph and finds motion_log’s link from motion_watcher/detector/motion.
  • “Show me what the camera sees.” The agent taps motion_watcher/camera/video for a frame’s surface_id, the ID of the frame in GPU memory, then calls exchange, which returns that frame as an image the agent can see.
  • “Add a second window that shows the camera.” The agent adds a DisplayWindow with add_node and connects the camera’s output to it with connect. A window opens while the stream keeps running.
  • “Were there any errors in the last few minutes?” The agent reads the stream’s records with logs.

The runtime also gives the agent a node catalog: every node type it can add, with its description, settings and ports. That’s where your nodes’ docstrings pay off. The agent reads """Reports how much of the picture changed, and whether that counts as motion.""" to learn what MotionDetector does.

  • It works on this machine only. tatolab mcp reaches the runtime through a local socket that only your user account can open. The runtime opens no network port for it.
  • Live changes aren’t saved into a kept stream. If the agent adds a window to motion_watcher, the window stays until the stream next loads; after a restart the runtime loads the graph it recorded at your last tatolab run -d. To make a change permanent, put it in stream.py and run tatolab run -d again.
  • An agent can write nodes too. It can write a node class into a module in your project, or install a package with uv add, then add the node by its import path, such as nodes.my_node:MyNode. Like every Python node, it runs in its own process from your project’s .venv.

To give an agent the runtime on another machine, run tatolab mcp there over ssh:

Terminal window
claude mcp add lab-camera -- ssh lab-camera .local/bin/tatolab mcp

A command run over ssh doesn’t get ~/.local/bin on its PATH on Debian and Ubuntu, so give the path to tatolab, relative to your home folder there. If you use Tailscale, the machine’s tailnet name works as the host name. See Agents and MCP for every tool, and the recipes the runtime provides.

  • Share between streams: exposure levels, addresses, and changing who can read an output while it runs.
  • Logs: the JSON Lines log format, and shipping logs to your own tools, including OpenTelemetry.
  • Use your model: swap the frame differencing for a real detector, running on the GPU.
  • Deploy to a machine: run the watcher on a small Linux box by the door.
  • Use cases: the problems teams solve with streams like these.