# Quickstart

Scaffold an agent, deploy it once for every tenant on your platform, run it, and open the result in the Console.

Deploy your first agent to every tenant

Scaffold an agent, deploy it once for every tenant on your platform, run it, and open the result
in the Console. About ten minutes, four commands.

- `tanomis` [installed](/getting-started/install) and signed in as a platform operator ([Get access](/getting-started/get-access))

- Python 3.12 or newer and [`uv`](https://docs.astral.sh/uv/) on your `PATH`

- A directory in your own repository

The journey is **Prepare → Scaffold → Validate → Deploy → Run**.

## 1. Check you are signed in

Confirm the context, and see the tenants the deploy will reach:

```bash
tanomis auth status
tanomis tenant ls
```

```text title="Output"
context: saas   logged-in: yes   expires in 54m

TENANT               STATE
northwind-sandbox    active
bluewater-bank       active
orion-retail         active
helix-health         active
```

**Checkpoint: signed in.** You should see `logged-in: yes` and at least one `active` tenant.
Your customers are tenants; the sandbox is the one that serves no customer, and it is where you
will run the agent in step 5.

## 2. Scaffold a working agent

One command gives you a Claude Agent SDK project that already answers. You will make it yours
after it runs.

```bash
tanomis agent new support-copilot --harness claude-agents-sdk --agents-root ./agents --description "Triage and draft responses to support requests"
```

```text
agents/support-copilot/
├── agent.py                      create_agent(input, context) returns (prompt, options)
├── agent.yaml                    what the agent may do: model, hosts, tools, limits
├── pyproject.toml
├── uv.lock
└── tests/test_agent_contract.py
```

Open `agent.py` and change one line, the `system_prompt`, to "Triage support requests: severity,
summary, and a concise draft reply." Everything else stays. Then run the contract test:

```bash
cd agents/support-copilot
uv run python -m unittest tests/test_agent_contract.py
```

**Checkpoint: project ready.** You should see `OK`. The test checks the entrypoint's shape; your
prompt logic is plain Python and needs no runtime to import.

## 3. Dry-run the deploy

See exactly what would be built and where it would be enabled, without uploading a byte. This is
the same command you will put on every pull request.

```bash
uv lock --locked
tanomis agent deploy . --scope global --tenants all --dry-run
```

```text title="Output"
dry-run: tanomis agent deploy .

  name:          support-copilot
  version:       0.1.0
  scope:         global
  tenants:       all (active customer tenants snapshotted by the server)
  build profile: python-managed
  lock policy:   uv-frozen
  files:         5
  checksum:      sha256:9f1c…e2a0

no changes made (dry-run) — no build was created, no bytes were uploaded
```

**Checkpoint: package ready.** You should see "no changes made". Commit `uv.lock`; remote builds
only accept locked projects.

## 4. Deploy to every tenant

One command builds remotely, registers an immutable global version with the contract you
declared, takes a warm-start snapshot, and enables the version for every active tenant. Nothing
routes traffic until that last step.

```bash
tanomis agent deploy . --scope global --tenants all
```

```text title="Output (abridged)"
build bld_3f9a2c created for support-copilot@0.1.0 (global, tenants all, profile python-managed, lock uv-frozen)
upload     done
build      done      image sha256:7ab3…
register   done      support-copilot@0.1.0
golden     ready     sessions will warm-start
enable     done      12 tenants → 0.1.0
```

> **Not a platform operator?** Organization members deploy to their own tenants with
> `--tenant TENANT` instead of `--scope global --tenants all`. The rest of this page is the same.

Confirm what each tenant now serves:

```bash
tanomis agent versions support-copilot --by-tenant
```

**Checkpoint: version enabled.** You should see `enable done` with the tenant count, and every
tenant on `0.1.0` in the versions table. A tenant created later is enabled with `tanomis agent enable`.
A skipped golden is fine: the version still runs, with cold starts.

## 5. Run it

Invoke the agent in the sandbox tenant through the same managed path the Console and your applications
use. The command opens a session, starts a run, and streams its events.

```bash
tanomis session run support-copilot \
  --tenant northwind-sandbox \
  --prompt "Customer reports that CSV exports stop at 80%. Draft a first response."
```

```text title="Output"
session  ses_7d4f9c   run  run_a12bc3   version  support-copilot@0.1.0
run_started      12:04:01
agent_message    Thanks for flagging this. Exports stopping at 80% usually means ...
run_completed    12:04:09   status=succeeded
```

**Checkpoint: first run verified.** You should see `run_completed` with `status=succeeded`. If the
stream closes without it, the run resource in the Console or API is the authority.

 Console · Sessions · ses_7d4f9c · run_a12bc3

Open the run in the Console. The same events are there, plus who invoked it, the policy decisions the run passed, and the execution trace. This is the record every run gets; see [Tour the Console](/getting-started/console-tour).

## What you just built

The lifecycle from the [Overview](/), with every stage now real.

1. **Source** agents/support-copilot in your repository.

2. **Version** support-copilot@0.1.0, global, immutable.

3. **Enablement** Every customer tenant serves 0.1.0.

4. **Session** ses_7d4f9c, warm-started.

5. **Run** run_a12bc3, succeeded.

6. **Evidence** Ledger entry and trace, in the Console.

## Next

 Make it yours
[Write your agent](/guides/build/write-your-agent)
 Prompts, tools, and input handling in agent.py; what the harness gives you.

 Give it tools
[MCP connectors](/guides/connect-tools/mcp-connectors)
 Declare a connector and require confirmation for selected tool calls.

 Ship the next version
[Roll out and roll back](/guides/deploy/rollout-and-rollback)
 Canary 0.2.0 to a few tenants, graduate it, or restore the baseline in one command.

<details class="quickstart-trouble">
<summary>If something goes wrong</summary>

| Symptom | Next action |
|---|---|
| Login required or tenant denied | Run `tanomis login`, then `tanomis auth status`. An administrator confirms your grant. |
| Lockfile missing or stale | Run `uv lock`, commit `uv.lock`, repeat the dry run. |
| Manifest rejected | Restore the generated fields; read [Manifest essentials](/guides/build/manifest-essentials) before widening anything. |
| Build fails after a clean dry run | Read the failing phase in the output, fix the dependency or source error, deploy again. |
| First run is slow | The golden was skipped; the version cold-starts and is still usable. |
| A model or tool action is denied | Compare with `permitted_models`, the approval list, and tenant policy. Refusals are recorded in the run. |

</details>
