Sorties

Register a webhook and token once, then fire it from any Claude session with a single MCP tool. Tokens stay encrypted on the server — never in a conversation, a skill file, or a git repo.

A Sortie is a stored webhook + bearer-token pair you can fire from any Claude session with one MCP call: fire_sortie. You register it once in BlackOps; the token is encrypted at rest on the server and decrypted only at the moment of firing. It never reaches the conversation, a skill file, a client, or a git repo.

Sorties work for Anthropic Claude Code Routines first-class, and for any HTTP webhook generally — Zapier, n8n, GitHub Actions repo-dispatch, or a custom server.

Why Sorties exist

Firing an action from a Claude session means the credential has to live somewhere the session can reach. In practice that has meant one of two bad options:

  • Hardcode the token in a skill file. That file lives in git forever — a permanent leak risk.
  • Read it from a local shell environment variable. That only works when Claude Code is the caller on that machine. It fails from the web app, the mobile app, another skill, or another routine.

Sorties remove the dilemma. The token is stored server-side once. Any Claude surface that can call the BlackOps MCP can fire the action by name — without ever seeing the secret.

This is the orchestration layer of BlackOps: Brain stores knowledge, Notes capture artifacts, Sorties fire actions.

Key concepts

  • Fire URL — the upstream endpoint the Sortie calls. Any HTTPS URL, any method (POST default).
  • Headers — the full set of request headers, configured as JSON. This is where Sorties stay endpoint-agnostic: you transcribe the headers from the endpoint's own example verbatim, and BlackOps adds no vendor-specific magic of its own.
  • Token — an optional secret, encrypted at rest. You place it in the request with the {{token}} placeholder (see below); it's never stored in the clear and never returned.
  • Default payload — a JSON body sent when the caller passes none. An explicit payload is shallow-merged on top.
  • Status — the last-known lifecycle state shown in the UI: Armed (configured, ready), Fired (in flight), Returned (upstream responded), Failed.
  • Fire history — every fire is recorded: when, who, the upstream status, duration, and any returned session URL. Payloads are never stored — only a SHA-256 hash (taken before the token is substituted, so the secret is never hashed).

How the token works

BlackOps does not know how any particular endpoint expects to be authenticated — and it doesn't need to. The Sortie config fully describes the request, and the only thing the server adds is the secret, wherever you mark it with {{token}}:

  • "Authorization": "Bearer {{token}}" — bearer auth (most APIs, Claude Code routines)
  • "x-api-key": "{{token}}" — API-key header auth
  • a {{token}} in the URL — query-string / path token auth
  • a {{token}} in the default payload — token-in-body webhooks

At fire time the decrypted token replaces every {{token}}. If you store a token but never reference it anywhere, BlackOps falls back to Authorization: Bearer <token> so simple single-token webhooks need no header config at all.

The token field is write-only. Once saved it can be rotated (paste a new value) or removed, but never read back.

Creating a Sortie

Go to Settings → Sorties → New Sortie and fill in:

| Field | Notes | | --- | --- | | Name | The handle you'll fire by, e.g. bug-fixer. Unique per site. | | Fire URL | The upstream endpoint, e.g. https://api.anthropic.com/v1/claude_code/routines/trig_…/fire. | | Method | POST by default. | | Token | Optional secret, encrypted at rest. Reference it with {{token}} in a header, the URL, or the payload. | | Headers | JSON object of request headers — transcribe the endpoint's example verbatim, with {{token}} where the secret goes. | | Default payload | Optional JSON body sent when no payload is supplied. | | Rate limit | Optional per-minute cap for this Sortie. Defaults to a conservative system limit. |

Worked example: a bug-fixer routine

Here's a real end-to-end Sortie that fires a Claude Code Routine to fix a bug. Anthropic's routine page gives you a curl example; you transcribe it into a Sortie named bug-fixer, putting {{token}} where the bearer secret goes:

| Field | Value | | --- | --- | | Name | bug-fixer | | Fire URL | https://api.anthropic.com/v1/claude_code/routines/trig_…/fire | | Method | POST | | Headers | { "Authorization": "Bearer {{token}}", "anthropic-version": "2023-06-01", "anthropic-beta": "experimental-cc-routine-2026-04-01" } | | Token | the routine's fire token — stored encrypted, substituted into {{token}} at fire time | | Default payload | (empty — the bug to work on is passed per fire) |

The anthropic-version and anthropic-beta headers are part of the endpoint's contract, so they live in your config — not in BlackOps. If Anthropic revs the beta identifier, you change the header here; nothing in the platform needs to change. (A tokenless fire of this endpoint returns 401; with the token and these headers it returns 200.)

Firing a Sortie

From any Claude session connected to the BlackOps MCP:

list_sorties()
→ the Sorties you can fire (names, URLs, status, last-fired time)

fire_sortie("bug-fixer", { text: "Investigate and fix the failing checkout flow" })
→ 200 — { "claude_code_session_url": "https://claude.ai/code/session_…" }

The payload is shallow-merged onto the Sortie's default payload and sent as the request body — its shape is whatever the endpoint expects (the bug-fixer routine takes an optional text turn). When the response carries a claude_code_session_url, fire_sortie surfaces it so you get a direct link to the session the routine started.

Every fire is recorded in the Sortie's history (status, upstream code, duration, session URL), and you can replay the same call from the admin UI's Test fire button to confirm wiring before depending on it from an agent.

Rate limiting

Every fire is rate-limited on two axes to prevent runaway loops:

  • Per-Sortie — uses the Sortie's own override, or the system default.
  • Per-user — a higher ceiling across all of your Sorties, guarding against one caller fanning out.

A fire that exceeds either limit is rejected and recorded in the fire history as failed with a 429.

Security model

  • Tokens are encrypted at rest with AES-256-GCM, the same scheme used for analytics and extension credentials.
  • The token is decrypted only on the server, only at fire time, and is never returned by any API or surfaced to a client.
  • Every Sortie is scoped to a single site. You can only see and fire Sorties for sites you have access to.
  • Fire history records a payload hash, never the payload contents — payloads may carry secrets of their own.

Related

Want this page as machine-readable markdown? GET /docs/features/sorties.md