Skip to main content
Glama

πŸ”” PushNotif MCP Server (pushnotif-mcp-server)

Listed on mcpservers.org AllMCPs Verified AgentShield Security

MCP Protocol Node.js License: MIT

Official open-source Model Context Protocol (MCP) Server implementation for PushNotif.biz.id β€” allowing AI coding assistants (Claude Desktop, Claude Code, Cursor, Windsurf, Cline, and Glama) to register accounts, generate SDK snippets, broadcast Web Push (VAPID) & Mobile Push (Android FCM / iOS APNs), configure In-App Popup Banners, Social Proof Toasts, Transactional Email OTP, and manage QRIS credits.


πŸ“¦ Repository Architecture (Open-Source MCP Server Implementation)

This repository contains the complete, runnable MCP Server implementation built on @modelcontextprotocol/sdk:

  • src/index.js β€” Full Stdio MCP Server implementation (@modelcontextprotocol/sdk) exposing all 19 PushNotif tools (ListToolsRequestSchema & CallToolRequestSchema).

  • Dockerfile β€” Containerized build for Glama.ai automated inspection and local Docker execution.

  • package.json β€” Node.js ES Module package (bin: pushnotif-mcp).

  • glama.json & smithery.yaml β€” Registry metadata manifests.


Related MCP server: BotBell MCP Server

πŸš€ Quick Start (Local Stdio MCP Server)

Option 1: Run via Node.js / npx (Stdio)

Clone and install dependencies:

git clone https://github.com/AarsyDesign/pushnotif-mcp.git
cd pushnotif-mcp
npm install

Add to your claude_desktop_config.json or .cursor/mcp.json:

{
  "mcpServers": {
    "pushnotif": {
      "command": "node",
      "args": ["/absolute/path/to/pushnotif-mcp/src/index.js"],
      "env": {
        "PUSHNOTIF_API_KEY": "pn_live_YOUR_API_KEY_HERE"
      }
    }
  }
}

Option 2: Run via Docker (Stdio)

docker build -t pushnotif-mcp .
docker run -i --rm -e PUSHNOTIF_API_KEY=pn_live_YOUR_API_KEY_HERE pushnotif-mcp

Option 3: Direct Streamable HTTP Endpoint

You can also connect directly via Streamable HTTP at https://pushnotif.biz.id/mcp with Authorization: Bearer pn_live_YOUR_API_KEY_HERE.


πŸ› οΈ Available Tools (19 Full-Lifecycle Tools)

Account Onboarding (No API Key Required)

  1. register_new_account β€” Two-step onboarding to request a 6-digit email OTP or verify the OTP to create a new PushNotif account (+1,000 Free Quota Credits forever), register the first website, and return api_key (pn_live_...).

  2. login_existing_account β€” Authenticate an existing account with email & password to retrieve its api_key and optionally update workspace profile name or password.

Workspace, Web Push, Mobile Push, In-App & Transactional Email Automation

  1. list_apps β€” List all registered websites/apps, active subscriber counts, credit balance, and optional ready-to-paste SDK snippets (html, nextjs, laravel, wordpress, flutter).

  2. create_app β€” Register a new website or mobile app and generate VAPID keys.

  3. update_app_branding β€” Update notification icon URL, automatic Welcome Push message, or upload Firebase FCM Service Account JSON / Apple APNs .p8 credentials.

  4. delete_app β€” Permanently delete a registered application along with its subscribers, campaigns, and logs.

  5. send_push_notification β€” Broadcast instant Web Push (VAPID), Android (FCM), and iOS (APNs) notifications.

  6. schedule_push_notification β€” Schedule one-time or recurring (daily / weekly) push campaigns.

  7. configure_inapp_banner β€” Configure In-App Popup Modals, Top Sticky Bars, or Bottom Slide Cards.

  8. configure_social_toast β€” Configure standalone on-site Live Activity Social Proof Toast popups.

  9. configure_rss_autopush β€” Configure automated 24/7 RSS / Sitemap / Atom feed monitoring and auto-push.

  10. configure_payment_webhook β€” Generate incoming webhook URLs for Midtrans, Xendit, Mayar, Lynk.id, Duitku, Tripay, WooCommerce, and GitHub, or trigger a live test event.

  11. configure_email_automation β€” Configure per-app switches for Automated Transactional Emails (Order Paid Receipt, Welcome Email, Broadcast Mirror) and custom Reply-To.

  12. send_transactional_email β€” Send 1-to-1 transactional emails (otp_code, payment_invoice, order_status, security_alert) via PushNotif's anti-phishing locked templates.

  13. list_subscribers β€” View active subscriber device distribution and segment tags.

  14. update_subscriber_tags β€” Assign, replace, or remove audience segment tags on subscriber devices.

  15. get_campaign_analytics β€” Inspect campaign delivery, click-through rate (CTR), and conversion metrics.

  16. create_qris_invoice β€” Generate a live QRIS payment invoice (starting from Rp 1,000 / 5,000 Credits).

  17. check_billing_and_qris_status β€” Check real-time QRIS payment status (PENDING / PAID), credit ledger history, and downloadable PDF invoices.


πŸ“„ License

MIT License β€” Copyright (c) 2026 PushNotif.biz.id (AarsyDesign)

Available Tools

16 tools
check_billing_and_qris_statusA
Read-onlyIdempotent
Inspect

Check QRIS top-up order payment status (PENDING or PAID), current workspace credit balance, credit mutation ledger history, and official downloadable PDF invoice URLs. Use this tool to verify whether an order from create_qris_invoice has settled or to audit credit consumption; do not use it to generate a new payment invoice (use create_qris_invoice instead) or view campaign click rates (use get_campaign_analytics instead). Read-only operation requiring PUSHNOTIF_API_KEY with 0 credit cost; pass order_id to inspect a single invoice or omit it to list recent orders and ledger entries. Returns JSON { credits_balance, orders: [{ id, amount_rp, credits_added, status, invoice_pdf_url, created_at }], recent_ledger: [{ id, delta, reason, created_at }] }.

NameRequiredDescriptionDefault
order_idNoOptional specific QRIS order ID in format ord_xxxx (from create_qris_invoice) to check; omit to return the latest orders and ledger history

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the annotations, the description adds authentication requirements (PUSHNOTIF_API_KEY), operational cost context (0 credit cost), and the behavioral difference between passing versus omitting order_id. These details materially help an agent invoke the tool correctly.

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

Conciseness5/5

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

The description is dense but front-loaded: purpose, usage routing, operational constraints, parameter behavior, and return shape are all presented without filler. Every sentence contributes to correct tool selection or invocation.

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?

With no output schema, the description compensates by explicitly documenting the JSON return shape, including credits_balance, orders, and recent_ledger. Annotations cover safety behavior, and the single parameter is fully described, leaving no meaningful gap.

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

Parameters4/5

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

Schema coverage is already 100%, so the baseline would be 3. The description adds practical meaning by explaining that order_id inspects a single invoice, while omitting it lists recent orders and ledger entries.

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 uses a specific verb and resource: checking QRIS top-up order payment status, credit balance, ledger history, and invoice URLs. It clearly distinguishes this tool from create_qris_invoice and get_campaign_analytics, so an agent can identify its scope without opening sibling schemas.

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?

It explicitly states when to use the tool: verifying whether an order from create_qris_invoice has settled or auditing credit consumption. It also names two alternatives and when not to use this tool: creating invoices and viewing campaign analytics.

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

configure_inapp_bannerA
Idempotent
Inspect

Configure and publish an on-site In-App Popup or Banner (center modal, top sticky bar, or bottom slide-in toast) rendered inside the website by the PushNotif SDK without requiring browser push permission. Use this tool for visual in-page promos and announcements; do not use it for OS lock-screen notifications (use send_push_notification instead). Prerequisite: call list_apps first to obtain app_id. Requires PUSHNOTIF_API_KEY; saving configuration is idempotent and costs 0 credits, while each live visitor display deducts 1 credit (inapp_trigger controls when the banner firesβ€”such as 'scroll_50' for 50% page scroll or 'event:add_to_cart' for custom DOM eventsβ€”combined with inapp_freq to cap repeat impressions per visitor). Returns JSON { ok, app_id, inapp_enabled, inapp_style, inapp_trigger, inapp_freq }.

NameRequiredDescriptionDefault
app_idYesTarget application ID in format app_xxxx (obtain from list_apps)
inapp_bodyYesBanner supporting message text (1 to 240 characters)
inapp_freqNoPer-visitor frequency cap: 'once_per_session' (default), 'once_per_day', 'cooldown_3h', 'cooldown_12h', 'once_per_week', or 'always'
inapp_styleNoVisual layout: 'modal' (center dialog), 'top_bar' (sticky top ribbon), or 'bottom_slide' (corner slide-in toast)
inapp_titleYesBanner headline text (1 to 100 characters)
inapp_accentNoOptional 6-digit hex color code for the CTA button and accent border (default: '#0058BE')
inapp_cta_urlNoOptional HTTPS destination URL opened when the CTA button is clicked
inapp_enabledNoSet true to publish the banner live on the website, or false to pause it (default: true)
inapp_triggerNoTrigger condition: 'immediate' (default), 'delay_5s', 'delay_10s', 'scroll_50', 'scroll_80', or custom DOM event 'event:<name>'
inapp_cta_textNoOptional CTA button label (must be paired with inapp_cta_url to render a clickable action button)

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already cover non-destructive, idempotent, closed-world, but the description adds the things annotations cannot: the PUSHNOTIF_API_KEY requirement, that saving is free while each live impression costs 1 credit, and the exact JSON shape returned. That is exactly the value-add behavior layer.

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?

Front-loaded with purpose and the sibling exclusion, and every sentence carries information (prerequisite, auth, cost model, return shape). It is dense and somewhat run-on β€” the trigger/frequency parenthetical could be split β€” so not a 5.

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

