# Progressive Capability (/reference/mcp/progressive-capability)



headless.ly uses progressive capability tiers so agents can explore before they authenticate. An agent connecting for the first time can discover schemas and search demo data. As it proves value, it upgrades through session, claimed, and production tiers — each unlocking more access.

The Four Tiers [#the-four-tiers]

| Tier | Auth                        | Tools                   | Capability                                                |
| ---- | --------------------------- | ----------------------- | --------------------------------------------------------- |
| L0   | None                        | `search`, `fetch`       | Read-only exploration of schemas and demo data            |
| L1   | Session token               | `search`, `fetch`, `do` | Sandboxed read/write within a temporary session           |
| L2   | API key (`hly_sk_...`)      | `search`, `fetch`, `do` | Full tenant access, persistent data, production mutations |
| L3   | Admin key (`hly_admin_...`) | `search`, `fetch`, `do` | Cross-tenant operations, schema modification, bulk access |

L0: Anonymous Exploration [#l0-anonymous-exploration]

No authentication required. The agent connects to any MCP endpoint and starts discovering.

```json
{
  "mcpServers": {
    "headlessly": { "url": "https://crm.headless.ly/mcp" }
  }
}
```

Available operations at L0:

```json title="headless.ly/mcp#fetch"
{ "type": "Schema" }
```

```json title="headless.ly/mcp#search"
{ "type": "Contact", "filter": { "stage": "Lead" }, "limit": 5 }
```

L0 searches return demo data seeded for the subdomain context. A CRM endpoint returns sample contacts, deals, and organizations. A billing endpoint returns sample subscriptions and invoices.

Calling `do` at L0 returns a structured upgrade prompt:

```json
{
  "error": "authentication_required",
  "message": "The do tool requires L1+ authentication.",
  "upgrade": "https://headless.ly/~your-tenant/settings/api-keys"
}
```

**Limits**: 30 requests per minute, 10 burst. Read-only.

L1: Session-Based Access [#l1-session-based-access]

A session token is issued when an agent starts an interactive session. The token is temporary and scoped to a sandboxed environment.

```json
{
  "mcpServers": {
    "headlessly": {
      "url": "https://crm.headless.ly/mcp",
      "headers": { "Authorization": "Bearer hly_sess_tR4nXwBp" }
    }
  }
}
```

At L1, the agent can write data and execute verbs inside the sandbox:

```ts title="headless.ly/mcp#do"
const contact = await $.Contact.create({
  name: 'Alice Chen',
  email: 'alice@startup.io',
  stage: 'Lead'
})
return contact
```

Session data is ephemeral. It persists for the session duration but is not visible to other sessions and is garbage-collected after expiry.

**Limits**: 100 requests per minute, 30 burst, 100 entity operations per `do` call, 30-second execution timeout, 128MB memory.

L2: Claimed Tenant [#l2-claimed-tenant]

L2 is the production tier. The agent operates on real, persistent data within a claimed tenant. Claiming happens by committing a workflow file to your GitHub repository:

```yaml
