<!-- source: https://www.secondlayer.tools/docs/mcp -->

# MCP and skills

Give Claude Code, Cursor, or any MCP client live access to Secondlayer, and teach it the rules for building on it.

## Connect

Point your agent at the hosted server and sign in once in the browser. In Claude Code:

```bash
claude mcp add --transport http secondlayer https://api.secondlayer.tools/mcp
```

The first call opens a sign-in page: check the app's name and allow it. Reads it makes use your credits, like reads made with a key. The hosted server carries the read tools only, so install the local server when you need to deploy subgraphs or manage webhooks.

### Remote

Any client that speaks Streamable HTTP takes the URL alone:

```json .mcp.json
{
  "mcpServers": {
    "secondlayer": {
      "type": "http",
      "url": "https://api.secondlayer.tools/mcp"
    }
  }
}
```

| Credential | When |
| --- | --- |
| Browser sign-in (OAuth) | The default. The client registers itself and opens the consent page. |
| `Authorization: Bearer <sk-sl_ key>` | A client without OAuth support. |

- An app can't make or revoke keys. Revoke an app under Apps on [/account/keys](/account/keys).
- Tools marked "Local only" below are not on the hosted server.

### Local

The `@secondlayer/mcp` package runs the server over **stdio**, with every tool:

```json .mcp.json
{
  "mcpServers": {
    "secondlayer": {
      "command": "npx",
      "args": ["-y", "@secondlayer/mcp"],
      "env": {
        "SECONDLAYER_API_URL": "https://api.secondlayer.tools",
        "SECONDLAYER_API_KEY": "<sk-sl_ key from /account/keys>"
      }
    }
  }
}
```