Completeness4/5

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

For a 10-parameter mutation tool with no output schema, the description supplies the return shape, auth, cost model, idempotency and prerequisite. Gaps are minor: nothing about error behavior (e.g. invalid app_id) or what happens to an already-published banner when inapp_enabled is omitted.

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?

With 100% schema coverage the schema already documents all ten parameters including the trigger and frequency enums, so the baseline is 3. The description does add a little meaning by explaining that inapp_trigger and inapp_freq work together to cap impressions, but most of its parameter prose restates values already in the schema.

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?

States a specific verb (configure/publish) and resource (In-App Popup or Banner) plus the concrete render styles, and explicitly contrasts it with the OS-notification sibling send_push_notification. An agent can distinguish it from every other tool in the sibling list without opening the schema.

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?

Gives both directions: 'use this tool for visual in-page promos and announcements' and 'do not use it for OS lock-screen notifications (use send_push_notification instead)'. It also names a prerequisite (call list_apps first for app_id), which is a routing instruction, not just context.

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

configure_payment_webhookA
Idempotent
Inspect

Generate the ready-to-paste Automated Payment & Order Webhook URL (POST /api/v1/apps/{app_id}/incoming-event) for Midtrans, Xendit, Mayar, Lynk.id, Duitku, Tripay, WooCommerce, and GitHub, or trigger a live test payment/order event when simulate_test=true. Use this tool when connecting a payment gateway or e-commerce store to automatically show a Live Activity Toast and/or broadcast a Web Push notification upon payment settlement; do not use it for RSS blog feeds (use configure_rss_autopush instead) or manual push campaigns (use send_push_notification instead). Prerequisite: call list_apps first to obtain app_id. Requires PUSHNOTIF_API_KEY; generating the webhook URL costs 0 credits, while live or simulated push broadcasts deduct 1 credit per delivered device (toast_only mode costs 0 credits on display). Returns JSON { ok, app_id, mode, webhook_url, supported_platforms, setup_guides, simulation_result }.

NameRequiredDescriptionDefault
modeNoAction when payment/order event arrives: 'both' (default: show Live Activity Toast on website + send Web Push), 'toast_only' (show Live Activity Toast only, 0 credits), or 'push_only' (send Web Push notification only)
app_idYesTarget application ID in format app_xxxx (obtain from list_apps)
platformNoPlatform format to simulate when simulate_test=true: 'midtrans' (default), 'xendit', 'woocommerce', or 'github'
item_nameNoOptional custom product/order name for test simulation (default: 'Paket Premium Rp 149.000')
buyer_nameNoOptional custom buyer name for test simulation (default: 'Budi (Jakarta)')
simulate_testNoSet true to immediately fire a test payment/order webhook event to verify Live Activity Toast and Web Push delivery

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing auth requirements (PUSHNOTIF_API_KEY), the exact cost model (URL generation 0 credits, 1 credit per delivered device for live/simulated broadcasts, toast_only 0 credits), and the response envelope. This is important because annotations mark the tool non-read-only and idempotent but say nothing about side effects or billing.

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?

Front-loaded with the core action and endpoint, then usage, exclusions, prerequisites, costs, and return shape in a logical order. It is dense β€” the opening sentence carries an eight-item platform list and two modes β€” but nearly every clause adds decision-relevant information, with little redundancy.

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?

For a six-parameter mutation tool with a simulated-write path, the description covers everything an agent needs: prerequisite resolution of app_id, auth, cost implications per mode, exclusions to sibling tools, and the returned JSON keys (which substitute for the absent output schema). Nothing material is left unspecified.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real value by tying credit cost to the mode parameter (toast_only costs 0 credits) and by restating app_id's provenance from list_apps. It does not, however, explain how platform and simulate_test interact in the description beyond the schema's own wording.

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?

States a specific verb+resource ("Generate the ready-to-paste Automated Payment & Order Webhook URL") with the exact endpoint path, and lists both operating modes (URL generation vs. simulate_test=true firing a live event). It also names the eight supported platforms, so the agent knows precisely what it produces and for whom.

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?

Explicit affirmative case ("Use this tool when connecting a payment gateway or e-commerce store...") plus two named exclusions routing to siblings: configure_rss_autopush for feeds and send_push_notification for manual campaigns. It also states the prerequisite, call list_apps first to obtain app_id, which prevents the most likely invocation error.

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

configure_rss_autopushA
Idempotent
Inspect

Configure automated 24/7 RSS, Atom, or XML Sitemap polling for an app_id, or trigger an immediate feed check and push broadcast via dispatch_now=true. Use this tool when a blog, news portal, or store wants newly published URLs automatically broadcast as push notifications; do not use it for manual one-off messages (use send_push_notification instead) or fixed-time calendar campaigns (use schedule_push_notification instead). Prerequisite: call list_apps first to obtain app_id. Requires PUSHNOTIF_API_KEY; feed URLs are validated against SSRF rules, deduplicated by item GUID/URL so each post is sent only once, and deduct 1 credit per delivered subscriber when a new item is broadcast (setting dispatch_now=true immediately fetches and broadcasts the newest feed entry even if rss_enabled=false). Returns JSON { ok, app_id, rss_enabled, rss_feed_url, rss_interval, dispatched_now, latest_item_title }.

NameRequiredDescriptionDefault
app_idYesTarget application ID in format app_xxxx (obtain from list_apps)
rss_prefixNoOptional text prepended to each auto-generated notification title (e.g., 'Artikel Baru: ')
rss_enabledNoSet true to enable background RSS/Sitemap polling at rss_interval, or false to pause background polling
dispatch_nowNoSet true to immediately fetch the latest feed entry and broadcast it to active subscribers right now
rss_feed_urlNoPublic HTTPS URL of the RSS 2.0, Atom, or XML Sitemap feed (required when enabling polling or calling dispatch_now=true)
rss_intervalNoBackground polling interval: '5m', '15m', '30m' (default), '1h', '3h', or 'daily_digest'

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly=false, idempotent=true, destructive=false, openWorldHint=true, so the description's added context is the differentiator: SSRF URL validation, GUID/URL deduplication so each post is sent once, the PUSHNOTIF_API_KEY requirement, and a per-subscriber credit cost of 1 per broadcast. It falls just short of 5 because it does not state what happens to an existing configuration when parameters are omitted (partial update vs reset).

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?

Front-loads the core action and the immediate-dispatch variant before routing, prerequisites, and cost. The middle sentence is dense with nested parentheticals and stacked clauses, which is efficient but slightly harder to scan than a cleanly split structure.

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?

For a mutating multi-mode configuration tool with open-world network behavior, the description covers prerequisites, auth, validation, deduplication, billing impact, mode precedence, and even the return shape ({ ok, app_id, rss_enabled, ... }) despite no output schema. Nothing an agent needs in order to call it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3; the description still adds genuine meaning by clarifying that dispatch_now fetches and broadcasts 'even if rss_enabled=false', a precedence rule absent from the schema's property text. It also reinforces that rss_feed_url is required when enabling polling or dispensing, but adds no interval-duration or prefix-format detail beyond the schema.

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?

States a specific verb and resource ('Configure automated 24/7 RSS, Atom, or XML Sitemap polling for an app_id') and adds the alternate mode ('trigger an immediate feed check and push broadcast via dispatch_now=true'). It also names the two siblings it is not (send_push_notification, schedule_push_notification), so an agent can discriminate it without opening a schema.

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?

Gives an explicit positive trigger ('when a blog, news portal, or store wants newly published URLs automatically broadcast') plus two explicit exclusions that name the correct alternative tool for each. It also states a prerequisite sequence ('call list_apps first to obtain app_id'), leaving nothing to inference.

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

create_appAInspect

Register a new website domain or mobile application under the authenticated workspace and generate its unique ECDSA P-256 VAPID keypair and 1-line HTML SDK snippet. Use this tool when adding an additional website or app to an existing account; do not use it to modify an existing app's icon, welcome push, or mobile keys (use update_app_branding instead) or to remove an app (use delete_app instead). Requires PUSHNOTIF_API_KEY, costs 0 credits, and creates a persistent app record where site_url must be a valid HTTPS origin (or http://localhost for local testing). Returns JSON { ok, app: { id, site_name, site_url, vapid_public_key, created_at }, sdk_snippet }.

