Median

How tool calls run

Syncs, calls, approvals, reviews and teammate runs, as your endpoint sees them.

Updated Oct 1, 202610 minute read

Sync

Median keeps a copy of each endpoint's manifest. The agent and your team only see tools from the last successful sync.

When a sync runs

TriggerFromRate limit
Connecting an endpoint or changing its URLOpening the route with Authorization: Bearer $MEDIAN_KEY, Add endpoint or Change endpoint on Agent → Tools, median tools endpoint add <url>, PUT /v1/tool-endpointsNo sync limit. Over the API, the request counts toward rate limits
A new conversationRuns before the agent's first reply. Every endpoint syncs in parallelNone
Asking for oneSync in the menu at the end of the endpoint's row, median tools endpoint sync, POST /v1/tool-endpoints/sync, POST /v1/tools/sync on the management API60 an hour per organization, bursts of 10

A deploy needs no hook. The next new conversation picks up the new manifest. Conversations already open use the last stored sync until one of the triggers above runs. Over the rate limit, a sync fails with rate_limited and "Too many requests. Wait a moment and try again."

Each sync times out after 10 seconds. The first reply waits for it, so an endpoint that never answers delays the first reply of every new conversation.

What a sync changes

Manifest changeResult
New toolAdded and switched on
Same name as beforeDescription, risk and input updated. The on or off switch stays as it was
Changed description or inputThe label and summary on Agent → Tools are written again
Tool left outDeleted. A request for it that is approved later fails with "The tool is no longer available."
Tool renamedTreated as a deleted tool plus a new one, switched on
Sync failsThe last good tool set stays in use. The endpoint row shows Sync failed: and the reason

Failure reasons and fixes are in Tool errors.

A tool you switch off on Agent → Tools or with median tools disable <name> leaves the agent's next turn and your team's run lists. A request for it that is approved later fails with "The tool is no longer available."

Remove endpoint deletes the endpoint's tools. Requests waiting on them expire, with a line in each thread.

One call

The agent sends low and medium calls straight to your endpoint as a signed POST. median() verifies the signature, validates the input and runs execute.

POST body
{
  "tool": "orderStatus",
  "toolCallId": "call_9f2c41d07b3e4a6f8c1d2e3f4a5b6c7d",
  "input": { "orderNumber": "ORD-1042" },
  "context": {
    "conversationId": "k57c2x9vx8p4q1m0z3b6n7r2hd6s8t4w",
    "risk": "low",
    "visitor": { "verified": true, "externalId": "user_123", "email": "ana@example.com" }
  }
}
RuleValue
Signature headermedian-signature: t=<ms>,v1=<hex>. v1 is the HMAC-SHA256 of the timestamp, a period and the raw body
Timeout10 seconds
RedirectsNever followed
Response body100 KB. A larger answer fails the call
Result the agent readsFirst 4,000 characters

Tools run in every channel: the widget, email and Discord. The wire format is in the tool endpoint reference. What execute receives and may return is in the config reference.

Per turn

A turn is one reply from the agent.

RuleDetail
3 calls per turnCounts low and medium calls sent to your endpoints. After the third, the agent answers with what it has or hands off
Identical callsThe same tool with the same input is sent once per turn. The agent reuses the first result
One tool at a timeCalls to one tool run in order. Calls to different tools can run in parallel
Pages and highlightsA tool whose result offered a page or highlighted something does not run again that turn. See Pages and highlights
high and reviewedNot sent. Each becomes a request and does not count toward the 3

What each risk adds to your description

Median appends a line to the description the agent reads.

RiskAppended line
lowNone
medium"Only call this after the customer has explicitly said yes to doing it, in this conversation."
reviewedThe medium line, plus a line saying a reviewer checks the call first
highA line saying the call asks a teammate to sign off first

Do not write these lines into your own descriptions.

:::warning medium is an instruction to the agent. No code checks for the customer's yes, and the call runs as soon as the agent makes it. Use reviewed or high when a wrong call costs you something. See risk levels. :::

