Skip to main content
Glama

Send Push Notification

send_notification
Destructive

Send a one-way push notification to the user's phone and browser. Nothing is awaited; use ask_user instead when you need an answer back. Reach for this when a long-running task finishes and the user asked to be told, when the agent hits an error it cannot resolve on its own, or for any "notify me when my agent needs me" moment while the user is away from the terminal. By default the notification reaches every device connected to the site; narrow delivery with subscriberIds, externalIds, or tags. The optional context object turns the tap-through into a rich detail page (summary, bullet details, changed files, error info, next steps), and context.askQuestion embeds a decision prompt on that page, returning a linkedCorrelationId you can poll with wait_for_answer. Returns per-channel delivery counts for web and mobile, plus a warning when zero devices are connected. Works from Claude Code, Codex, Cursor, Hermes, or any MCP client; no Claude subscription is required. SIDE EFFECT: delivers real notifications to real devices immediately.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
envNoSet to "test" from a test suite. The notification is recorded in the activity feed and nothing is delivered to a phone or browser. The X-Pushary-Env: test header does the same for every call on the connection.
urlNoURL opened when the user taps the notification. Ignored if context is provided, because a context detail page URL is generated automatically.
bodyYesNotification body text (max 500 chars). One or two sentences the user can act on without opening anything.
tagsNoDeliver only to subscribers that have any of these tags.
titleYesNotification title shown on the lock screen (max 100 chars). Lead with the outcome, e.g. "Build finished" or "Migration failed".
contextNoStructured context rendered as a rich detail page when the user taps the notification. Strongly recommended for task_complete and error notifications so the user can act from their phone.
iconUrlNoURL of the notification icon image
imageUrlNoURL of a large image shown in the notification
agentNameNoName of the agent sending this notification, format "{Agent} - {project}" (e.g. "Claude Code - myproject"). Shown in the notification so the user knows which session is talking. Falls back to the MCP client name if omitted.
machineIdNoStable machine id of the sending agent, so two machines never collapse into one session.
sessionIdNoOpaque per-session id of the sending agent, so parallel sessions are attributed separately in the activity feed.
externalIdsNoDeliver only to subscribers matching these external IDs.
subscriberIdsNoDeliver only to these subscriber IDs. Omit all targeting fields to reach every connected device.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
envNoEchoed when the call was test traffic.
hintNoWhat to do next, when there is a next step.
sentNoTotal devices reached, web plus mobile. Zero is a successful call that found nobody to deliver to, not an error.
warningNoPresent only when the notification reached zero devices, naming what the user has to connect.
deliveryNoPer-channel outcome. The two channels are independent with no cross-fallback, so each reports its own result.
linkedCorrelationIdNoPresent only when context.askQuestion embedded a decision prompt. Pass it to wait_for_answer to collect the response.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed2 schema fields changed
    • addedInput schema / properties / env
      Added value: +{
      +  "description": "Set to \"test\" from a test suite. The notification is recorded in the activity feed and nothing is delivered to a phone or browser. The X-Pushary-Env: test header does the same for every call on the connection.",
      +  "enum": [
      +    "test"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / env
      Added value: +{
      +  "description": "Echoed when the call was test traffic.",
      +  "enum": [
      +    "test"
      +  ],
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "delivery": {
      +      "additionalProperties": false,
      +      "description": "Per-channel outcome. The two channels are independent with no cross-fallback, so each reports its own result.",
      +      "properties": {
      +        "mobile": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "recipients": {
      +              "description": "Phones that accepted the push.",
      +              "type": "number"
      +            },
      +            "status": {
      +              "description": "Why mobile delivery reached nobody, present only when it reached nobody.",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "recipients"
      +          ],
      +          "type": "object"
      +        },
      +        "web": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "recipients": {
      +              "description": "Browsers that accepted the push.",
      +              "type": "number"
      +            },
      +            "status": {
      +              "description": "Why web delivery reached nobody, present only when it reached nobody.",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "recipients"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "web",
      +        "mobile"
      +      ],
      +      "type": "object"
      +    },
      +    "hint": {
      +      "description": "What to do next, when there is a next step.",
      +      "type": "string"
      +    },
      +    "linkedCorrelationId": {
      +      "description": "Present only when context.askQuestion embedded a decision prompt. Pass it to wait_for_answer to collect the response.",
      +      "type": "string"
      +    },
      +    "sent": {
      +      "description": "Total devices reached, web plus mobile. Zero is a successful call that found nobody to deliver to, not an error.",
      +      "type": "number"
      +    },
      +    "warning": {
      +      "description": "Present only when the notification reached zero devices, naming what the user has to connect.",
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  3. First observed

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explicitly states the side effect: 'SIDE EFFECT: delivers real notifications to real devices immediately.' It also explains that nothing is awaited, narrows delivery options, warns about zero connected devices, and notes that context.askQuestion returns a linkedCorrelationId that can be polled. The annotations already say destructiveHint=true, but the description goes far beyond that with concrete behavioral details. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is packed with valuable information, but it's a bit long and could be more tightly organized. The opening sentence, the SIDE EFFECT warning, and the when-to-use guidance are all front-loaded. The middle section about targeting and context is dense but deserves its place. It could be slightly trimmed, but it earns its length with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 13 parameters, nested objects, and a rich sibling set, yet the description covers everything an agent needs to invoke it correctly: the use cases, the delivery options, the context structure, the side effect, the return value hints (per-channel counts and warnings), and the relationship to siblings. The output schema exists but the description still clarifies semantics like what happens when url is ignored or what askQuestion returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all parameters thoroughly. The description adds some context about the purpose of context objects and delivery targeting, but the schema still carries the heavy lifting. For example, the schema already explains env: 'test' and context.askQuestion. The description adds the overall targeting semantics and the linkedCorrelationId flow, which helps, but baseline 3 is appropriate since the schema is complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: sending a one-way push notification to the user's phone and browser. It explicitly distinguishes it from ask_user, saying 'Nothing is awaited; use ask_user instead when you need an answer back.' It also has a clear SIDE EFFECT warning. This is a specific verb+resource+scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: when a long-running task finishes and the user asked to be told, when the agent hits an error it cannot resolve alone, or any 'notify me when my agent needs me' moment. It also gives an explicit exclusion: use ask_user when you need an answer back, and wait_for_answer for polling the linkedCorrelationId. This is exemplary usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.6/5.0
Disambiguation5/5

Each tool has a clearly distinct responsibility: ask_user blocks for an answer, wait_for_answer polls an existing question, cancel_question retracts a pending one, send_notification is one-way, and propose_scope handles a specific scope-ratification workflow. Even though propose_scope is a form of asking, its contract-enforcement semantics are clearly separated from a general ask_user call.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: ask_user, cancel_question, propose_scope, send_notification, wait_for_answer. The naming is predictable and makes the action and target of each tool immediately clear.

Tool Count5/5

Five tools is well-scoped for a push-notification and user-question server. Each tool covers a distinct part of the interaction lifecycle without redundant or filler operations.

Completeness4/5

The core lifecycle is well covered: create a question, wait for an answer, cancel a stale question, send a one-way notification, and propose a scope contract. A minor gap is the lack of a way to list or inspect all pending questions, though wait_for_answer and cancel_question handle the primary workflows adequately.

Resources