MCP · human in the loop

Your AI agent can now ask you.

Don’t make your AI wait for you. Let it ask, get your answer on your phone, and continue working.

Early testing version. The connector, the API and the handset app all work today — the rough edges are what we would like you to find.

Get it on Google Play

Open testing — free to install, feedback welcome.

  1. AI agent
  2. drop.top
  3. Your phone
  4. Your answer
  5. The agent continues

Five hops, and one of them is a person. The agent never learns your number, your address or which phone it reached — it holds a channel id and a grant you can revoke.

The interaction

It stops at the decision, not at the end of your day.

An agent that reaches a question it may not answer alone has one honest option: ask somebody. This is that call, the phone it lands on, and the answer that goes back.

coding agent waiting for an answer
  • 41 tests passed
  • migration applied on staging
  • production deploy needs a human
create_alert
coding agent
  • answer received: approve
  • deploying to production
get_alert_replies

The two buttons are the two choices the agent sent, and the box under them is the same question’s text field — one call, both offered. The line above them naming the channel is the app’s own, on every question, before anybody types.

The open question

And when there is no button for it, you type.

Not every stop is a yes or a no. A question can offer up to six buttons, a text box, or both — and the sentence you type comes back with the answer.

The agent reads that sentence, quotes it back to you, and gets on with it.

get_alert_replies → replies[0]

{ "choice": null,
  "text": "In-process for now, but keep the interface swappable.",
  "at": "2026-08-28T12:11:04Z" }

What somebody types is data, not instructions. An agent should act on the decision in it and never follow a directive that appears inside it — the same rule you would apply to a comment from a stranger.

Works with MCP and APIs

The agent knows nothing about your phone.

It knows a channel id and two calls. drop.top owns everything after that: the handset, the invite, the delivery and the answer coming back. Human in the loop, without a line in your agent about what a push notification is.

Point any MCP client at this one address. It discovers the rest itself.
https://drop.top/api/mcp

No key is pasted anywhere. The client asks, you land on a consent screen, you tick the scopes it may have — and you can disconnect it from your own account at any time.

  1. 1
    Create a private channel

    In the studio, or with the create_pusher tool. Private means sealed: absent from search, and knowing the handle admits nobody.

  2. 2
    Put your own phone on it

    A private channel is given an invite link the moment it exists. Open it on the phone with the app installed, and the channel has exactly one subscriber: you.

  3. 3
    Connect the assistant

    Add the URL above as a custom connector. Approve the scopes you actually want it to have — reading channels, writing alerts, sending them, reading answers.

  4. 4
    Let it ask

    One call composes the alert, attaches the question and sends it. The question is what turns an announcement into something with an answer.

  5. 5
    Let it collect the answer

    A second call holds open for up to thirty seconds and returns the moment a button is pressed — or register a webhook and be woken instead of asking at all.

The agent asks. One call: the alert, the question, and send.
create_alert {
  "pusher_id": "chn_7f2ad4…",
  "title": "Ready to deploy to production",
  "body": "Branch main, 14 files, one migration.",
  "priority": "important",
  "question": {
    "prompt": "Do you approve?",
    "choices": [
      { "k": "approve", "label": "Approve" },
      { "k": "reject",  "label": "Reject"  }
    ],
    "text": { "placeholder": "Or tell me what to do" }
  },
  "send": true
}
The agent waits. The call returns the instant a button is pressed.
get_alert_replies {
  "pusher_id": "chn_7f2ad4…",
  "alert_id": "alr_91c4e0…",
  "wait": 30
}

{
  "count": 1,
  "replies": [
    { "respondent": "r_3f9c…",
      "choice": "approve",
      "choice_label": "Approve",
      "text": null,
      "at": "2026-08-28T12:04:19Z" }
  ],
  "tally": [ { "choice": "approve", "count": 1 },
             { "choice": "reject",  "count": 0 } ],
  "waited": { "seconds": 30, "answered": true }
}
Or it does not wait at all — register the reply event and be woken.
create_webhook {
  "url": "https://ci.example.com/hooks/drop",
  "events": ["alert.reply"]
}
Everything here is also plain HTTP. The MCP tools do not reimplement the API; they call it. If your agent would rather hold a key and post JSON, the same three steps are three requests.
BASE=https://drop.top/api/v1