Approvals

A high or reviewed call does not reach your endpoint. Median records a request, and the agent tells the customer the call needs sign-off or is being checked.

StatusMeaning
reviewingA reviewed call the reviewer is reading
pendingWaiting on a teammate
executingApproved. The call is out at your endpoint
succeededYour endpoint answered
failedThe call failed, the tool was switched off or removed, or the hourly check found no result 10 minutes after approval
deniedA teammate or the reviewer said no
expiredUnanswered for 24 hours, its endpoint was removed, or its conversation was resolved, closed or archived while it waited

median tools approvals and GET /v1/tool-approvals return these statuses.

Rules

  • One open request per tool per conversation. When the agent asks again, it is told the request is still waiting and says so to the customer.
  • 3 open requests per conversation. Open means reviewing, pending or executing.
  • An unanswered request expires after 24 hours, at the moment it runs out.
  • Only a request on an open conversation can be decided. Resolving, closing or archiving the conversation expires its open requests, and deciding one then fails with "This request expired because the conversation ended."
  • A request is decided once. A second decision fails with "This request has already been reviewed."
  • An approved call runs once. If it never reports back, the hourly check fails it once 10 minutes have passed, with "The tool returned no result. Check whether the action completed before retrying."
  • After a denial, or once an approved call finishes, the agent gets a turn to tell the customer, if it is still handling the conversation. If a teammate holds the conversation, the outcome waits until it is handed back. An expired request does not wake the agent.

Where teammates decide

Any member can approve or deny.

WhereHow
InboxApprove and run or Deny on the request card in the thread. See Approvals and tool runs
Slack and DiscordApprove and Deny buttons in the mirrored thread, for linked accounts. See Work from Slack and Discord
AssistantAsk it in the app, the command palette, Slack or Discord. It waits for your confirmation before it decides. See Assistant
CLImedian tools approvals, median tools approve <id>, median tools deny <id>, median tools status <id>. See CLI reference
API and MCPGET /v1/tool-approvals, POST /v1/tool-approvals/{id}/approve, POST /v1/tool-approvals/{id}/deny. See the management API

Slack and Discord alerts go out for high requests and for reviewed requests passed to your team.

Reviewed calls

A reviewed call waits for the customer's yes, then for a reviewer. The reviewer is a second AI model that stands in for the teammate a high call would wait on.

It reads:

  • The tool's name, description and input schema, and the exact input
  • Whether your server verified the customer, and their id
  • The name, email and page details the customer or page gave
  • What earlier conversations taught about the customer
  • Your team's notes on the conversation
  • Every other tool call in the conversation
  • The whole transcript, with pictures the customer attached

It approves only when the customer said yes to this exact action, the call acts on the customer's own account or data, the input matches what was discussed, no note says otherwise, and nothing in the conversation reads like someone steering the agent. An unverified customer is not approved for a call that needs to know who they are.

It escalates when it cannot tell from what it was given, or when the call is unusual:

  • An amount far larger than the conversation explains
  • The same request over and over
  • A customer who seems to be testing the agent
  • A tool it does not understand

After an escalation or no verdict, the conversation turns unread. If the agent still handles the conversation, it tells the customer a teammate has to approve the call.

VerdictResultLine in the thread
ApproveRuns. approvedBy is "The reviewer"The reviewer approved running <tool>
DenyDenied. The card shows the reason. The agent tells the customer it cannot be doneThe reviewer declined <agent>'s request to run <tool>
EscalateMoves to pending for your team. The card shows the reasonThe reviewer passed <tool> to the team
No verdictMoves to pending. Covers a failed review, no decision, and a review past 5 minutes<tool> could not be reviewed, so it is with the team

The customer never sees the reviewer's reason. A teammate can approve or deny while the reviewer is still reading. The teammate's decision wins and the verdict is dropped.

Run a tool yourself

A teammate can run any switched-on tool on a conversation, at any risk level, with no sign-off.

