Human-in-the-loop for the Claude Agent SDK

Human-in-the-loop for the Claude Agent SDK, in one config block.

Add the hosted Pushary MCP server to the mcpServers option of query() and allow its tools. The agent can then put a question on a phone with ask_user and hold for the reply with wait_for_answer, with nothing else to install. For agents you ship to your own users, the Partner plan adds enroll_end_user and create_decision as MCP tools, or call decisions.ask from @pushary/server inside a custom tool so each user answers about their own action.

No install. One mcpServers entry.two calls
import { query } from "@anthropic-ai/claude-agent-sdk"

for await (const message of query({
  prompt: "Clean up stale feature flags. Ask before deleting anything.",
  options: {
    mcpServers: {
      pushary: {
        type: "http",
        url: "https://pushary.com/api/mcp/mcp",
        headers: { Authorization: `Bearer ${process.env.PUSHARY_API_KEY}` },
      },
    },
    allowedTools: [
      "mcp__pushary__ask_user",
      "mcp__pushary__wait_for_answer",
      "mcp__pushary__send_notification",
    ],
  },
})) {
  if (message.type === "result") console.log(message)
}

Why you need it

Claude Agent SDK pauses the agent. Pushary reaches the human.

The Claude Agent SDK runs the loop, the tools, and the permissions, and it has no channel to you once you close the laptop. The Pushary server adds ask-a-human and notify as MCP tools the model can call mid run. The Python SDK works the same way through ClaudeAgentOptions(mcp_servers={...}).

How it works

From ask to resume

Connect the phone once, then ask a human from the tool or step that guards the action. The waiting, the delivery, and the record are handled for you.

  1. 01

    Add the mcpServers entry

    Put the hosted Pushary server in the mcpServers option of query() with your API key as a Bearer token.

  2. 02

    Allow the tools

    Add mcp__pushary__ask_user, mcp__pushary__wait_for_answer, and mcp__pushary__send_notification to allowedTools.

  3. 03

    Tell the agent when to ask

    In the prompt or system prompt, say which actions need a human first. The model calls ask_user at that step and holds for the reply.

  4. 04

    Reach your own users when you ship

    When the agent serves your own product's users, allow the Partner-plan tools (mcp__pushary__enroll_end_user, mcp__pushary__create_decision, mcp__pushary__get_decision) so the decision goes durably to the right person, or call decisions.ask from @pushary/server inside a custom tool.

A decision is a yes or no confirm, a multiple-choice select, or a free-text input. Every one is stored with its outcome and kept in the audit log.

For your users

Your agent asks your users, not just you

Ship the agent to real users and let each of them approve their own decisions from their phone, under your brand.

Your users answer on their own phones

The externalId is your own id for the end-user. Connect their phone once with a keyless one-tap link, and every approval lands with the right person. No account, no app, no key on their side.

Durable, fail-closed waits

The agent stays open on a durable wait backed by a decisions ledger. If nobody answers in the window you set, the decision comes back denied, so a timeout or a restart never turns into an unapproved action.

Phone-first delivery

Pushary reaches the person on the device they carry: native app push first, then PWA push notifications, then Slack if you route it there. You do not build a delivery pipeline.

Signed webhooks and an audit trail

Every decision is written to a durable ledger you can query and export, and resolved decisions post a signed webhook to your callback URL. You have the record of who approved what and when.

FAQ

Questions, answered

Human-in-the-loop for other frameworks

Let your Claude Agent SDK agent ask a human.

Connect a user with one tap, ask a human with one call, and act on a fail-closed decision. The durable store and the audit log come with it.

Partner plan, $99 a month. Your users never see a Pushary login or bill.