NameRequiredDescriptionDefault
site_urlYesCanonical HTTPS origin URL of the website (must start with https:// or http://localhost)
site_nameYesDisplay name of the website or mobile application (2 to 80 characters)

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare the safety profile (non-read-only, non-destructive, non-idempotent), and the description adds the information that actually matters for calling it: PUSHNOTIF_API_KEY is required, the operation costs 0 credits, and it creates a persistent record. It also discloses the generated artifacts (ECDSA P-256 VAPID keypair, SDK snippet), which cannot be inferred from annotations.

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

Conciseness5/5

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

It is dense but front-loaded: the purpose sentence comes first, then usage routing, then constraints and return shape, in that order. Every sentence carries distinct information and none repeats the name or annotations.

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?

For a non-idempotent mutation tool with no output schema, the description supplies auth requirements, cost, persistence, input validation rules, and the exact return JSON shape. An agent has everything needed to call it correctly and interpret the result.

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 both parameters, including the HTTPS/localhost constraint and the 2–80 character name limit. The description's restatement of the site_url origin rule adds little beyond the schema, so the baseline 3 applies.

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?

States a precise verb and resource ('Register a new website domain or mobile application') plus the concrete side effects (VAPID keypair, HTML SDK snippet). It explicitly names the siblings it is not (update_app_branding, delete_app), so an agent can separate it from every adjacent tool.

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?

Gives the positive trigger ('when adding an additional website or app to an existing account') and two explicit exclusions with the correct alternatives for each. Nothing about tool selection is left to inference.

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

create_qris_invoiceAInspect

Create a prepaid credit top-up invoice payable via Indonesian QRIS (all banks and e-wallets) at a flat rate of Rp 0.20 per credit (Rp 1,000 = 5,000 non-expiring credits). Use this tool when the user wants to purchase additional credits; do not use it to check whether an existing invoice has been paid (use check_billing_and_qris_status instead). Requires PUSHNOTIF_API_KEY, generates a PENDING order valid for 30 minutes at 0 fee, and automatically credits the workspace upon payment webhook confirmation; if both package_id and custom amount_rp are supplied, amount_rp takes precedence (minimum Rp 1,000). Returns JSON { ok, order: { id, amount_rp, credits_added, status, qris_checkout_url, expires_at } }.

NameRequiredDescriptionDefault
amount_rpNoCustom top-up amount in Indonesian Rupiah (minimum 1000, maximum 10000000; 1 IDR = 5 lifetime credits, overrides package_id)
package_idNoPreset package tier: 'starter' (Rp 20,000 = 100,000 credits), 'growth' (Rp 50,000 = 250,000 credits), or 'pro' (Rp 100,000 = 500,000 credits); ignored if amount_rp is explicitly provided

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations: discloses the required PUSHNOTIF_API_KEY, that the order is PENDING and expires in 30 minutes at zero fee, that crediting happens automatically on webhook confirmation (i.e. the call does not itself deliver credits), and the amount_rp-vs-package_id precedence. This is the mutation lifecycle detail an agent needs and cannot get from readOnlyHint/destructiveHint alone.

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?

Dense but front-loaded: purpose first, then exclusion, then auth/lifecycle, then parameter conflict, then return shape. Every clause carries information, though the inline JSON return shape makes the sentence long and slightly heavy to parse.

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

Completeness4/5

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

With no output schema, the description usefully spells out the returned JSON fields including qris_checkout_url and expires_at. The remaining hole is behavior with zero arguments, since both parameters are optional and the description never says which one is defaulted to.

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

Parameters4/5

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

Schema coverage is 100% so the baseline is 3, and the description adds the flat Rp 0.20/credit rate, the Rp 1,000 minimum, and the precedence rule in prose. It does not state what happens when neither optional parameter is supplied (required params = 0), which is the one semantic gap.

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?

States a specific verb and resource ('Create a prepaid credit top-up invoice') plus the payment rail (Indonesian QRIS, all banks and e-wallets), which makes it trivially distinguishable from billing/status siblings. An agent knows exactly what is being created without opening the schema.

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?

Explicitly names the trigger ('when the user wants to purchase additional credits') and the anti-trigger with the exact alternative tool ('do not use it to check whether an existing invoice has been paid (use check_billing_and_qris_status instead)'). No inference required.

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

delete_appA
DestructiveIdempotent
Inspect

Permanently delete a registered application (app_id) along with all of its subscriber device tokens, scheduled campaigns, and delivery history. Use this tool only when a user explicitly asks to remove a duplicate or decommissioned app; do not use it to pause notifications or change app settings (use update_app_branding or configure_inapp_banner instead). Prerequisite: call list_apps first to verify the exact app_id and active subscriber count. Requires PUSHNOTIF_API_KEY, costs 0 credits, and is irreversibly destructive (confirm_delete must be set to true or the call is rejected). Returns JSON { ok, deleted_app_id, deleted_site_name, subscribers_removed }.

NameRequiredDescriptionDefault
app_idYesTarget application ID in format app_xxxx to permanently delete (obtain from list_apps)
confirm_deleteYesSafety confirmation flag: must be explicitly set to true to execute permanent deletion

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and confirm_delete is in the schema, but the description adds real context the annotations cannot: the cascade deletion scope, the API key requirement, the zero credit cost, and that the call is rejected without confirm_delete=true. Only missing the return format, which prevents a 5. It does not contradict the idempotentHint=true annotation, since a repeat delete would leave the same end state.

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

Conciseness5/5

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

Four sentences, no redundancy: purpose and cascade first, then usage boundary, then prerequisite and cost/auth, then return shape. Each sentence carries distinct, actionable information.

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

Completeness4/5

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

Covers authentication, cost, cascade scope, confirmation safety, and return keys, which is thorough for a two-parameter destructive tool with no output schema. The description could not have done much more without becoming verbose.

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 description coverage is 100%, so both parameters are already documented. The description restates confirm_delete behavior and app_id provenance from list_apps but adds no syntax or format detail beyond what the schema provides, meeting the baseline.

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?

States a specific verb (permanently delete) and resource (registered application) plus the exact cascade of what is removed: subscriber device tokens, scheduled campaigns, delivery history. The scope alone distinguishes it from update_app_branding and configure_inapp_banner, which it names explicitly.

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?

Gives an explicit when-to-use condition (user asks to remove a duplicate or decommissioned app) and an explicit when-not-to-use condition (pausing notifications or changing app settings), naming the two alternative tools. It also states a prerequisite: call list_apps first to verify app_id and subscriber count.

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

get_campaign_analyticsA
Read-onlyIdempotent
Inspect

Retrieve historical push campaign delivery metrics (delivered count, click count, CTR percentage, credits spent) and active scheduled queue items (cmp_sch_xxxx). Use this tool to audit campaign performance or look up scheduled campaign IDs before editing or canceling them with schedule_push_notification; do not use it to inspect QRIS payment invoices (use check_billing_and_qris_status instead) or subscriber device lists (use list_subscribers instead). Read-only operation requiring PUSHNOTIF_API_KEY with 0 credit cost; omitting app_id aggregates metrics across all workspace apps up to limit rows. Returns JSON { summary: { total_sent, total_clicks, avg_ctr_percent }, campaigns: [{ id, app_id, title, delivered_count, click_count, ctr_percent, created_at }], scheduled_queue: [{ id, app_id, title, scheduled_for, recurrence_rule, status }] }.

NameRequiredDescriptionDefault
limitNoMaximum number of recent campaigns to return (1 to 50, default: 10)
app_idNoOptional application ID filter in format app_xxxx (omit to aggregate across all workspace apps)

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly, idempotent, non-destructive, so the safety bar is covered; the description goes well beyond that by disclosing the required PUSHNOTIF_API_KEY credential, the 0-credit cost, and the aggregation semantics when app_id is omitted. These are operationally relevant facts an agent could not derive from structured fields.

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?

Content is ordered well: purpose, metric scope, usage and exclusions, auth/cost, then return shape, so it is front-loaded with what matters most. The single dense paragraph and the full JSON return sketch could be tightened, but every clause carries useful information.

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?

With no output schema, the description takes on the burden of describing returns and does so fully (summary totals plus campaign and scheduled_queue item shapes). For a two-parameter read-only tool this covers everything an agent needs to call it and interpret results correctly.

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

Parameters4/5

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

Schema coverage is 100%, so the parameters are already documented and baseline is 3. The description adds meaning beyond the schema by explaining the consequence of omitting app_id (aggregation across all workspace apps bounded by limit rows), which clarifies intent rather than repeating format details.

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?

States a specific verb (retrieve) and specific resources (push campaign delivery metrics and scheduled queue items), enumerating the exact metric fields and the cmp_sch_xxxx ID format. It also explicitly names the siblings it is not (check_billing_and_qris_status, list_subscribers), so an agent can distinguish it without opening another schema.

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?

Gives concrete when-to-use cases (audit campaign performance, look up scheduled campaign IDs before editing/canceling) and names the follow-on tool schedule_push_notification. It also states explicit when-not cases with the correct alternatives for QRIS invoices and subscriber device lists, leaving nothing to inference.

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

list_appsA
Read-onlyIdempotent
Inspect

List all registered websites and mobile apps in the workspace with active subscriber counts, current credit balance, and optional framework SDK installation snippets (when include_sdk_framework is set). Use this tool first as a prerequisite to obtain a valid app_id before calling send_push_notification, schedule_push_notification, update_app_branding, delete_app, configure_inapp_banner, or configure_rss_autopush; do not use it to inspect individual subscriber devices (use list_subscribers instead). Read-only operation requiring PUSHNOTIF_API_KEY with 0 credit cost; when include_sdk_framework is passed ('html', 'nextjs', 'laravel', 'wordpress', 'flutter'), each app entry also includes ready-to-paste SDK setup code. Returns JSON { tenant_name, credits_balance, total_apps, apps: [{ id, site_name, site_url, active_subscribers, sdk_guide }] }.

NameRequiredDescriptionDefault
app_idNoOptional specific app_id (format app_xxxx) to filter and inspect in detail
include_sdk_frameworkNoOptional target stack ('html', 'nextjs', 'laravel', 'wordpress', or 'flutter') to include copy-paste SDK & service worker installation code

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, and the description adds material context not in them: the PUSHNOTIF_API_KEY requirement, the zero-credit cost, and the conditional side effect of include_sdk_framework injecting SDK snippets per app. It also states the exact return payload, which matters since no output schema exists.

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?

One dense paragraph, front-loaded with the purpose and then prerequisites, exclusions, and return shape in priority order. No filler sentences, though the inline JSON return signature makes it heavier to read than ideal; a short bullet structure would scan faster.

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?

For a two-param, no-output-schema read tool, everything an agent needs is present: auth requirement, cost, prerequisite ordering, alternative for device-level inspection, optional parameter behavior, and the response shape. Nothing material is left to inference.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real value by enumerating and explaining the effect of include_sdk_framework values ('html', 'nextjs', 'laravel', 'wordpress', 'flutter') β€” each app entry gains ready-to-paste setup code. It says nothing about the app_id filter parameter, leaving that entirely to the schema.

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?

Opens with a precise verb+resource+scope: 'List all registered websites and mobile apps in the workspace' including subscriber counts and credit balance. It explicitly distinguishes itself from list_subscribers and names the write tools it feeds, so an agent can place it correctly among 15 siblings without opening a schema.

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?

Gives an explicit prerequisite rule ('use this tool first ... before calling send_push_notification, schedule_push_notification, update_app_branding, delete_app, configure_inapp_banner, configure_rss_autopush') and an explicit exclusion ('do not use it to inspect individual subscriber devices (use list_subscribers instead)'). Both when-to-use and when-not-to-use, with named alternatives, are stated.

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

list_subscribersA
Read-onlyIdempotent
Inspect

Retrieve active subscriber device records, assigned segment tags, and platform breakdown counts (Web VAPID, Android FCM, iOS APNs) for the workspace or a specific app_id. Use this tool to inspect audience size, platform distribution, or obtain a subscriber_id before calling update_subscriber_tags; do not use it to view campaign click metrics (use get_campaign_analytics instead) or modify subscriber tags (use update_subscriber_tags instead). Read-only operation requiring PUSHNOTIF_API_KEY with 0 credit cost; filter by app_id and optional tag to narrow results. Returns JSON { total_active, platform_breakdown: { web, android_fcm, ios_apns }, subscribers: [{ id, app_id, platform, tags, created_at }] }.

NameRequiredDescriptionDefault
tagNoOptional segment tag filter (returns only subscribers carrying this tag)
limitNoMaximum number of subscriber records to return (1 to 100, default: 15)
app_idNoOptional application ID filter in format app_xxxx (omit to aggregate across all apps in the workspace)

TDQS

A4.4/5.0
Behavior4/5

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

Goes well beyond the annotations by disclosing the PUSHNOTIF_API_KEY requirement, zero credit cost, and the full JSON return shape β€” valuable since there is no output schema. It does not discuss pagination/truncation behavior for the limit parameter or how totals relate to the returned page, which keeps it from a 5.

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?

Purpose, alternatives, and constraints are front-loaded in the first two sentences, with the return shape last. It is a dense paragraph with some redundancy between the opening enumeration and the trailing return-JSON listing, but every element is functional for an agent without an output schema.

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?

Covers auth, cost, filtering, sibling routing, and return structure β€” everything an agent needs to call a read-only list tool with no output schema. The absence of an output schema is fully compensated by the inline JSON shape description.

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 description coverage is 100%, so all three parameters are already documented in the schema at a baseline of 3. The description reinforces app_id and tag as narrowing filters but adds no new semantics (e.g., how tag filtering interacts with platform_breakdown counts) and never mentions limit.

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?

States a specific verb and resource ('Retrieve active subscriber device records... platform breakdown counts') and enumerates exactly what is returned. It explicitly distinguishes itself from get_campaign_analytics and update_subscriber_tags, so an agent can route correctly without opening a schema.

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?

Gives positive use cases (inspect audience size, platform distribution, obtain a subscriber_id before update_subscriber_tags) and two explicit exclusions with the alternative tool named for each. When-to-use and when-not-to-use are both covered.

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

login_existing_accountA
Idempotent
Inspect

Authenticate an existing PushNotif account using email and password to retrieve its live API key and registered apps, with optional inline profile name or password update (when new_name or new_password is provided). Use this tool for existing users connecting from chat or updating account credentials; do not use it for new signups (use register_new_account instead) or app-level branding (use update_app_branding instead). Requires valid email and password (no prior API key needed), costs 0 credits, and is rate-limited against brute-force attempts; read-only unless new_name or new_password is supplied. Returns JSON { ok, tenant: { id, name, email, api_key, credits }, apps: [{ id, site_name, site_url }], profile_updated }.

NameRequiredDescriptionDefault
emailYesRegistered PushNotif account email address
new_nameNoOptional new workspace display name (2 to 80 characters) to update upon login
passwordYesCurrent account login password
new_passwordNoOptional new account password (minimum 6 characters) to replace the current password

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint false, idempotent true, destructive false), it discloses cost (0 credits), a brute-force rate limit, the conditional mutation behavior ('read-only unless new_name or new_password is supplied'), and the exact response envelope. This resolves the ambiguity inherent in a tool whose readOnlyHint is false despite being primarily a login.

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?

