Skip to content

Commit 0fb93d8

Browse files
authored
Merge pull request #278 from aojea/demo
add simple demo
2 parents 645a0ea + e3da73b commit 0fb93d8

11 files changed

Lines changed: 5908 additions & 72 deletions

File tree

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,19 @@ SAM is a smart network built for autonomous AI agents:
99
* **Agentic Network:** Formed by lightweight nodes (`sam-node`) that provide self-healing, P2P connectivity, allowing autonomous agents to plug in, communicate, and invoke tools dynamically.
1010
* **Portability:** Cryptographic identities are environment-agnostic, allowing seamless node mobility across cloud, local, and edge environments.
1111

12+
Getting started is a one-liner (see the [Quick Start Guide](site/content/docs/quickstart.md)): install, add the skill, and your agent is on the mesh.
13+
14+
<img src="site/static/demo.gif" alt="Demo: installing SAM, adding the sam-mesh skill, and an agent discovering and calling tools across the mesh" width="100%" />
15+
16+
<details>
17+
<summary><b>Advanced demo</b>: an agent fans a batch of work across a warm pool of reviewer agents on the mesh</summary>
18+
1219
<video src="https://github.com/user-attachments/assets/f1a61b6f-efcd-46d8-a6e6-659fb29dd1ce" width="100%" autoplay loop muted playsinline controls></video>
1320

21+
Full walkthrough: [Warm Agent Pool use case](site/content/docs/use-cases/warm-agent-pool.md).
22+
23+
</details>
24+
1425
---
1526

1627
## Architecture Components

site/content/_index.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ description: Sovereign Agent Mesh - A zero-config, zero-trust decentralized mesh
44
---
55
SAM (Sovereign Agent Mesh) provides a secure, zero-trust P2P network specifically designed for AI agents to discover, share, and invoke tools across machines.
66

7-
<video autoplay loop muted playsinline style="width: 100%; border-radius: 8px;">
8-
<source src="demo.mp4" type="video/mp4">
9-
</video>
10-
117
Think of it as a private, zero-trust overlay network tailored for agent-to-agent communication.
128

139
**Secure by Default**: You do not join a mesh automatically, and your tools are never exposed by default. SAM relies on a Zero-Trust architecture, meaning you are 100% isolated until you explicitly join a mesh and allow access. You can use our public testnet for "Easy Mode" testing, or run completely in "DIY Mode" by hosting your own control plane.

site/content/docs/quickstart.md

Lines changed: 66 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -40,73 +40,13 @@ Expand-Archive -Path "sam.zip" -DestinationPath "$env:ProgramFiles\sam"
4040

4141
## 2. Connect Your Node to the Mesh
4242

