---
title: Infrastructure
description: What a routine runs on and talks to. The cloud run, environments and secrets, connectors and MCP, browsers, storage, sandboxes, notification channels and scheduling, with what is verified and what is not.
sidebar:
  order: 1
---

## What it is

RoutineOS does not host anything. A routine is a Claude scheduled task (formerly called a routine) that runs as a Claude Code cloud session. Everything else a routine touches is reached from that session: connectors and MCP servers, a browser, a store, an optional sandbox, and the channels it uses to reach a person.

This section covers each of those pieces, what RoutineOS checks about them, and what is still unverified.

## Why it exists

Most routine failures are infrastructure failures, not prompt failures: a host the run cannot reach, a connector that was never connected, a secret put in the wrong place, a schedule that fires in UTC when the person meant local time. RoutineOS makes each dependency explicit in `app.toml` so the permission screen can show it before anything is created.

## How it works

### The three tags

Every platform claim RoutineOS relies on lives in the capability registry, `skills/routineos/registry/capabilities.toml`. Each record has an `id`, a `claim`, a `status`, a `source` and a checked date. Statuses are `unverified`, `docs-stated`, `pilot-verified`, `conflict` and `broken`.

```
python3 skills/routineos/scripts/routineos.py platform list
python3 skills/routineos/scripts/routineos.py platform list --status unverified
python3 skills/routineos/scripts/routineos.py platform check <app dir>
```

`platform check` lists which registry records an app depends on (the `relies_on` list under `[risks]` in `app.toml`). When RoutineOS speaks to a person it tags each claim as **pilot** (checked by a real run), **docs** (read in official docs), **unverified** (not checked, do not promise) or **call** (the author's judgement).

### Where each dependency is declared

| Dependency | Declared in | Shown on the permission screen |
|---|---|---|
| Connector or MCP server | `[[integration]]` with `kind = "connector"` or `"mcp"`, named in the routine's `connectors` | Yes, with direction |
| Direct HTTP host | `[[integration]]` with `kind = "http"`, named in `hosts` | Yes, marked reachable or not |
| Secret | `[[secret]]` with `where` and a single `host` | Name and host only |
| Environment | `[environment]`, as the person read it on claude.ai | Level, domains, secret names, setup script, variable names |
| Store | `[store] adapter` in `routine.toml`, `[store] kind` in `app.toml` | Yes |
| Tools a run may use | `tools` on the routine | Yes |
| Schedule | `schedule` and `timezone` on the routine | Local time, UTC cron and runs per day |

### The pages

| Page | Covers |
|---|---|
| [Connectors and MCP](/infrastructure/connectors-and-mcp) | Claude connectors, local MCP servers, gateways, write access |
| [MCP browsers](/infrastructure/mcp-browsers) | Which browser options a cloud run can reach |
| [Storage](/infrastructure/storage) | artifact-db (the default) and the other adapters |
| [Compute sandboxes](/infrastructure/compute-sandboxes) | The cloud run itself and optional external sandboxes |
| [Notification channels](/infrastructure/notification-channels) | Email, Slack, push, Telegram and the Desk |
| [Scheduling and Claude cloud routines](/infrastructure/scheduling) | Triggers, cron, limits, environments, secrets |

## Worked example

Hiring Signals (built from the `jobs-watch` template) needs very little infrastructure: it runs on the cloud session, searches the web, writes to the Desk's artifact-db store, and holds any intro note behind an email gate (48 hours). Its permission screen lists the Gmail connector for the gate, the artifact store, the schedule `0 22 * * 1,4` with its runs per day, and the environment the person reported. If the design later adds a job-board MCP server, that is one more `[[integration]]` and a new permission screen.

## Common pitfalls

- **Trusting the registry as current.** It holds core caveats and may be stale. Search the live docs when a decision depends on a current limit.
- **Copying registry values into other files.** Read the registry instead, so there is one place to update.
- **Assuming RoutineOS can read your environment.** It cannot. See [Scheduling](/infrastructure/scheduling#environments-and-secrets).

## Related

- [Scheduling and Claude cloud routines](/infrastructure/scheduling)
- [routine.toml and app.toml](/reference/routine-toml)
- [CLI reference](/reference/cli#permissions)