It is front-loaded with the primary action and scope, then alternatives, then operational facts. Dense but every clause carries information; the response-shape clause is arguably the least essential given no output schema exists, but it is still useful and compact.

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?

For a 4-parameter login-and-profile-update tool with no output schema, the description covers preconditions, cost, rate limiting, conditional mutation, alternatives, and the return JSON shape. Nothing an agent needs to call it correctly is missing.

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

Parameters4/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 four parameters. The description adds value by framing new_name and new_password as optional inline profile updates triggered on login and tying them to the 'profile_updated' return value, which the schema alone does not convey. It does not restate length constraints, which is fine since the schema covers them.

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 names a specific verb (authenticate), resource (existing PushNotif account), and the concrete outcome (retrieve live API key and registered apps, with optional profile update). It also explicitly contrasts with register_new_account and update_app_branding, so an agent can route between siblings without opening any schema.

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?

It states exactly when to use this tool (existing users connecting from chat, or updating credentials) and when not to, naming the correct alternatives for signups and app-level branding. The prerequisites ('requires valid email and password, no prior API key needed') are also spelled out.

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

register_new_accountAInspect

Two-step onboarding tool to request a 6-digit email OTP (step 1: omit otp_code) or verify the OTP to create a new PushNotif account with 1,000 free lifetime credits, register the initial website, and return a live API key (step 2: pass otp_code, password, and name). Use this tool only for brand-new user signups; do not use it for existing accounts (use login_existing_account instead) or to add websites to an existing account (use create_app instead). Public endpoint requiring no API key; step 1 is rate-limited to 5 OTPs per 10 minutes per IP (valid 10 minutes), while step 2 irreversibly creates a tenant and ECDSA P-256 VAPID keypair. Returns JSON { ok, step, tenant: { id, name, email, api_key, credits }, app: { id, site_name, site_url, vapid_public_key } }.