43-
Getting a node onto the mesh takes two things: **joining** — registering the node and obtaining its cryptographic identity (a Biscuit token) via an OIDC login — and **running** it. The `--join` flag on `run` does both in one command: it enrolls the first time (when the node has no identity yet), then starts serving; on every later restart it's a no-op since the identity is already stored.
43+
**Shortcut: let your agent do it.** If you use an agent that supports skills (Claude Code, Google Antigravity, …), install the [agent skill](#4-teach-your-ai-agent-to-use-the-mesh) with `sam-node skill install`, restart the agent, and ask it to connect to the mesh. The skill walks it through starting the node and registering the MCP endpoint on its own — the only thing it hands back to you is the one-time enrollment login below.
4444

45-
### Recommended: One Command
45+
Getting a node onto the mesh takes two steps: **joining** — registering the node and obtaining its cryptographic identity (a Biscuit token) via an OIDC login — and **running** it. We recommend doing them as two explicit commands: enrollment is a one-time step per machine whose prompts (browser login, admin approval) are easier to follow on their own, and it is the same flow the [agent skill](#4-teach-your-ai-agent-to-use-the-mesh) guides your agent through. If you prefer a single command, see the [alternative below](#alternative-one-command).
4646

47-
#### Using the Binary
48-
The binary is the simplest way to run a node locally — no volumes or port mapping to think about:
49-
```bash
50-
SAM_API_TOKEN=my-secret-token sam-node run --join --bind-addr 127.0.0.1:8080
51-
```
52-
The CLI will open your browser for login (or print a device code if headless). Once authenticated:
53-
```text
54-
Successfully joined the Sovereign Agent Mesh!
55-
INFO sam-node [AuthN] Successfully authenticated with router via libp2p: ...
56-
SAM Node Online.
57-
PeerID: 12D3KooW...
58-
```
59-
60-
#### Using Docker
61-
Docker works the same way, but needs a persistent volume for the identity and explicit port mapping (`5001/udp`, `5002/tcp` for libp2p, `8080/tcp` for the local API):
62-
```bash
63-
mkdir -p $(pwd)/sam-data
64-
docker run -it \
65-
--user "$(id -u):$(id -g)" \
66-
-v $(pwd)/sam-data:/data \
67-
-p 5001:5001/udp \
68-
-p 5002:5002 \
69-
-p 8080:8080 \
70-
-e SAM_API_TOKEN=my-secret-token \
71-
ghcr.io/google/sam-node:latest \
72-
run --join --data-dir /data --bind-addr 0.0.0.0:8080
73-
```
74-
Use `-it` for this first run so you can complete the browser/device-code login; once enrolled, restart it detached with `-d` instead (`--join` is a no-op at that point, so it's safe to leave in your start command). If there's no interactive terminal attached (e.g. `-d` on the very first run), the node instead comes up as an unauthenticated sidecar waiting for out-of-band enrollment over MCP.
75-
76-
By default `--join` enrolls with the public testnet (`bananas.sam-mesh.dev`); pass `--control-plane <url>` to join a different mesh.
77-
78-
#### Running It in the Background
47+
### Recommended: Join, Then Run
7948

80-
`sam-node run` stays in the foreground. Add `--daemonize` to start it detached and return as soon as its local API answers — useful when an AI agent is driving the setup, or when you don't want a terminal dedicated to the node:
81-
82-
```bash
83-
sam-node run --daemonize
84-
```
85-
```text
86-
sam-node is running in the background.
87-
PID 48213
88-
Endpoint http://127.0.0.1:8080/mcp
89-
Token /home/you/.config/sam-mesh/api-token
90-
Logs /home/you/.config/sam-mesh/sam-node.log
91-
Stop kill 48213
92-
```
93-
94-
If no API token is configured (`SAM_API_TOKEN` or `--api-token-path`), `--daemonize` generates one under the data directory and reuses it on later starts. The command is idempotent: re-run it to confirm a node is up. Enrollment still needs a one-time login, so on a node with no identity it tells you to run `sam-node join --headless <control-plane-url>` first. In headless mode, SAM prefers OAuth device flow automatically when the provider supports it, and falls back to OOB code-paste only when needed.
95-
96-
#### Starting Over
97-
98-
A node reuses whatever is already in its data directory, which is what you want day to day but not when you are testing setup flows. Two levels of reset:
99-
100-
```bash
101-
sam-node reset # forget the mesh identity only, keep the PeerID
102-
sam-node reset --all # delete every file the node keeps, including its key
103-
```
104-
105-
`--all` asks for confirmation, and needs `--yes` when there is no terminal to ask on. Both refuse while a node is still running, so stop it first (`kill <pid>` from the `--daemonize` output). After `--all` the node generates a new PeerID and has to enroll again.
106-
107-
### Alternative: Join and Run Separately
108-
109-
If you're deploying headlessly with a pre-issued bootstrap token, or just prefer explicit steps, you can join and run as two commands instead.
49+
Join once to enroll the node, then run it. The identity is stored in the node's data directory and reused on every later start.
11050

11151
#### Step 1: Join the Mesh
11252

@@ -186,6 +126,66 @@ docker run -d \
186126
```
187127
Verify the node is running with `docker logs sam-node`.
188128

129+
#### Running It in the Background
130+
131+
`sam-node run` stays in the foreground. Add `--daemonize` to start it detached and return as soon as its local API answers — useful when an AI agent is driving the setup, or when you don't want a terminal dedicated to the node:
132+
133+
```bash
134+
sam-node run --daemonize
135+
```
136+
```text
137+
sam-node is running in the background.
138+
PID 48213
139+
Endpoint http://127.0.0.1:8080/mcp
140+
Token /home/you/.config/sam-mesh/api-token
141+
Logs /home/you/.config/sam-mesh/sam-node.log
142+
Stop kill 48213
143+
```
144+
145+
If no API token is configured (`SAM_API_TOKEN` or `--api-token-path`), `--daemonize` generates one under the data directory and reuses it on later starts. The command is idempotent: re-run it to confirm a node is up. Enrollment still needs a one-time login, so on a node with no identity it tells you to run `sam-node join --headless <control-plane-url>` first. In headless mode, SAM prefers OAuth device flow automatically when the provider supports it, and falls back to OOB code-paste only when needed.
146+
147+
#### Starting Over
148+
149+
A node reuses whatever is already in its data directory, which is what you want day to day but not when you are testing setup flows. Two levels of reset:
150+
151+
```bash
152+
sam-node reset # forget the mesh identity only, keep the PeerID
153+
sam-node reset --all # delete every file the node keeps, including its key
154+
```
155+
156+
`--all` asks for confirmation, and needs `--yes` when there is no terminal to ask on. Both refuse while a node is still running, so stop it first (`kill <pid>` from the `--daemonize` output). After `--all` the node generates a new PeerID and has to enroll again.
157+
158+
### Alternative: One Command
159+
160+
The `--join` flag on `run` does both steps in one command: it enrolls the first time (when the node has no identity yet), then starts serving; on every later restart it's a no-op since the identity is already stored. By default `--join` enrolls with the public testnet (`bananas.sam-mesh.dev`); pass `--control-plane <url>` to enroll with a different mesh.
161+
162+
#### Using the Binary
163+
```bash
164+
SAM_API_TOKEN=my-secret-token sam-node run --join --bind-addr 127.0.0.1:8080
165+
```
166+
The CLI will open your browser for login (or print a device code if headless). Once authenticated:
167+
```text
168+
Successfully joined the Sovereign Agent Mesh!
169+
INFO sam-node [AuthN] Successfully authenticated with router via libp2p: ...
170+
SAM Node Online.
171+
PeerID: 12D3KooW...
172+
```
173+
174+
#### Using Docker
175+
```bash
176+
mkdir -p $(pwd)/sam-data
177+
docker run -it \
178+
--user "$(id -u):$(id -g)" \
179+
-v $(pwd)/sam-data:/data \
180+
-p 5001:5001/udp \
181+
-p 5002:5002 \
182+
-p 8080:8080 \
183+
-e SAM_API_TOKEN=my-secret-token \
184+
ghcr.io/google/sam-node:latest \
185+
run --join --data-dir /data --bind-addr 0.0.0.0:8080
186+
```
187+
Use `-it` for this first run so you can complete the browser/device-code login; once enrolled, restart it detached with `-d` instead (`--join` is a no-op at that point, so it's safe to leave in your start command). If there's no interactive terminal attached (e.g. `-d` on the very first run), the node instead comes up as an unauthenticated sidecar waiting for out-of-band enrollment over MCP.
188+
189189
## 3. Query the Local MCP API
190190

191191
Your SAM node exposes a standard Model Context Protocol (MCP) server. The easiest way to interact with it is using the `mcp-client` CLI tool (which is installed alongside `sam-node`):
@@ -249,3 +249,5 @@ sam-node skill show # print the document, for agents with a diffe
249249
```
250250

251251
Re-run `sam-node skill install` after upgrading `sam-node` to refresh the document. Then connect your agent to the node's MCP endpoint — see the [integration guides](../integrations/) — and restart it so both the skill and the tools load.
252+
253+
With the skill installed you can also skip the manual setup entirely and ask the agent to bring itself online (for example: *"connect to the sam mesh and show me what tools are available"*). The skill teaches it to start the node with `sam-node run --daemonize`, read the API token, and register the MCP endpoint itself; it only stops to hand you the one-time `sam-node join` login, which stays with a human by design.

site/content/docs/use-cases/warm-agent-pool.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ weight: 10
77
Fan a batch of work across a pool of identical, already-running worker agents —
88
built entirely from ordinary mesh MCP services, no gossip and no node changes.
99

10+
<video autoplay loop muted playsinline controls style="width: 100%; border-radius: 8px;">
11+
<source src="../../../demo-warm-agent-pool.mp4" type="video/mp4">
12+
</video>
13+
1014
Source: [`development/examples/code-reviewer-pool/`](https://github.com/google/sam/tree/main/development/examples/code-reviewer-pool).
1115

1216
## The idea

site/layouts/index.html

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,23 @@ <h1 class="landing-title">SAM</h1>
2525
</div>
2626
</div>
2727

28-
<!-- Bottom Row: Demo Video -->
28+
<!-- Bottom Row: Demo Player -->
29+
<link rel="stylesheet" href="{{ "vendor/asciinema-player/asciinema-player.css" | relURL }}">
2930
<div style="width: 100%;">
30-
<video autoplay loop muted playsinline style="width: 100%; border-radius: 12px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5), 0 0 40px rgba(0, 240, 255, 0.1); border: 1px solid rgba(0, 240, 255, 0.15);">
31-
<source src="{{ "demo.mp4" | relURL }}" type="video/mp4">
32-
</video>
31+
<div id="demo-player" data-cast="{{ "demo.cast" | relURL }}" style="border-radius: 12px; overflow: hidden; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5), 0 0 40px rgba(0, 240, 255, 0.1); border: 1px solid rgba(0, 240, 255, 0.15);"></div>
3332
</div>
33+
<script src="{{ "vendor/asciinema-player/asciinema-player.min.js" | relURL }}"></script>
34+
<script>
35+
var demoEl = document.getElementById('demo-player');
36+
AsciinemaPlayer.create(demoEl.dataset.cast, demoEl, {
37+
speed: 2.5,
38+
idleTimeLimit: 2,
39+
autoPlay: true,
40+
loop: true,
41+
preload: true,
42+
fit: 'width'
43+
});
44+
</script>
3445
</div>
3546

3647
{{ partial "scripts.html" . }}

0 commit comments

Comments
 (0)