---
title: "Tutorial: build and share a stream"
description: "Build a stream that reports motion, share its reports with a second stream in another project, look inside both, keep them running, and hand them to an agent."
type: "docs-page"
url: "https://tatolab.com/docs/tutorial"
site: "Tatolab"
section: "Tutorial"
---

# Tutorial: build and share a stream

> Build a stream that reports motion, share its reports with a second stream in another project, look inside both, keep them running, and hand them to an agent.

The quickstart ran a stream someone else wrote. In this tutorial you'll build your own and share what it produces. You'll write a **motion watcher**, a stream that watches a camera and reports motion. Then you'll write a second stream, in a project of its own, that reads those reports and keeps a log of them. By the end, both run on their own and an agent can work with them.

![What you'll build: motion_watcher exposes its motion reports, and motion_log, in a project of its own, reads them into a file.](https://tatolab.com/media/docs/share-light.jpg)

## What you'll learn

- How a node declares its inputs, outputs and settings, and how it reads and writes data.
- How to expose an output, and read it from a stream in another project.
- How to look inside running streams with `graph`, `tap`, `logs` and `exchange`, and where each stream's JSON Lines log lives.
- How to keep streams running as part of the machine, and hand them to an AI agent.
- Optionally, how to process video on the GPU, steered by your Python code.

## What you need

- Tatolab installed and its runtime running: `tatolab streams` should print `No streams in this runtime.` See [Install](https://tatolab.com/docs/install). If you built from source, keep `tatolabd` running in a terminal of its own throughout.
- [uv](https://tatolab.com/docs/install/python), a text editor, two or three terminals, and about 45 minutes.
- A camera. Without one, use `tatolab new … --test-pattern` in step 1, and wherever a later `stream.py` imports and adds `CameraSource`, use `TestPatternSource` instead, keeping `name="camera"`. The detector then sees nothing move, but everything else works.
- [`jq`](https://jqlang.org), for step 4: `sudo apt install jq` or `brew install jq`.
- Claude Code or another MCP client, for step 7.

You don't need to know numpy or anything about video. Each step explains the code it adds.

## The steps

1. [Start from the scaffold](https://tatolab.com/docs/tutorial/scaffold): create the project and find your way around it.
2. [Write your first node](https://tatolab.com/docs/tutorial/first-node): a motion detector in numpy that reports what it sees.
3. [Share the motion reports](https://tatolab.com/docs/tutorial/share): expose them, and read them from a second stream in another project.
4. [Look inside](https://tatolab.com/docs/tutorial/look-inside): see the graph, sample the data, read the logs, grab a frame.
5. [Optional: show motion on the picture](https://tatolab.com/docs/tutorial/gpu-tint): a GPU effect driven by the detector.
6. [Keep it running](https://tatolab.com/docs/tutorial/keep-running): streams that outlive your terminal.
7. [Let an agent watch](https://tatolab.com/docs/tutorial/agents): connect Claude Code, or any MCP client, to the runtime.

Each step shows the complete files it changes, so you can catch up if something goes wrong.