NameRequiredDescriptionDefault
nameNoWorkspace or company display name (2 to 80 characters; required when verifying otp_code)
emailYesEmail address to register (must not already belong to an existing PushNotif account)
otp_codeNoOptional 6-digit numeric OTP from email: omit on first call to send the OTP email, then provide on second call to complete registration
passwordNoAccount login password (minimum 6 characters; required when verifying otp_code)
site_urlNoOptional full HTTPS origin URL of the initial website (e.g., https://example.com)
site_nameNoOptional display name for the initial website or app (defaults to workspace name)

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations, the description discloses the rate limit (5 OTPs per 10 min per IP), OTP validity window, that step 2 irreversibly creates a tenant plus an ECDSA P-256 VAPID keypair, and that the endpoint is public with no API key. These are behavioral facts the structured fields do not carry.

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 two-step mechanism and sibling exclusions are front-loaded, and every clause carries operational information. It is dense to the point of being a single long sentence, which slightly hurts scannability, but nothing is wasted.

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?

A non-idempotent, open-world mutation tool with no output schema is fully covered: the description supplies the return payload shape (ok, step, tenant, app fields including the API key and VAPID key), the rate limit, and the irreversibility warning. An agent has everything needed to call it correctly and interpret the response.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3; the description earns above that by explaining the conditional coupling of otp_code with password and name and by tying each parameter set to a step. It does not add format constraints beyond what the schema already states (length minimums, HTTPS origin).

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 states a concrete verb and resource (register a new account via OTP) and spells out the two-step protocol explicitly. It names the sibling tools it is not (login_existing_account, create_app), so an agent can distinguish it from all 15 siblings without opening a schema.

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?

Explicit when-to-use ('only for brand-new user signups') and when-not-to-use rules with named alternatives for each case. The two-step invocation condition (omit otp_code first, pass it on the second call) is stated as a routing rule, not left to inference.

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

schedule_push_notificationAInspect

Create a new scheduled or recurring push notification campaign, edit an existing queued campaign (via update_campaign_id), or cancel a queued campaign before execution (via cancel_campaign_id). Use this tool for delayed, recurring, or editable future broadcasts; do not use it for immediate sending (use send_push_notification instead) or automated RSS feed polling (use configure_rss_autopush instead). Prerequisite: call list_apps to obtain app_id, or call get_campaign_analytics to obtain an existing cmp_sch_xxxx ID for editing or cancellation. Requires PUSHNOTIF_API_KEY; scheduling, editing, or canceling costs 0 credits up front, and 1 credit per delivered device is deducted only when the schedule fires (mutually exclusive modes: pass cancel_campaign_id to delete, update_campaign_id to modify fields in-place, or neither to create a new schedule). Returns JSON { ok, action, scheduled_campaign: { id, app_id, title, body, scheduled_for, recurrence_rule, status } }.

NameRequiredDescriptionDefault
urlNoOptional HTTPS destination URL opened when the notification is tapped
bodyNoNotification body text (1 to 240 characters; required when creating, optional when editing via update_campaign_id)
titleNoNotification headline (1 to 100 characters; required when creating, optional when editing via update_campaign_id)
app_idNoTarget application ID in format app_xxxx (required when creating a new schedule)
scheduled_forNoISO-8601 execution timestamp with timezone offset (e.g., '2026-10-21T08:00:00+07:00')
recurrence_ruleNoRecurrence pattern: 'once' (default), 'daily', 'twice_daily', 'weekly', 'monthly', 'every_30m', 'every_3h', 'every_6h', or a 5-field cron expression
cancel_campaign_idNoOptional existing scheduled campaign ID (format cmp_sch_xxxx from get_campaign_analytics) to cancel and remove from the queue
update_campaign_idNoOptional existing scheduled campaign ID (format cmp_sch_xxxx from get_campaign_analytics) to edit in-place with new title, body, url, scheduled_for, or recurrence_rule

TDQS

A4.6/5.0
Behavior4/5

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

Goes well beyond the annotations: discloses the PUSHNOTIF_API_KEY requirement, the credit model (0 up front, 1 credit per delivered device charged when the schedule fires), and the mutual exclusivity of cancel/update/create modes, plus the return shape. Minor gap: annotations declare destructiveHint=false while the description says cancel_campaign_id will 'delete' and 'remove from the queue' β€” the description could reconcile that asymmetry (irreversible queue removal vs. no data destruction) rather than leave it implicit.

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?

Front-loaded with the core verb+resource and every sentence carries information (alternatives, prerequisites, auth, cost, mode exclusivity, return shape). Dense single-paragraph packing of mode rules and cost rules makes it slower to scan than a short bulleted breakdown would be.

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?

For an 8-parameter, zero-required mutation tool with conditional requirements and no output schema, the description supplies the mode logic, prerequisites, credential/cost behavior, and an inline return shape β€” everything needed to call it correctly in any of its three modes.

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

Parameters4/5

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

Schema coverage is 100%, so per-parameter meaning is already documented; the description still adds value by explaining that the three mode parameters are mutually exclusive and that passing neither means create. It does not, however, explain interactions such as what happens if title/body are supplied with cancel_campaign_id, or how scheduled_for and recurrence_rule interact.

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?

Names specific verbs and a specific resource: creating, editing (via update_campaign_id) and cancelling (via cancel_campaign_id) scheduled/recurring push campaigns, and explicitly excludes two named siblings (send_push_notification for immediate sends, configure_rss_autopush for feed polling). An agent can distinguish this from every sibling without opening the schema.

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?

Explicit when-to-use ('delayed, recurring, or editable future broadcasts'), when-not ('do not use it for immediate sending'), and named alternatives for the excluded cases. It also gives the prerequisite chain (call list_apps for app_id; call get_campaign_analytics for cmp_sch_xxxx), which is exactly the guidance an agent needs before invoking.

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

send_push_notificationAInspect

Broadcast an immediate push notification across Web Push (VAPID), Android (FCM), and iOS (APNs) to active subscribers of a specific app_id. Use this tool for instant real-time delivery; do not use it for future or recurring broadcasts (use schedule_push_notification instead) or on-site HTML popups (use configure_inapp_banner instead). Prerequisite: call list_apps first to obtain app_id. Requires PUSHNOTIF_API_KEY, deducts 1 credit (Rp 0.20) per successfully delivered device (0 credits charged for 404/410 dead tokens, which are auto-pruned), and is irreversible once dispatched; when segment is set to a custom tag (from update_subscriber_tags) instead of 'all', only subscribers carrying that tag receive the broadcast, and omitting url defaults the tap action to the app's registered site_url. Returns JSON { ok, campaign_id, total_targeted, total_delivered, total_gone_pruned, credits_deducted, credits_remaining }.

NameRequiredDescriptionDefault
urlNoOptional HTTPS destination URL opened when the notification is tapped (defaults to app's site_url)
bodyYesNotification message body text (1 to 240 characters)
titleYesNotification headline shown on the lock screen (1 to 100 characters)
app_idYesTarget application ID in format app_xxxx (obtain from list_apps)
segmentNoTarget audience filter: 'all' (default) or a specific subscriber tag assigned via update_subscriber_tags

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare the generic write/non-idempotent profile; the description adds concrete operational facts: PUSHNOTIF_API_KEY requirement, 1 credit per delivered device with a stated price, zero charge for 404/410 dead tokens that are auto-pruned, and that dispatch is irreversible. It also documents the segment fallback and the url default, which are behavioral, not just schema restatement.

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 action and its scope are front-loaded, and every sentence carries non-redundant information (alternatives, prerequisite, cost, irreversibility, segment/url behavior, return shape). It is a single dense block with several clauses chained into one long sentence, which costs a little scannability but wastes no words.

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?

Despite no output schema, the description enumerates the return fields (ok, campaign_id, total_targeted, total_delivered, total_gone_pruned, credits_deducted, credits_remaining). Combined with prerequisites, cost model, sibling routing, and irreversibility for a non-idempotent destructive-adjacent broadcast, an agent has everything needed to invoke it correctly.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real semantics: segment as 'all' vs a custom tag sourced from update_subscriber_tags with tag-matching delivery behavior, and url defaulting to the app's registered site_url. It doesn't repeat title/body length limits, but those are already fully specified in the schema.

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?

States a specific verb (broadcast), resource (immediate push notification), delivery channels (VAPID/FCM/APNs), and audience scope (active subscribers of a given app_id). It explicitly distinguishes itself from schedule_push_notification and configure_inapp_banner, so an agent can route correctly without opening a schema.

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?

Gives explicit when-to-use (instant real-time delivery), explicit when-not-to-use with the two named alternative tools, and a required prerequisite step (call list_apps first to obtain app_id). Nothing about tool selection is left to inference.

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

update_app_brandingA
Idempotent
Inspect

Update an existing application's notification icon URL, automated welcome push message, and optional native mobile push credentials (Android FCM HTTP v1 service account JSON and iOS APNs .p8 key). Use this tool to configure app-level branding, onboarding welcome alerts, or native mobile credentials; do not use it to create a new app (use create_app instead) or configure on-site HTML popups (use configure_inapp_banner instead). Prerequisite: call list_apps first to obtain app_id. Requires PUSHNOTIF_API_KEY and idempotently updates only the fields provided at 0 configuration cost (when welcome_enabled=true, each new subscriber welcome push deducts 1 credit; APNs requires apns_key_id, apns_team_id, apns_bundle_id, and apns_p8_key together). Returns JSON { ok, app_id, icon_url, welcome_enabled, android_fcm_configured, ios_apns_configured }.

NameRequiredDescriptionDefault
app_idYesTarget application ID in format app_xxxx (obtain from list_apps)
icon_urlNoOptional direct HTTPS URL to a square PNG/JPG/WebP brand icon (recommended 192x192px)
apns_key_idNoOptional 10-character Apple Developer APNs Key ID (provide together with apns_team_id, apns_bundle_id, and apns_p8_key)
apns_p8_keyNoOptional full PEM content of Apple's AuthKey_XXXX.p8 private key file
apns_team_idNoOptional 10-character Apple Developer Team ID
welcome_bodyNoBody text of the automated welcome push notification (max 180 characters; used when welcome_enabled=true)
welcome_titleNoHeadline of the automated welcome push notification (max 80 characters; used when welcome_enabled=true)
apns_bundle_idNoOptional iOS application Bundle Identifier (e.g., 'id.company.app')
welcome_enabledNoSet true to automatically send a welcome push notification immediately after a visitor subscribes
fcm_service_account_jsonNoOptional raw JSON string of Google Firebase Service Account key for native Android FCM HTTP v1 delivery

TDQS

A4.4/5.0
Behavior4/5

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

Well beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), it discloses the auth requirement (PUSHNOTIF_API_KEY), partial-update behavior (only provided fields change), cost implications (1 credit per welcome push when welcome_enabled=true), the all-or-nothing APNs field group, and the return shape. The only gap is absence of any confirmation of irreversibility or rollback for credential overwrites, which keeps it short of a 5.

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?

Front-loads the action and affected fields, then layers usage exclusions, prerequisites, and return contract in a logical order with zero filler sentences. It is dense and long for a single paragraph, but nearly every clause carries operational information.

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?

With 10 parameters and no output schema, the description compensates by naming the returned JSON keys and stating the prerequisite and credential grouping rules. An agent has everything needed to invoke it correctly and interpret the response.

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 description coverage is 100%, so per-parameter meaning is already fully documented; the description mainly restates the field set. It does add cross-field semantics the schema cannot express β€” the APNs four-field coupling and the credit cost tied to welcome_enabled β€” but that added value is modest against a fully documented schema, so baseline 3 is fair.

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?

Names a specific verb+resource (update an existing application's branding) and enumerates exactly which fields it touches: icon URL, welcome push copy, and native mobile credentials. It also explicitly delineates from create_app and configure_inapp_banner, so an agent can distinguish it from siblings without opening schemas.

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?

Gives positive triggers (configure app-level branding, onboarding welcome alerts, native mobile credentials), explicit exclusions with named alternatives (use create_app instead, use configure_inapp_banner instead), and a prerequisite (call list_apps first to obtain app_id). Nothing is left to inference.

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

update_subscriber_tagsA
Idempotent
Inspect

Assign or remove audience segment tags on a subscriber device (subscriber_id), or permanently unsubscribe and delete the device record (when unsubscribe=true). Use this tool to manage subscriber segmentation for targeted send_push_notification broadcasts or to remove a specific subscriber; do not use it to list subscribers (use list_subscribers instead). Prerequisite: call list_subscribers first to obtain a valid subscriber_id. Requires PUSHNOTIF_API_KEY and costs 0 credits; when unsubscribe=true is passed, the subscriber token is irreversibly deleted and tag parameters are ignored, otherwise add_tags and remove_tags idempotently update the subscriber's tag set. Returns JSON { ok, subscriber_id, action, tags, removed }.

NameRequiredDescriptionDefault
add_tagsNoOptional list of lowercase segment tag strings (e.g., ['vip', 'jakarta']) to attach to the subscriber for targeted broadcasts
remove_tagsNoOptional list of segment tag strings to remove from the subscriber
unsubscribeNoSet true to permanently unsubscribe and delete this subscriber device record
subscriber_idYesTarget subscriber device ID in format sub_xxxx (obtain from list_subscribers)

TDQS

A4.2/5.0
Behavior2/5

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

The description contributes a lot beyond the annotations: API key requirement, zero credit cost, idempotent tag updates, tag parameters being ignored when unsubscribe=true, and an irreversible token deletion. However, that last point directly conflicts with the annotation destructiveHint=false β€” an agent trusting the annotations alone would treat this as a safe non-destructive mutation while the description documents permanent deletion. The mismatch undercuts the annotation contract even though the description is the more accurate side.

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?

Front-loaded with the core action and the destructive branch is flagged early, with sibling routing and prerequisites following. It is dense but slightly overstuffed β€” the redundant '(subscriber_id)' gloss after 'subscriber device' and the trailing return-shape JSON could be tightened without losing information.

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?

Covers the full call envelope for a 4-parameter mutation with no output schema: auth requirement, cost, prerequisite, side effects, parameter precedence, and the return shape { ok, subscriber_id, action, tags, removed }. There is no gap an agent would need to guess at.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3; the description exceeds it by adding real semantics the schema lacks β€” that tag updates are idempotent, that add_tags/remove_tags are silently ignored when unsubscribe=true, and that unsubscribe irreversibly deletes the token. Those interactions between parameters are the useful part an agent cannot get from the schema alone.

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?

States a specific verb (assign/remove tags, or unsubscribe) against a specific resource (subscriber device identified by subscriber_id), and explicitly names the sibling it is not (list_subscribers). An agent can distinguish this from every other subscriber-related tool without opening the schema.

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?

Explicit when-to-use ('manage subscriber segmentation for targeted send_push_notification broadcasts'), explicit when-not ('do not use it to list subscribers, use list_subscribers instead'), plus a stated prerequisite ('call list_subscribers first to obtain a valid subscriber_id'). Nothing is left to inference.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 20 tool updatesv2.2.0
    • Changedcheck_billing_and_qris_status1 field changed
      • changedInput schema / properties / order_id / description
        Previous value: -"Optional specific QRIS order ID (format ord_xxxx from create_qris_invoice) to inspect; omit to list recent orders"New value: +"Optional specific QRIS order ID in format ord_xxxx (from create_qris_invoice) to check; omit to return the latest orders and ledger history"
    • Changedconfigure_inapp_banner6 fields changed
      • changedInput schema / properties / inapp_accent / description
        Previous value: -"Optional hex color code for the CTA button and accent border (default: '#0058BE')"New value: +"Optional 6-digit hex color code for the CTA button and accent border (default: '#0058BE')"
      • changedInput schema / properties / inapp_cta_text / description
        Previous value: -"Optional call-to-action button label (e.g., 'Klaim Voucher β†’')"New value: +"Optional CTA button label (must be paired with inapp_cta_url to render a clickable action button)"
      • changedInput schema / properties / inapp_cta_url / description
        Previous value: -"Optional HTTPS URL opened when the CTA button is clicked"New value: +"Optional HTTPS destination URL opened when the CTA button is clicked"
      • changedInput schema / properties / inapp_enabled / description
        Previous value: -"Set true to activate the banner on the website, or false to pause it (default: true)"New value: +"Set true to publish the banner live on the website, or false to pause it (default: true)"
      • changedInput schema / properties / inapp_style / description
        Previous value: -"Visual layout style: 'modal' (center dialog), 'top_bar' (sticky top ribbon), or 'bottom_slide' (corner toast card)"New value: +"Visual layout: 'modal' (center dialog), 'top_bar' (sticky top ribbon), or 'bottom_slide' (corner slide-in toast)"
      • changedInput schema / properties / inapp_trigger / description
        Previous value: -"Display trigger condition: 'immediate' (default), 'delay_5s', 'delay_10s', 'scroll_50', 'scroll_80', or custom DOM event 'event:<name>'"New value: +"Trigger condition: 'immediate' (default), 'delay_5s', 'delay_10s', 'scroll_50', 'scroll_80', or custom DOM event 'event:<name>'"
    • Removedconfigure_mobile_credentials
    • Addedconfigure_payment_webhook
    • Changedconfigure_rss_autopush4 fields changed
      • changedInput schema / properties / rss_enabled / description
        Previous value: -"Set true to enable background RSS/Sitemap polling, or false to disable it"New value: +"Set true to enable background RSS/Sitemap polling at rss_interval, or false to pause background polling"
      • changedInput schema / properties / rss_feed_url / description
        Previous value: -"Public HTTPS URL of the RSS 2.0, Atom, or XML Sitemap feed (e.g., 'https://example.com/feed')"New value: +"Public HTTPS URL of the RSS 2.0, Atom, or XML Sitemap feed (required when enabling polling or calling dispatch_now=true)"
      • changedInput schema / properties / rss_interval / description
        Previous value: -"Polling frequency: '5m', '15m', '30m' (default), '1h', '3h', or 'daily_digest'"New value: +"Background polling interval: '5m', '15m', '30m' (default), '1h', '3h', or 'daily_digest'"
      • changedInput schema / properties / rss_prefix / description
        Previous value: -"Optional prefix prepended to each notification title (e.g., 'Artikel Baru: ')"New value: +"Optional text prepended to each auto-generated notification title (e.g., 'Artikel Baru: ')"
    • Changedcreate_app1 field changed
      • changedInput schema / properties / site_url / description
        Previous value: -"Canonical HTTPS URL of the website (must start with https:// or http://localhost)"New value: +"Canonical HTTPS origin URL of the website (must start with https:// or http://localhost)"
    • Changedcreate_qris_invoice2 fields changed
      • changedInput schema / properties / amount_rp / description
        Previous value: -"Custom top-up amount in Indonesian Rupiah (minimum 1000, maximum 10000000; 1 IDR = 5 credits)"New value: +"Custom top-up amount in Indonesian Rupiah (minimum 1000, maximum 10000000; 1 IDR = 5 lifetime credits, overrides package_id)"
      • changedInput schema / properties / package_id / description
        Previous value: -"Preset package tier: 'starter' (Rp 20,000 = 100,000 credits), 'growth' (Rp 50,000 = 250,000 credits), or 'pro' (Rp 100,000 = 500,000 credits); overridden if amount_rp is explicitly provided"New value: +"Preset package tier: 'starter' (Rp 20,000 = 100,000 credits), 'growth' (Rp 50,000 = 250,000 credits), or 'pro' (Rp 100,000 = 500,000 credits); ignored if amount_rp is explicitly provided"
    • Addeddelete_app
    • Changedget_campaign_analytics1 field changed
      • changedInput schema / properties / app_id / description
        Previous value: -"Optional application ID filter (format app_xxxx); omit to aggregate across all apps in the workspace"New value: +"Optional application ID filter in format app_xxxx (omit to aggregate across all workspace apps)"
    • Removedget_integration_guide
    • Changedlist_apps2 fields changed
      • addedInput schema / properties / app_id
        Added value: +{
        +  "description": "Optional specific app_id (format app_xxxx) to filter and inspect in detail",
        +  "type": "string"
        +}
      • addedInput schema / properties / include_sdk_framework
        Added value: +{
        +  "description": "Optional target stack ('html', 'nextjs', 'laravel', 'wordpress', or 'flutter') to include copy-paste SDK & service worker installation code",
        +  "type": "string"
        +}
    • Changedlist_subscribers3 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"Optional application ID filter (format app_xxxx); omit to list subscribers across all workspace apps"New value: +"Optional application ID filter in format app_xxxx (omit to aggregate across all apps in the workspace)"
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of recent subscriber records to return (1 to 100, default: 15)"New value: +"Maximum number of subscriber records to return (1 to 100, default: 15)"
      • addedInput schema / properties / tag
        Added value: +{
        +  "description": "Optional segment tag filter (returns only subscribers carrying this tag)",
        +  "type": "string"
        +}
    • Changedlogin_existing_account3 fields changed
      • addedInput schema / properties / new_name
        Added value: +{
        +  "description": "Optional new workspace display name (2 to 80 characters) to update upon login",
        +  "type": "string"
        +}
      • addedInput schema / properties / new_password
        Added value: +{
        +  "description": "Optional new account password (minimum 6 characters) to replace the current password",
        +  "type": "string"
        +}
      • changedInput schema / properties / password / description
        Previous value: -"Account password"New value: +"Current account login password"
    • Changedregister_new_account7 fields changed
      • changedInput schema / properties / email / description
        Previous value: -"Email address that received the OTP from request_registration_otp"New value: +"Email address to register (must not already belong to an existing PushNotif account)"
      • changedInput schema / properties / name / description
        Previous value: -"User or company workspace name (2 to 80 characters)"New value: +"Workspace or company display name (2 to 80 characters; required when verifying otp_code)"
      • changedInput schema / properties / otp_code / description
        Previous value: -"Exact 6-digit numeric OTP code sent to the user's email"New value: +"Optional 6-digit numeric OTP from email: omit on first call to send the OTP email, then provide on second call to complete registration"
      • changedInput schema / properties / password / description
        Previous value: -"Account password (minimum 6 characters)"New value: +"Account login password (minimum 6 characters; required when verifying otp_code)"
      • changedInput schema / properties / site_name / description
        Previous value: -"Optional display name for the first website or app (defaults to workspace name)"New value: +"Optional display name for the initial website or app (defaults to workspace name)"
      • changedInput schema / properties / site_url / description
        Previous value: -"Optional full HTTPS origin URL of the first website (e.g., https://example.com)"New value: +"Optional full HTTPS origin URL of the initial website (e.g., https://example.com)"
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "email",
        -  "password",
        -  "otp_code"
        -]New value: +[
        +  "email"
        +]
    • Removedrequest_registration_otp
    • Changedschedule_push_notification7 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"Target application ID in format app_xxxx (required when creating a schedule)"New value: +"Target application ID in format app_xxxx (required when creating a new schedule)"
      • changedInput schema / properties / body / description
        Previous value: -"Notification body text (required when creating a schedule; 1 to 240 characters)"New value: +"Notification body text (1 to 240 characters; required when creating, optional when editing via update_campaign_id)"
      • changedInput schema / properties / cancel_campaign_id / description
        Previous value: -"Optional scheduled campaign ID (format cmp_sch_xxxx from get_campaign_analytics) to cancel and delete before execution"New value: +"Optional existing scheduled campaign ID (format cmp_sch_xxxx from get_campaign_analytics) to cancel and remove from the queue"
      • changedInput schema / properties / scheduled_for / description
        Previous value: -"ISO-8601 execution timestamp (e.g., '2026-10-21T08:00:00+07:00')"New value: +"ISO-8601 execution timestamp with timezone offset (e.g., '2026-10-21T08:00:00+07:00')"
      • changedInput schema / properties / title / description
        Previous value: -"Notification headline (required when creating a schedule; 1 to 100 characters)"New value: +"Notification headline (1 to 100 characters; required when creating, optional when editing via update_campaign_id)"
      • addedInput schema / properties / update_campaign_id
        Added value: +{
        +  "description": "Optional existing scheduled campaign ID (format cmp_sch_xxxx from get_campaign_analytics) to edit in-place with new title, body, url, scheduled_for, or recurrence_rule",
        +  "type": "string"
        +}
      • changedInput schema / properties / url / description
        Previous value: -"Optional HTTPS destination URL opened on tap"New value: +"Optional HTTPS destination URL opened when the notification is tapped"
    • Changedsend_push_notification3 fields changed
      • changedInput schema / properties / segment / description
        Previous value: -"Subscriber filter: 'all' (default, sends to every active subscriber of app_id) or a specific subscriber tag string (e.g., 'vip', 'jakarta')"New value: +"Target audience filter: 'all' (default) or a specific subscriber tag assigned via update_subscriber_tags"
      • changedInput schema / properties / title / description
        Previous value: -"Notification headline shown on lock screen (1 to 100 characters)"New value: +"Notification headline shown on the lock screen (1 to 100 characters)"
      • changedInput schema / properties / url / description
        Previous value: -"Optional HTTPS destination URL opened when the user taps the notification (defaults to the app's site_url)"New value: +"Optional HTTPS destination URL opened when the notification is tapped (defaults to app's site_url)"
    • Changedupdate_app_branding8 fields changed
      • addedInput schema / properties / apns_bundle_id
        Added value: +{
        +  "description": "Optional iOS application Bundle Identifier (e.g., 'id.company.app')",
        +  "type": "string"
        +}
      • addedInput schema / properties / apns_key_id
        Added value: +{
        +  "description": "Optional 10-character Apple Developer APNs Key ID (provide together with apns_team_id, apns_bundle_id, and apns_p8_key)",
        +  "type": "string"
        +}
      • addedInput schema / properties / apns_p8_key
        Added value: +{
        +  "description": "Optional full PEM content of Apple's AuthKey_XXXX.p8 private key file",
        +  "type": "string"
        +}
      • addedInput schema / properties / apns_team_id
        Added value: +{
        +  "description": "Optional 10-character Apple Developer Team ID",
        +  "type": "string"
        +}
      • addedInput schema / properties / fcm_service_account_json
        Added value: +{
        +  "description": "Optional raw JSON string of Google Firebase Service Account key for native Android FCM HTTP v1 delivery",
        +  "type": "string"
        +}
      • changedInput schema / properties / welcome_body / description
        Previous value: -"Body text of the automated welcome push notification (max 180 characters)"New value: +"Body text of the automated welcome push notification (max 180 characters; used when welcome_enabled=true)"
      • changedInput schema / properties / welcome_enabled / description
        Previous value: -"Set true to automatically send a welcome push notification immediately after a visitor grants permission"New value: +"Set true to automatically send a welcome push notification immediately after a visitor subscribes"
      • changedInput schema / properties / welcome_title / description
        Previous value: -"Headline of the automated welcome push notification (max 80 characters)"New value: +"Headline of the automated welcome push notification (max 80 characters; used when welcome_enabled=true)"
    • Removedupdate_profile
    • Addedupdate_subscriber_tags
  2. 16 tool updatesv2.1.2
    • Changedcheck_billing_and_qris_status1 field changed
      • changedInput schema / properties / order_id / description
        Previous value: -"Opsional: ID tagihan QRIS tertentu yang ingin dicek (misal: ord_xxxx)"New value: +"Optional specific QRIS order ID (format ord_xxxx from create_qris_invoice) to inspect; omit to list recent orders"
    • Changedconfigure_inapp_banner10 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID yang ingin diatur"New value: +"Target application ID in format app_xxxx (obtain from list_apps)"
      • changedInput schema / properties / inapp_accent / description
        Previous value: -"Kode warna HEX tombol (misal: #0058BE, #047857, #E11D48)"New value: +"Optional hex color code for the CTA button and accent border (default: '#0058BE')"
      • changedInput schema / properties / inapp_body / description
        Previous value: -"Isi pesan singkat"New value: +"Banner supporting message text (1 to 240 characters)"
      • changedInput schema / properties / inapp_cta_text / description
        Previous value: -"Teks tombol aksi (CTA)"New value: +"Optional call-to-action button label (e.g., 'Klaim Voucher β†’')"
      • changedInput schema / properties / inapp_cta_url / description
        Previous value: -"URL tujuan saat tombol diklik"New value: +"Optional HTTPS URL opened when the CTA button is clicked"
      • changedInput schema / properties / inapp_enabled / description
        Previous value: -"True untuk mengaktifkan banner di website/aplikasi"New value: +"Set true to activate the banner on the website, or false to pause it (default: true)"
      • changedInput schema / properties / inapp_freq / description
        Previous value: -"Frekuensi tampil: once_per_session, once_per_day, always, cooldown_3h, cooldown_12h, once_per_week"New value: +"Per-visitor frequency cap: 'once_per_session' (default), 'once_per_day', 'cooldown_3h', 'cooldown_12h', 'once_per_week', or 'always'"
      • changedInput schema / properties / inapp_style / description
        Previous value: -"Gaya tampilan: modal, top_bar, atau bottom_slide"New value: +"Visual layout style: 'modal' (center dialog), 'top_bar' (sticky top ribbon), or 'bottom_slide' (corner toast card)"
      • changedInput schema / properties / inapp_title / description
        Previous value: -"Judul pengumuman/promo"New value: +"Banner headline text (1 to 100 characters)"
      • changedInput schema / properties / inapp_trigger / description
        Previous value: -"Pemicu muncul: immediate, delay_5s, delay_10s, scroll_50, scroll_80, atau event:nama_event (misal: event:add_to_cart, event:payment_success)"New value: +"Display trigger condition: 'immediate' (default), 'delay_5s', 'delay_10s', 'scroll_50', 'scroll_80', or custom DOM event 'event:<name>'"
    • Changedconfigure_mobile_credentials6 fields changed
      • changedInput schema / properties / apns_bundle_id / description
        Previous value: -"iOS App Bundle ID (misal: id.perusahaan.app)"New value: +"iOS application Bundle Identifier (e.g., 'id.company.app')"
      • changedInput schema / properties / apns_key_id / description
        Previous value: -"Apple APNs Key ID (10 karakter)"New value: +"10-character Apple Developer APNs Key ID (e.g., 'ABC123DEFG')"
      • changedInput schema / properties / apns_p8_key / description
        Previous value: -"Isi teks file AuthKey_XXXX.p8 dari Apple Developer"New value: +"Full PEM text content of Apple's AuthKey_XXXX.p8 private key file"
      • changedInput schema / properties / apns_team_id / description
        Previous value: -"Apple Developer Team ID (10 karakter)"New value: +"10-character Apple Developer Team ID"
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID yang ingin dikonfigurasi"New value: +"Target application ID in format app_xxxx (obtain from list_apps)"
      • changedInput schema / properties / fcm_service_account_json / description
        Previous value: -"Isi teks file service-account.json Firebase untuk Android APK"New value: +"Raw JSON string of the Google Firebase Service Account key file for Android FCM HTTP v1"
    • Changedconfigure_rss_autopush6 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID tujuan"New value: +"Target application ID in format app_xxxx (obtain from list_apps)"
      • changedInput schema / properties / dispatch_now / description
        Previous value: -"Set true jika ingin langsung menarik item RSS terbaru dan menembak Push Notification detik ini juga"New value: +"Set true to immediately fetch the latest feed entry and broadcast it to active subscribers right now"
      • changedInput schema / properties / rss_enabled / description
        Previous value: -"True untuk mengaktifkan pemantau RSS otomatis"New value: +"Set true to enable background RSS/Sitemap polling, or false to disable it"
      • changedInput schema / properties / rss_feed_url / description
        Previous value: -"URL RSS/Atom/Sitemap website (misal: https://domain.com/rss.xml)"New value: +"Public HTTPS URL of the RSS 2.0, Atom, or XML Sitemap feed (e.g., 'https://example.com/feed')"
      • changedInput schema / properties / rss_interval / description
        Previous value: -"Interval cek: 5m, 15m, 30m, 1h, 3h, atau daily_digest"New value: +"Polling frequency: '5m', '15m', '30m' (default), '1h', '3h', or 'daily_digest'"
      • changedInput schema / properties / rss_prefix / description
        Previous value: -"Awalan judul notifikasi (misal: Artikel Baru:)"New value: +"Optional prefix prepended to each notification title (e.g., 'Artikel Baru: ')"
    • Changedcreate_app2 fields changed
      • changedInput schema / properties / site_name / description
        Previous value: -"Nama website atau aplikasi"New value: +"Display name of the website or mobile application (2 to 80 characters)"
      • changedInput schema / properties / site_url / description
        Previous value: -"URL domain lengkap dengan https://"New value: +"Canonical HTTPS URL of the website (must start with https:// or http://localhost)"
    • Changedcreate_qris_invoice2 fields changed
      • changedInput schema / properties / amount_rp / description
        Previous value: -"Nominal Rupiah top-up (default: 20000)"New value: +"Custom top-up amount in Indonesian Rupiah (minimum 1000, maximum 10000000; 1 IDR = 5 credits)"
      • changedInput schema / properties / package_id / description
        Previous value: -"Pilih paket: starter, growth, atau pro (opsional jika mengisi amount_rp)"New value: +"Preset package tier: 'starter' (Rp 20,000 = 100,000 credits), 'growth' (Rp 50,000 = 250,000 credits), or 'pro' (Rp 100,000 = 500,000 credits); overridden if amount_rp is explicitly provided"
    • Changedget_campaign_analytics2 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"Opsional: filter untuk App ID tertentu"New value: +"Optional application ID filter (format app_xxxx); omit to aggregate across all apps in the workspace"
      • changedInput schema / properties / limit / description
        Previous value: -"Jumlah riwayat kampanye terakhir yang ditampilkan (default: 10)"New value: +"Maximum number of recent campaigns to return (1 to 50, default: 10)"
    • Changedget_integration_guide2 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID yang ingin diambil panduannya"New value: +"Target application ID in format app_xxxx (obtain from list_apps)"
      • changedInput schema / properties / framework / description
        Previous value: -"Nama framework (misal: Next.js / React, Flutter, Laravel)"New value: +"Target stack: 'html' (default 1-line script), 'nextjs', 'laravel', 'wordpress', or 'flutter'"
    • Changedlist_subscribers2 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"Opsional: filter untuk App ID tertentu"New value: +"Optional application ID filter (format app_xxxx); omit to list subscribers across all workspace apps"
      • changedInput schema / properties / limit / description
        Previous value: -"Jumlah baris pelanggan terbaru yang ditampilkan (default: 15)"New value: +"Maximum number of recent subscriber records to return (1 to 100, default: 15)"
    • Changedlogin_existing_account2 fields changed
      • changedInput schema / properties / email / description
        Previous value: -"Alamat email akun PushNotif"New value: +"Registered PushNotif account email address"
      • changedInput schema / properties / password / description
        Previous value: -"Password akun PushNotif"New value: +"Account password"
    • Changedregister_new_account6 fields changed
      • changedInput schema / properties / email / description
        Previous value: -"Alamat email pengguna (sama dengan saat request_registration_otp)"New value: +"Email address that received the OTP from request_registration_otp"
      • changedInput schema / properties / name / description
        Previous value: -"Nama pengguna atau workspace"New value: +"User or company workspace name (2 to 80 characters)"
      • changedInput schema / properties / otp_code / description
        Previous value: -"Kode OTP 6 angka yang diterima pengguna di inbox email"New value: +"Exact 6-digit numeric OTP code sent to the user's email"
      • changedInput schema / properties / password / description
        Previous value: -"Password akun baru (minimal 6 karakter)"New value: +"Account password (minimum 6 characters)"
      • changedInput schema / properties / site_name / description
        Previous value: -"Nama website atau aplikasi pertama"New value: +"Optional display name for the first website or app (defaults to workspace name)"
      • changedInput schema / properties / site_url / description
        Previous value: -"URL lengkap website pertama (diawali https://)"New value: +"Optional full HTTPS origin URL of the first website (e.g., https://example.com)"
    • Changedrequest_registration_otp2 fields changed
      • changedInput schema / properties / email / description
        Previous value: -"Alamat email pengguna yang akan didaftarkan"New value: +"Valid email address to register (e.g., user@domain.com); must not already be registered"
      • changedInput schema / properties / name / description
        Previous value: -"Nama pengguna atau nama perusahaan/workspace"New value: +"Optional user or workspace display name (2 to 80 characters)"
    • Changedschedule_push_notification7 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID tujuan (misal: app_xxxx)"New value: +"Target application ID in format app_xxxx (required when creating a schedule)"
      • changedInput schema / properties / body / description
        Previous value: -"Isi pesan notifikasi"New value: +"Notification body text (required when creating a schedule; 1 to 240 characters)"
      • changedInput schema / properties / cancel_campaign_id / description
        Previous value: -"Isi jika ingin membatalkan/menghapus jadwal kampanye (cmp_sch_xxxx)"New value: +"Optional scheduled campaign ID (format cmp_sch_xxxx from get_campaign_analytics) to cancel and delete before execution"
      • changedInput schema / properties / recurrence_rule / description
        Previous value: -"Aturan perulangan: once, daily, twice_daily, weekly, monthly, every_30m, every_3h, every_6h, atau ekspresi cron kustom (misal: 0 5,12,15,18,19 * * *)"New value: +"Recurrence pattern: 'once' (default), 'daily', 'twice_daily', 'weekly', 'monthly', 'every_30m', 'every_3h', 'every_6h', or a 5-field cron expression"
      • changedInput schema / properties / scheduled_for / description
        Previous value: -"Waktu kirim format ISO-8601 (misal: 2026-10-17T06:00:00Z)"New value: +"ISO-8601 execution timestamp (e.g., '2026-10-21T08:00:00+07:00')"
      • changedInput schema / properties / title / description
        Previous value: -"Judul pesan notifikasi"New value: +"Notification headline (required when creating a schedule; 1 to 100 characters)"
      • changedInput schema / properties / url / description
        Previous value: -"URL tujuan saat notifikasi diketuk"New value: +"Optional HTTPS destination URL opened on tap"
    • Changedsend_push_notification5 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID tujuan (misal: app_xxxx)"New value: +"Target application ID in format app_xxxx (obtain from list_apps)"
      • changedInput schema / properties / body / description
        Previous value: -"Isi pesan notifikasi"New value: +"Notification message body text (1 to 240 characters)"
      • changedInput schema / properties / segment / description
        Previous value: -"Filter segmen pelanggan (default: all)"New value: +"Subscriber filter: 'all' (default, sends to every active subscriber of app_id) or a specific subscriber tag string (e.g., 'vip', 'jakarta')"
      • changedInput schema / properties / title / description
        Previous value: -"Judul pesan notifikasi"New value: +"Notification headline shown on lock screen (1 to 100 characters)"
      • changedInput schema / properties / url / description
        Previous value: -"URL tujuan saat notifikasi diketuk"New value: +"Optional HTTPS destination URL opened when the user taps the notification (defaults to the app's site_url)"
    • Changedupdate_app_branding5 fields changed
      • changedInput schema / properties / app_id / description
        Previous value: -"App ID yang ingin diubah (misal: app_xxxx)"New value: +"Target application ID in format app_xxxx (obtain from list_apps)"
      • changedInput schema / properties / icon_url / description
        Previous value: -"URL gambar logo PNG/JPG aplikasi"New value: +"Optional direct HTTPS URL to a square PNG/JPG/WebP brand icon (recommended 192x192px)"
      • changedInput schema / properties / welcome_body / description
        Previous value: -"Isi pesan notifikasi sambutan"New value: +"Body text of the automated welcome push notification (max 180 characters)"
      • changedInput schema / properties / welcome_enabled / description
        Previous value: -"Aktifkan/matikan pesan sambutan otomatis"New value: +"Set true to automatically send a welcome push notification immediately after a visitor grants permission"
      • changedInput schema / properties / welcome_title / description
        Previous value: -"Judul notifikasi sambutan saat user baru klik Izinkan"New value: +"Headline of the automated welcome push notification (max 80 characters)"
    • Changedupdate_profile2 fields changed
      • changedInput schema / properties / name / description
        Previous value: -"Nama perusahaan atau pemilik workspace baru"New value: +"New workspace or company display name (2 to 80 characters)"
      • changedInput schema / properties / new_password / description
        Previous value: -"Opsional: password baru (minimal 6 karakter)"New value: +"Optional new account login password (minimum 6 characters; omit to keep current password unchanged)"
  3. 17 tool updatesv2.1.0
    • First observedcheck_billing_and_qris_status
    • First observedconfigure_inapp_banner
    • First observedconfigure_mobile_credentials
    • First observedconfigure_rss_autopush
    • First observedcreate_app
    • First observedcreate_qris_invoice
    • First observedget_campaign_analytics
    • First observedget_integration_guide
    • First observedlist_apps
    • First observedlist_subscribers
    • First observedlogin_existing_account
    • First observedregister_new_account
    • First observedrequest_registration_otp
    • First observedschedule_push_notification
    • First observedsend_push_notification
    • First observedupdate_app_branding
    • First observedupdate_profile

TDQS

A4.4/5.0

Scored across 16 tools

Disambiguation4/5

Each tool targets a distinct resource+action and the descriptions include explicit 'do not use X, use Y instead' cross-references, making boundaries unusually clear. The only friction is that a few tools are multi-modal (schedule_push_notification creates, edits, and cancels campaigns; configure_rss_autopush and configure_payment_webhook take dispatch_now/simulate_test flags), so an agent must parse parameters to know which operation it is invoking.

Naming Consistency5/5

All 16 tools are snake_case and begin with a clear action verb followed by the resource (list_apps, create_app, update_app_branding, send_push_notification, check_billing_and_qris_status). The get_/list_ split reflects genuine read-shape differences rather than convention drift, and nothing mixes casing or verb style.

Tool Count4/5

16 tools is at the upper-but-reasonable end for a server spanning auth, app CRUD, push delivery, scheduling, in-app banners, RSS, payment webhooks, subscribers, analytics, and billing. Each tool maps to a real workflow step, though compressing the three schedule modes (create/edit/cancel) into one tool hints the surface could be tightened further.

Completeness4/5

Coverage is strong: full app lifecycle (list/create/update branding/delete), subscriber read+tag+unsubscribe, push send/schedule/analytics, and billing invoice+status. Minor gaps remainβ€”there is no way to rename an app or change its site_url outside branding, no per-campaign detail fetch, and no API-key rotation or logout operation.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to manage OneSignal push notifications, email, SMS, and user management through natural language. Supports multi-channel messaging, segmentation, templates, analytics, and iOS Live Activities with 50+ tools for complete OneSignal API coverage.
    1
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to send push notifications and interactive alerts to iPhone and Mac devices via the BotBell app. It allows AI to receive user replies and manage notification bots for tasks like alerts, reminders, and remote approvals.
    2
    10 npm
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Lets AI assistants manage subscribers, trigger workflows, inspect notification events, and tune preferences across any MCP-compatible client.
    -