WhereHow
InboxTools in the panel beside the thread, or / in the composer. See Approvals and tool runs
Slack and Discord/actions. See Work from Slack and Discord
AssistantAsk it. It waits for your confirmation before it runs the tool
CLImedian tools run <conversation> <tool> --input '{"orderNumber":"ORD-1042"}'
API and MCPPOST /v1/conversations/{id}/tools/run with { "tool", "input" }. GET /v1/conversations/{id}/tools lists what can run
  • Median checks the input against the tool's schema first. Errors name the field, like "orderNumber is needed to run this."
  • At most 3 runs are in flight per conversation. The fourth fails with "Three tools are already running in this conversation. Wait for one to finish."
  • Archived conversations refuse with "Move this conversation out of the archive before running a tool." Resolved and closed conversations allow runs.
  • The agent is not told. It gets no turn from the run and never sees the result. The result shows on the run's card in the thread.
  • The exception is a run that never reports back. Once 10 minutes have passed, the hourly check fails it, adds "<tool> did not run: the call never reported back" to the thread, marks the conversation unread and can start an agent turn.

What your endpoint receives

PathapprovedBytoolCallId
The agent calls a low or medium toolAbsentcall_ and 32 hex characters
A teammate approves a requestThe teammate's name, or "A teammate"The request id
The reviewer approves a request"The reviewer"The request id
A request is approved with a Median key over the API"the API"The request id
A teammate runs a toolThe teammate's name, or "the API" for a keyThe run id
median tools test"A test from the CLI"test_ and a UUID
You ask Median support to test a tool"Median support"test_ and a UUID

context.risk is always the tool's own risk. Treat toolCallId as opaque. A second request for the same action gets a new id, so check your own state before acting twice. Tests with no --conversation send the test_ id as conversationId too. See Custom tools for median tools test.

Roles

ActionMemberAdmin and Owner
See the tool list on Agent → ToolsRead onlyYes
See endpoints on Agent → ToolsNoYes
Read endpoints with median tools list or GET /v1/tool-endpointsYesYes
Add, change, sync and remove endpointsNoYes
Switch tools on or offNoYes
Approve or deny requestsYesYes
Run a tool on a conversationYesYes
median tools testNoYes
See and settle Suggested toolsNoYes
See tool events on LogsNoYes

The full matrix is in roles.

Limits

LimitValue
Tool endpoints per organization10
Tools per organization, across endpoints20
Endpoint URL512 characters. HTTPS, or HTTP on localhost and 127.0.0.1
Tool and field namesA letter, then letters, numbers and underscores, up to 64 characters
Description500 characters
Input fields per tool20 flat scalars
Input schema8,000 characters, serialized
Manifest500 KB
Sync timeout10 seconds
Manual syncs60 an hour per organization, bursts of 10
Call timeout10 seconds
Response body100 KB. A larger answer fails the call
Result the agent readsFirst 4,000 characters
Calls sent per agent turn3
Open requests per conversation3
Open requests per tool per conversation1
Request lifetime24 hours
Review time5 minutes, then your team
Approved call or teammate run with no resultFailed at the first hourly check after 10 minutes
Teammate runs in flight per conversation3
Signature tolerance5 minutes by default

API rate limits for the CLI and API paths are in rate limits.

Logs

Tool events appear on Logs under the Tools type.

EventLogged when
Tool callMedian sends a call to your endpoint: the agent's, an approved request, a teammate run or a test. Carries the outcome, error and duration
Approval requestedThe agent asks for sign-off or a review, or the reviewer passes a call to your team
Tool call approvedA teammate, a key or the reviewer approves a request
Tool call declinedA teammate, a key or the reviewer denies a request
Approval expiredA request goes unanswered for 24 hours, its conversation ends, or its endpoint is removed
Tools syncedA sync finishes or fails. A failure repeating the last error is not logged again
Tool endpoint changedAn endpoint is added, moved or removed
Tool switched on or offA tool's switch changes
Tool suggestedThe agent or a resolved-conversation review files a suggested tool

Still need help?

    Esc