Docs
Using your workspace

Blueprints

A blueprint is a reusable recipe for getting something done — research a report, draft a piece, plan a content window. You fork a starter and customize the steps. There's no execution engine: a blueprint is a recipe an LLM reads and walks itself, calling the platform's primitive tools as it goes.

How a blueprint works

Blueprints are render-and-walk. The platform does not run them — there is no server-side runner that executes steps for you. A blueprint is a recipe: an LLM (the in-app chat copilot, or your own agent over the API or MCP) reads the rendered recipe and walks it step by step, making the actual tool calls. The recipe is the plan; the LLM is the runner.

Today only the manual trigger ships — a human or agent picks up the recipe on demand. Scheduled and event triggers are on the roadmap.

Step kinds

A blueprint is a graph of steps. There are 8 step kinds:

  • tool — call a platform operation with arguments.
  • llm — a prompt at an effort tier (fast / medium / deep / research), mapped to a model per tenant.
  • loop — iterate over a collection; optionally in parallel.
  • branch — if / else on a structured condition (eq / neq / gt / gte / lt / lte / in / is_null, combined with and / or / not).
  • parallel — run child steps concurrently and merge their results (object or array).
  • blueprint — run another blueprint as a sub-step.
  • transform — reshape data with a JSONata expression. No LLM, no tool call — pure data.
  • assert — halt the run if a condition is false.

Sending email to workspace members

A blueprint can email people on your team. There’s no new step kind for it — it’s a plain tool step that calls the notifications.email_member operation. The DSL already treats email_sent and notification as side-effect categories; this is the sender behind them.

It runs autonomously. There’s no human confirmation step in the loop, so an agent walking a recipe can notify a teammate as part of getting the work done.

Sending well is a small loop: look up who you’re allowed to email, send, then confirm it landed. notifications.list_recipients notifications.email_member notifications.list_sends. The two reads bracket the send so an agent picks a real recipient up front and checks the result (and its own remaining cap) at the end — both gated by the notifications:read scope.

Picking a recipient

Before sending, an agent looks up who it can email with notifications.list_recipients. It returns the workspace’s addressable members — each a { user_id, email, display_name }— so the agent chooses a member email that email_member will actually accept, instead of guessing an address. This is a narrow recipient picker, not a full team roster: it answers “who can I email?” and nothing more.

  • Over MCP. Read the notification_recipient://list resource.
  • Over the API. GET /notifications/recipients.

Confirming a send landed (and staying under cap)

After sending, notifications.list_sends returns recent sends so an agent can confirm the email landed. Narrow the history with limit, recipient_email, blueprint_run_id, and sincefilters — for example, fetch the sends for the current run to verify each teammate was notified exactly once.

Each response also carries a summary of { sent_last_hour, cap_per_hour, cap_per_run }. An autonomous agent reads this before a send to self-check it’s under the per-hour and per-run caps, so it backs off on its own rather than firing into a rejection.

  • Over MCP. Read the notification_sends://list resource.
  • Over the API. GET /notifications/sends.

Members only, no external addresses

The recipient must be a current member of the workspace, identified by their member email. Free-text or external email addresses are rejected— you cannot use this to mail someone outside the workspace. If a member is removed, they stop being a valid recipient.

Caps and idempotency

Sends are bounded by a per-business and per-run cap, so a runaway recipe can’t blast your team — the same caps the summary on notifications.list_sends reports, so an agent can see how much headroom it has left before it sends. Sends are also idempotent— a retried step won’t deliver the same email twice.

Where it’s available

  • Over the API. notifications.email_member is a unified operation, so it’s callable over the REST / HTTP API like any other operation (find it in the /api/platform/v1/operations catalog). The two reads sit alongside it at GET /notifications/recipients and GET /notifications/sends.
  • From an MCP agent. It’s exposed as a notifications coarse tool with an email_member action, so MCP clients (Claude Desktop, Cursor) can call it too. The recipient picker and send history are reachable as the notification_recipient://list and notification_sends://list resources.
  • From a blueprint. Add a tool step that calls notifications.email_member.

Sending is gated by the notifications:write scope, which is on the MCP customer-agent bundle and the admin role tier; the recipient and send-history reads are gated by notifications:read.

What works today

Email works whenever an agent or API caller is in the loop. Because blueprints are render-and-walk (see above), the calling LLM walks the rendered recipe and makes the notifications.email_member call itself — so a recipe that emails a teammate runs fine when you start it from chat or over the API. Fully unattended, scheduled email — a cron firing a blueprint with no LLM in the loop — is not available yet. That waits on the platform-side blueprint runner (a later wave), the same dependency as the scheduled and event triggers noted above.

Starters

Amdahl ships 6 starter blueprints — battle-tested recipes you fork into your workspace and customize:

  • bootstrap_workspace — get a fresh workspace ready.
  • draft_piece — research and draft a single content piece.
  • plan_and_draft_window — plan a content window and draft across it.
  • multi_persona_social_launch — a coordinated social launch across personas.
  • research_report — produce a researched, cited report.
  • substack_thought_leader_newsletter — a thought-leadership newsletter.

You forka starter to customize it — forks land in your workspace as a fresh draft you own. There’s no in-app step editor; authoring is done by handing the recipe off to an LLM (in chat or over MCP) that writes and validates the blueprint for you.

In the app

Open Blueprints from the sidebar. The list has two groups: Your blueprints (the ones your workspace owns) and Blueprints from Amdahl (the starters), each with a Fork button. Open any blueprint to see a read-only canvas of its step graph — the tool, llm, branch, and loop steps laid out so you can read the recipe end to end.

Draft a content pieceStarterFork
toolPull research
llmWrite the draft
branchLong enough?

Over the API

Blueprints are authored over REST under /api/platform/v1. There is no run endpoint — the platform does not execute recipes; an LLM reads the recipe and walks it itself. Authenticate with the X-API-Key header (see Using the API).

Author a blueprint

Create, update, and delete recipes under /agent-blueprints, fork a starter, and dry-run-validate a body before you save it.

  • GET /agent-blueprints / GET /agent-blueprints/:id — browse and read recipes.
  • POST /agent-blueprints — create a blueprint.
  • PATCH /agent-blueprints/:id — update one.
  • DELETE /agent-blueprints/:id — archive one.
  • POST /agent-blueprints/:id/unarchive — restore one.
  • POST /agent-blueprints/fork — fork a starter into your workspace.
  • POST /agent-blueprints/validate — validate a body without saving (catches bad step references, cycles, and tool-allowlist typos).
bash
# Validate a blueprint body before saving it
curl https://app.amdahl.co/api/platform/v1/agent-blueprints/validate \
  -H "X-API-Key: amdahl_sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "identity": { "slug": "weekly-digest" }, "steps": [] }'

Not sure of the exact route or input shape? Call /api/platform/v1/operations — it returns the catalog of every operation your key can call, each with its JSON schema.

From an MCP agent

Over MCP, blueprints are reachable through the blueprints coarse tool — for authoring and discovery. Its actions:

  • list / get — browse and read recipes (starters and your own).
  • validate — dry-run a body.
  • describe_step_kinds / list_prompt_fragments — introspect what the DSL offers.
  • create / update / delete / unarchive — author recipes.
  • fork — fork a starter into the workspace.

You can also read a recipe directly via the agent_blueprint:// resource scheme.

There is no “run” tool anywhere.Because a blueprint is render-and-walk, an agent doesn’t need one — it reads the recipe and calls the primitive tools itself, which is exactly what walking a blueprint is. The platform never runs a recipe for you, on MCP or REST; it stores, authors, validates, and serves recipes, and the LLM does the walking.