A client's JSON `env` can't read your shell, so this block holds the hosted values from the [Introduction](/docs#get-started) literally.

On your box, set these instead of the key ([Self-host](/docs/self-host#use-these-docs-on-your-box)):

| Variable | Value |
| --- | --- |
| `SECONDLAYER_API_URL` | `http://127.0.0.1:3800` |
| `INSTANCE_TOKEN` | From `.env.local` |

The same package's `secondlayer-mcp-http` command serves it over HTTP behind your own URL, with sessions and an optional `SECONDLAYER_MCP_SECRET` bearer.

### Authentication

| Surface | Reads | Writes |
| --- | --- | --- |
| Index, Streams, Contracts, Scaffold | Hosted: `SECONDLAYER_API_KEY`. Self-host: open on loopback | — |
| Subgraphs, Webhooks | Hosted: `SECONDLAYER_API_KEY`. Self-host: open on loopback | Hosted: `SECONDLAYER_API_KEY`. Self-host: `INSTANCE_TOKEN` |

A token sent on a loopback read that did not need it is ignored, never rejected.

### Start here

Read `secondlayer://context` first, then any other resource you need, before calling tools.

| Resource | What it returns |
| --- | --- |
| `secondlayer://chain-triggers` | Chain-webhook trigger types and the filter fields each accepts (for webhooks_create triggers). |
| `secondlayer://column-types` | Subgraph column types, SQL mappings, and options |
| `secondlayer://context` | Live agent context — what exists (your subgraphs, webhooks, account), what you can do, and read-auth tiers. |
| `secondlayer://filters` | Event filter types and their available fields |
| `secondlayer://traits` | SIP trait standards the platform can classify and scaffold against — the valid values for contracts_find `trait` and subgraph scaffold `--trait`. |
| `secondlayer://samples/{contractId}` | Decoded camelCase print samples for a contract (schema + up to 5 events). |

For Index, call `index_discover` first to learn every event type, its columns, and the filters it accepts.

### Tools

Reads are cursor-paginated. Writes that kick off work (reindex, backfill, replay, deploy) return an `operationId` to poll. Account tools register only when `SECONDLAYER_API_URL` is the hosted API.

### Scaffold

| Tool | What it does |
| --- | --- |
| `subgraphs_scaffold` | Generate a subgraph from observed print events when available; ABI token transfers or public functions only when the contract has never printed. |

### Subgraphs

| Tool | What it does |
| --- | --- |
| `subgraphs_backfill` | Backfill a subgraph over a block range. Local only. |
| `subgraphs_delete` | Delete a subgraph permanently. Local only. |
| `subgraphs_deploy` | Deploy a subgraph from TypeScript code. Local only. |
| `subgraphs_gaps` | List indexing gaps (missing block ranges) for a subgraph. Local only. |
| `subgraphs_list` | List all deployed subgraphs. Local only. |
| `subgraphs_operations` | Operation history for a subgraph (deploy/reindex/backfill/stop), newest first — status, block range, progress, and error. Local only. |
| `subgraphs_query` | Query rows from a subgraph table (max 200 rows), reading the open /v1 surface — { rows, next_cursor, tip } envelope, cursor-paginated (no offset). Local only. |
| `subgraphs_reindex` | Reindex a subgraph: drops and rebuilds the whole subgraph from its start block to chain tip. Local only. |
| `subgraphs_spec` | Fetch a subgraph's self-describing spec — the tables, columns, filters, and read URLs a consumer needs, without guessing. Local only. |
| `subgraphs_status` | Get full details of a subgraph including schema, health (incl. health.emptyMapping when processed events wrote 0 rows), and table columns. Local only. |
| `subgraphs_stop` | Cancel an in-flight reindex or backfill operation for a subgraph. Local only. |
| `subgraphs_test` | Prove a subgraph mapping writes rows against Index data before deploy. Local only. |

### Webhooks

| Tool | What it does |
| --- | --- |
| `webhooks_create` | Create a webhook that fires on raw chain events (set triggers). Local only. |
| `webhooks_dead` | List a webhook's dead-letter queue — deliveries that exhausted their retries, with the outbox id, payload, and last error. Local only. |
| `webhooks_delete` | Delete a webhook. Local only. |
| `webhooks_deliveries` | List recent delivery attempts for a webhook — status code, attempt count, error, duration, timestamps. Local only. |
| `webhooks_get` | Get full detail for a webhook (triggers, auth, retry config, circuit state). Local only. |
| `webhooks_list` | List all webhooks for the current account. Local only. |
| `webhooks_pause` | Pause a webhook: stops delivery attempts and stops queueing new ones. Local only. |
| `webhooks_replay` | Replay a block range for a webhook. Local only. |
| `webhooks_requeue` | Requeue ONE dead-lettered delivery for another attempt, by its outbox id from webhooks_dead. Local only. |
| `webhooks_resume` | Resume a paused webhook (also clears a tripped circuit breaker). Local only. |
| `webhooks_rotate_secret` | Rotate a webhook's signing secret. Local only. |
| `webhooks_test` | Send a one-off test webhook to a webhook's URL (built for its format, SSRF-guarded). Local only. |
| `webhooks_update` | Patch a webhook (name, url, authConfig, format, retry, timeout, concurrency). Local only. |

### Index

| Tool | What it does |
| --- | --- |
| `batch_query` | Run up to 10 public /v1 reads in one round trip (POST /v1/batch). |
| `index_blocks` | List decoded blocks from Index. |
| `index_contract_calls` | List decoded contract calls from the Index (function name, args, result). |
| `index_discover` | Discover the Index vocabulary: every event type and its columns, allowed/equality filters, and required-non-null fields (and which types accept `trait`). |
| `index_events` | List decoded chain events from the Index by event type. |
| `index_ft_transfers` | List decoded SIP-010 fungible-token transfers from Index. |
| `index_nft_transfers` | List decoded SIP-009 non-fungible-token transfers from Index. |
| `index_print_schema` | Empirical per-topic print payload schemas for a contract, inferred from sampled on-chain events: each topic's fields with observed Clarity types, decoded TS types, subgraph column types, and presence rates. |
| `index_transactions` | List decoded transactions from Index. |

### Streams

| Tool | What it does |
| --- | --- |
| `streams_dumps` | List the Streams bulk parquet dumps manifest — coverage range, latest_finalized_cursor, and per-file metadata (block range, row count, size, sha256, signed URL). |
| `streams_tip` | Current canonical chain tip as Streams sees it: block height/hash, burn height, finalized_height, lag_seconds, and the oldest seekable height/cursor for this key's retention window. |

### Contracts

| Tool | What it does |
| --- | --- |
| `contracts_find` | Discover deployed Stacks contracts conforming to a trait (e.g. "sip-010", "sip-009", "sip-013"). |
| `contracts_get_abi` | Fetch a single deployed contract's ABI from the registry (prod-safe). |

### Codegen

| Tool | What it does |
| --- | --- |
| `codegen_index_schema` | Generate an ORM schema for the Index tables (blocks, transactions, decoded_events, …) — the same output as `sl codegen index`. Local only. |

### Instance

| Tool | What it does |
| --- | --- |
| `instance_status` | Decoder health and empty-index diagnosis from GET /public/status. Local only. |

### Archive

| Tool | What it does |
| --- | --- |
| `archive_latest` | Signed pointer to the official archive tree (hosted). Local only. |
| `archive_quote` | Price a hosted archive fetch (metered). Local only. |
| `archive_verify` | Read-only, free compare of this instance against a signed archive (POST /v1/archive/verify). Local only. |
| `credits_balance` | Archive credits balance at api.secondlayer.tools. Local only. |
| `archive_bootstrap` | Restore verified history into this instance (secondlayer bootstrap --against … --yes --json). Local only. |
| `archive_repair` | Plan (default) or apply a repair of local chain data against a signed archive. Local only. |

### Account

| Tool | What it does |
| --- | --- |
| `account_create_key` | Mint an account key (sk-sl_*) for archive credits, quote, and fetch at api.secondlayer.tools. Local only, against the hosted API. |
| `account_whoami` | Show the archive account email at api.secondlayer.tools, not the self-host instance. Hosted only. |

### Notes

- **One-time secrets.** `webhooks_create` returns its signing secret exactly once: forward it to the user.
- **Cursors are opaque** and per-keyspace: contract-call cursors are not interchangeable with event cursors.
- **Tail without streaming.** For subgraph tables, every page with rows returns `next_cursor`; poll with `cursor = next_cursor ?? cursor`.
- See the [REST API](/docs/rest-api) for the underlying endpoints.

## Agent skill

The `secondlayer` skill teaches an agent the rules for building on Secondlayer: read the print schema before writing a handler, prove a mapping writes rows before deploying it.

```bash
bunx skills add ryanwaits/secondlayer --skill secondlayer -y
```

| Use | When |
| --- | --- |
| The skill | An agent writes code against Secondlayer |
| MCP | It needs live state: your subgraphs, webhooks, chain tips |

The skill is static text that can't see your instance, and MCP can, so install both. Source: [`skills/secondlayer`](https://github.com/ryanwaits/secondlayer/tree/main/skills/secondlayer).

## Notes for agents

- Hosted: 'claude mcp add --transport http secondlayer https://api.secondlayer.tools/mcp'. A 401 names the OAuth metadata; the person signs in once in the browser. Clients without OAuth send 'Authorization: Bearer sk-sl_*'. Read tools only; tools listed "Local only" need the stdio server.
- Install: 'bunx @secondlayer/mcp' with SECONDLAYER_API_URL and INSTANCE_TOKEN for the instance. For hosted archive and credits tools also set SECONDLAYER_API_KEY.
- Read first: the 'secondlayer://context' resource (instance state, chain tips, capabilities), plus 'secondlayer://filters' and 'secondlayer://chain-triggers'.
- Read tools: index_discover to learn event types and filters, then index_events (or index_ft_transfers, index_contract_calls); cursor-paginate.
- subgraphs_deploy: run with dryRun first to preview the DDL. webhooks_create returns a one-time signingSecret; capture it.
- Webhook and subgraph tools: list, get, query, deploy, create, update, pause, resume, rotate-secret, deliveries, dead, requeue, replay.

## Setup

Ensure setup once, skipping any step already done:
- Skill: `bunx skills add ryanwaits/secondlayer --skill secondlayer -y`
- CLI: `bun add -g @secondlayer/cli`
- Instance: `secondlayer init` writes `INSTANCE_TOKEN`. Loopback `/v1` reads need no key.
- Hosted/archive: export `SECONDLAYER_API_KEY` (`sk-sl_*`) or buy credits with `secondlayer credits buy` (`balance`, `refill`), then `secondlayer whoami`