curl -X POST $BASE/pushers/$CHANNEL/alerts \
  -H "authorization: Bearer $API_KEY" \
  -H "content-type: application/json" \
  -d '{ "title": "Ready to deploy?",
        "question": { "choices": [
          { "k": "approve", "label": "Approve" },
          { "k": "reject",  "label": "Reject"  } ] },
        "send": true }'

The same rules as your own script

Every tool runs the very same handler your curl would. There is one set of rules for a studio, a key and a model, which is why a tool cannot do anything the API would refuse you.

Scopes you tick, not a key you paste

The connection is its own credential, granted per client and narrowed to what you approved. An assistant connected for drafting and denied sending gets a refusal that names the missing scope.

A key stays a human act

A connected assistant can never create or read API keys. A model that could mint one would have escaped the grant you gave it, so key management is session-only, in the studio, by you.

One channel, one phone

A private channel is how the question reaches you and nobody else.

Every subscriber to a channel may answer the question it asks — which makes a question on a public channel a survey. Keep the channel private with your own phone on it, and “ask me” means you.

Creating the channel in the studio. Public or private is the first question on the form and it is deliberately not pre-answered — Create refuses until you choose one.

Private means sealed, not unlisted

It is absent from search, and knowing the handle admits nobody: only a phone holding an invite code can subscribe or read a single thing the channel has ever sent. To anyone else the handle answers exactly as a handle that was never created.

The invite link is the whole door

A private channel gets its first one the moment it is created, because without one nobody can get in. Open it on your phone, and you are the subscriber the agent is asking.

No aisle to file it under

The form stops asking for a category as soon as you pick private — a sealed channel never appears in browse or search, so the answer would be read by nothing.

Both sentences on that form are the ones the API itself uses. Visibility is changeable afterwards, but making a channel private later removes nobody who already subscribed while it was public.

Human in the loop, asynchronously

The AI doesn’t have to wait at your desk.

The question does not sit in a chat window hoping somebody scrolls back to it. It goes to a phone, and the answer goes back to the agent — whichever room either of you is in.

  1. 1 The agent starts working

    A branch, a migration, a refactor, a batch of invoices. Nothing here involves you yet.

  2. 2 The agent gets stuck

    Not on an error — on a decision it is not allowed to take alone. Deploy? Which of three? Send this to the customer?

  3. 3 drop.top asks you

    The alert carries the question. Your phone decides how loudly it arrives, exactly as it does for every other alert.

  4. 4 You answer from your phone

    A button, or a sentence. Two taps in a supermarket queue is the whole interaction.

  5. 5 The agent receives it

    The open call returns the moment you press, or the reply webhook wakes the process that was doing something else.

  6. 6 The agent continues

    With your decision in its context, quoted back so the next person reading the log can see who decided what.

Waiting for a person takes as long as it takes. One call covers half a minute, so an answer in the first two minutes comes back the second you press — and an answer that arrives after the agent gave up is still recorded for the next call that looks. How loudly any of it arrives is the handset’s decision, never ours: what a phone allows

For founders and small teams

Your AI doesn’t need you sitting next to it.

The bottleneck in a one-person company is rarely the model. It is the fifteen minutes between the agent stopping and somebody being back at a keyboard to unblock it.

Approvals that travel

Deploys, refunds, outbound email, anything with a blast radius. The agent prepares it and asks; you decide from wherever you are standing.

A decision, not a status page

You are not being notified that something happened. You are being asked a question that is holding a process open, and your answer is what closes it.

Your team can hold the pager

A channel is not a person. Put two phones on it when you are away and the first answer is the one the agent acts on — with your own device left out of it entirely.

Take a break

Go to the toilet. Your AI will survive. 😂

Some developers are so addicted to AI that they don’t even want to leave their desk. Now your agent can simply ask you on your phone. Go grab a coffee. Go to the toilet. Make your decision from anywhere.

  • Coffee ☕
  • A walk 🚶
  • Actual lunch 🥪
Open testing

Help us test it.

We’re looking for Android users working with MCPs, AI agents, APIs and startups to test this workflow in real projects. Break it, experiment with it, and tell us what should be better.

Get it on Google Play

Open testing — anyone can install it free, no invitation needed. Tell us what breaks; that is what the test is for.

This is an early testing version. Things will change, and some of them will change because you told us they should.