Skip to main content
Glama

jami-mcp

The official Model Context Protocol server for JamiDev — Jami's payments API for Ethiopia. Connect it to Claude, Cursor, VS Code, Codex or any MCP client and your agent can create ETB checkouts, watch them settle, reconcile orders, preview and send payouts, debug webhooks, and read the Jami docs while it writes your integration.

Built on the official jami-sdk, so every tool behaves exactly like the SDK and the REST API.

npx -y jami-mcp

Quick start

  1. Get a token: Jami dashboard → JamiDev → Developer → API Tokens. Start with a sandbox org — its jamidev_test_… token moves no real money.

  2. Add the server to your client (below), with the token as JAMI_TOKEN.

  3. Ask: "Charge buyer@example.com 1,237 birr for order #1042 on Telebirr, phone 251900000001, and wait for it."

No token yet? The server still runs. The docs, withdrawal-quote and webhook tools work without one, so you can start building right away.

Claude Code

claude mcp add jami -e JAMI_TOKEN=jamidev_test_xxx -- npx -y jami-mcp

Claude Desktop · Cursor · Windsurf

Add to claude_desktop_config.json, ~/.cursor/mcp.json or ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "jami": {
      "command": "npx",
      "args": ["-y", "jami-mcp"],
      "env": { "JAMI_TOKEN": "jamidev_test_xxx" }
    }
  }
}

VS Code

.vscode/mcp.json — VS Code prompts for the token and stores it securely:

{
  "inputs": [
    { "type": "promptString", "id": "jami-token", "description": "JamiDev API token", "password": true }
  ],
  "servers": {
    "jami": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "jami-mcp"],
      "env": { "JAMI_TOKEN": "${input:jami-token}" }
    }
  }
}

Codex

~/.codex/config.toml:

[mcp_servers.jami]
command = "npx"
args = ["-y", "jami-mcp"]
env = { JAMI_TOKEN = "jamidev_test_xxx" }

Related MCP server: mcp-jazzcash

Tools

Tool

What it does

Needs token

jami_create_checkout

Charge a product (p_… token or id) or any amount (amount_minor + description). With gateway: pushes the prompt to the buyer's phone. Without: returns a Jami payment link to send them.

✓

jami_create_product · jami_update_product

Create or edit products; each comes back with its public page and p_… token.

✓

jami_get_product · jami_list_products

Read the catalog.

✓

jami_get_checkout_status

Check a session once, with the failure reason when it expired.

✓

jami_wait_for_checkout

Wait for the buyer to finish, with progress updates. Never hangs: returns open at the timeout.

✓

jami_list_orders

Orders, newest first, paginated and filterable by status.

✓

jami_get_balance

Withdrawable earnings and whether the org can withdraw.

✓

jami_quote_withdrawal

Fee, tax and net for an amount, plus auto-pay and cap checks. Offline.

—

jami_create_withdrawal

Pay out to Telebirr, M-Pesa or CBE Birr. Opt-in (see Safety).

✓

jami_get_withdrawal · jami_list_withdrawals

Track payouts.

✓

jami_verify_webhook

Check a captured delivery's signature, and why it fails.

—

jami_create_test_webhook

Build a correctly signed test event, and optionally POST it to your local handler.

—

jami_search_docs · jami_read_doc

Search and read the live docs at dev.jami.bio.

—

Every tool returns a readable markdown summary plus typed structuredContent. Pass response_format: "json" for the raw payload. Money is always integer santim, and every parameter that takes money ends in _minor: amount_minor: 15000 = 150.00 ETB.

Prompts: integrate_jami (build a full integration in your stack), go_live_checklist, debug_payment. Resource: jami://reference — fees, limits, sandbox numbers, failure codes and webhook rules in one page.

Safety

The defaults are set so an agent can't move money by accident.

  • Withdrawals are off until you start the server with --enable-withdrawals (or JAMI_ENABLE_WITHDRAWALS=true). When they're on, clients that support elicitation ask you to confirm each payout, and every payout needs an idempotency_key, so a retry can never pay twice. Sandbox tokens are refused before any request is made.

  • --read-only registers only the tools that read data. Use it for reporting agents.

  • Live mode is announced. With a jamidev_live_ token, the server tells the agent that checkouts charge real buyers and to confirm first.

  • Tokens stay in the environment. They never appear in tool output.

Options

--http                 Streamable HTTP on POST /mcp instead of stdio
--port <n>             HTTP port (default 3333)
--host <addr>          HTTP bind address (default 127.0.0.1)
--read-only            Only read tools
--enable-withdrawals   Register jami_create_withdrawal
--base-url <url>       Override the API base (default https://jami.bio/api/jamidev)
--docs-url <url>       Override the docs origin (default https://dev.jami.bio)

Env

Purpose

JAMI_TOKEN

jamidev_test_… or jamidev_live_…

JAMI_WEBHOOK_SECRET

Default secret for the webhook tools

JAMI_READ_ONLY, JAMI_ENABLE_WITHDRAWALS

Same as the flags

Remote (HTTP) mode

npx -y jami-mcp --http --port 3333
# → http://127.0.0.1:3333/mcp   (health check: /healthz)

The HTTP server is stateless, so any number of clients can share one process. Without JAMI_TOKEN, each request authenticates with its own Authorization: Bearer jamidev_… header, which makes one deployment safe to share across teams. On loopback it rejects foreign Host headers (DNS-rebinding protection). In HTTP mode, jami_create_test_webhook never sends requests; it only returns the signed payload and a curl command.

Embedding

import { createJamiServer } from 'jami-mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = createJamiServer({ token: process.env.JAMI_TOKEN, docsUrl: 'https://dev.jami.bio', readOnly: true, withdrawals: false });
await server.connect(new StdioServerTransport());

Development

npm install
npm test          # in-memory MCP client against a mocked API
npm run build
npm run inspect   # opens the MCP Inspector on dist/index.js

Full guide: dev.jami.bio/docs/mcp · Support: support@jami.bio

MIT © Jami

Available Tools

16 tools
jami_create_checkoutCreate checkoutA

Start a checkout and get back how the buyer pays — either for one of the organization's published products, or for ANY amount with no product ("charge this buyer 1,237 ETB for order #1042").

Buyers pay in ETB via Telebirr, M-Pesa or CBE Birr; nothing is added on top. In LIVE mode a "direct" checkout pushes a real payment prompt to the buyer's phone, so only call this when the user actually wants to charge someone.

What to charge:

  • Product: product_id (p_… token or 24-char id, must be published). amount_minor only for flexible-price (pwyw) products.

  • Custom amount: omit product_id, pass amount_minor (≥ 100 = 1.00 ETB) and description (what the buyer sees, ≤ 120 chars).

How to collect it:

  • Direct push: pass gateway + customer_email + customer_phone. The prompt goes straight to the buyer's phone (kind 'direct').

  • Payment link: omit gateway. You get a Jami link in checkout_url (kind 'redirect') to send the buyer by SMS/Telegram/email; they pick the method and enter their details there, and can retry a failed attempt until the link expires (30 min). customer_* is optional.

Args:

  • customer_email / customer_phone: required for a direct push; optional for a link. Phone like "251911223344" or "0911223344". Sandbox magic numbers: 251900000001 = instant success, 251900000002 = instant failure.

  • gateway: 'telebirr' | 'mpesa' | 'cbe'. Omit for a payment link.

  • amount_minor: integer santim. 123700 = 1,237.00 ETB.

  • metadata: optional string map (e.g. { "orderId": "1042" }) stored on the order and sent back on order webhooks.

Returns: { session_id, kind: 'free' | 'redirect' | 'direct', checkout_url, order_id }.

  • free: completed instantly; order_id is set.

  • redirect: send the buyer to checkout_url.

  • direct: the buyer confirms on their phone; call jami_wait_for_checkout next.

ParametersJSON Schema
NameRequiredDescriptionDefault
gatewayNoPayment method for paid products
metadataNoYour own key/values, returned on order webhooks (max 20 keys)
product_idNoProduct token (p_…) or id. Omit for a custom-amount checkout.
descriptionNoCustom amount only: what the buyer is paying for, e.g. "Order #1042"
success_urlNoWhere to send the buyer after paying
amount_minorNoInteger santim. Required for custom amounts (≥ 100) and pay-what-you-want products; ignored for fixed prices
checkout_linkNoCheckout link token (cl_…) to attribute this session to
customer_nameNo
customer_emailNoBuyer email for the receipt. Required with gateway; optional for a payment link
customer_phoneNoBuyer phone, e.g. "251911223344"
collected_fieldsNoAnswers to the product's checkout fields, keyed by field id
customer_external_idNoYour own user id, stored on the customer record

Output Schema

ParametersJSON Schema
NameRequiredDescription
kindYes
order_idYes
session_idYes
checkout_urlYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare mutation/non-idempotent/open-world, but the description adds substantial context they don't carry: LIVE mode pushes a real payment prompt to a phone, link expiry is 30 minutes, failed attempts can be retried, ETB-only payment with nothing added on top, and sandbox magic numbers for instant success/failure. This is unusually rich operational disclosure.

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?

Well front-loaded with the core outcome first, then structured 'What to charge' / 'How to collect it' / Args / Returns sections that are easy to scan. It is somewhat long and a few lines (phone format, amount_minor units) duplicate schema text, but the structure justifies the length.

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 modes, gateway selection, when-to-call caution, error/retry behavior, expiry, and next-step routing; an output schema exists yet the description still summarizes the return shape (session_id/kind/checkout_url/order_id) and how to act on each kind. 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 description coverage is already 92%, so the schema carries most parameter detail. The description nonetheless adds cross-parameter semantics the schema cannot express: product_id vs. amount_minor mutual exclusion, gateway-driven kind selection, and required/optional status of customer_email/customer_phone per mode. It omits explanation of secondary params (success_url, checkout_link, collected_fields, customer_external_id), keeping it from a 5.

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 ('Start a checkout and get back how the buyer pays') and immediately distinguishes the two modes it serves: a published product vs. an arbitrary custom amount. It also names the sibling workflow it feeds into (jami_wait_for_checkout), so an agent can place it in the toolset 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 states when NOT to call it ('only call this when the user actually wants to charge someone') and lays out the decision between direct push vs. payment link with the exact parameter conditions (pass gateway vs. omit gateway). It routes the agent to jami_wait_for_checkout for the direct case, which is explicit alternative guidance.

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

jami_create_productCreate productA

Create a product the organization sells, and get its public Jami page (url) and p_… token. Published by default, so the page and checkouts work immediately.

Pricing (can't be changed after creation; the amounts can):

  • fixed: amount_minor is the price, e.g. 250000 = 2,500.00 ETB.

  • pwyw (flexible): minimum_amount_minor; each checkout then sends its own amount.

  • free: no price.

Args: title (1–120 chars), pricing_model, amount_minor / minimum_amount_minor, description?, status? ('published' | 'draft').

Returns: { product_id, token, url, title, status, pricing_model, price }. To charge for it, call jami_create_checkout with product_id = token (omit gateway for a payment link).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
statusNopublished
descriptionNo
amount_minorNoFixed price in santim
pricing_modelYes
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown
minimum_amount_minorNoFlexible price floor in santim

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYesPublic Jami page where anyone can buy it (published only)
priceYes
titleYes
tokenYesUse as product_id in jami_create_checkout
statusYes
product_idYes
amount_minorYes
pricing_modelYes
minimum_amount_minorYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare this is a non-read-only, non-idempotent, non-destructive write, so the bar is lower. The description adds the crucial immutability constraint ('Pricing can't be changed after creation; the amounts can') and the default publication behavior, which are not visible in the structured fields. It does not cover auth/permission requirements or reversal.

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 purpose, then a compact pricing block, then args, then return shape and next step. Every section earns its place, though the Args/Returns lines partially restate schema and output-schema data.

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 lifecycle an agent needs: what is created, defaults, immutable vs mutable fields, the returned fields, and the follow-up call. An output schema exists, yet the description's summary of returns is coherent with it rather than missing anything critical.

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 description coverage is only 43%, so the description must carry weight, and it does: it explains all three pricing_model modes and their corresponding amount fields (amount_minor with the 250000 = 2,500.00 ETB example, minimum_amount_minor, free) plus the status values. It omits the response_format parameter entirely, leaving one 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 product the organization sells') and immediately scopes the outcome (public Jami page url + p_… token). It is clearly distinguished from siblings jami_update_product and jami_get_product without needing to open their schemas.

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

Usage Guidelines4/5

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

Gives clear operative context ('Published by default, so the page and checkouts work immediately') and routes the agent onward ('To charge for it, call jami_create_checkout with product_id = token'). It lacks an explicit when-not-to-use statement (e.g. vs update_product for existing products), so it stops short of a 5.

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

jami_create_test_webhookCreate test webhookA

Build a correctly signed JamiDev webhook delivery for testing a handler locally — no real event needed.

Args:

  • type: 'order.created' | 'order.completed' | 'benefit.granted' | 'checkout.session.expired' | 'withdrawal.paid' | 'withdrawal.failed'.

  • secret: signing secret (defaults to JAMI_WEBHOOK_SECRET; any string works for a local test).

  • data: optional fields to merge over the realistic sample payload.

  • livemode: default false (sandbox).

  • target_url: optional. When set, the delivery is POSTed there (e.g. "http://localhost:3000/webhooks/jami") and the response status is reported.

Returns: { payload, signature, headers, curl } — the exact body and X-JamiDev-Signature to send, plus delivery_status when target_url is set. Handlers must verify the RAW body and reply 2xx within 10 seconds.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataNo
typeYes
secretNo
livemodeNo
target_urlNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
curlYes
headersYes
payloadYes
signatureYes
delivery_errorNo
delivery_statusNo

TDQS

A4.7/5.0
Behavior5/5

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

Annotations declare the safety profile (readOnlyHint=false, openWorldHint=true), and the description adds substantial context beyond them: default secret from JAMI_WEBHOOK_SECRET, livemode defaults to sandbox, target_url triggers an actual POST with reported status, and handlers must verify the RAW body and reply 2xx within 10 seconds. These are genuine operational traits not derivable 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.

Conciseness4/5

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

Front-loaded purpose followed by clean Args/Returns sections; every element is useful. Minor redundancy in re-listing the enum values already present in the schema, but overall tight and well-structured.

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?

Given 5 params, an object-typed field, and an existing output schema, the description still supplies the merge semantics, signing/verification requirements, and timeout constraint an agent needs to use the tool correctly. Nothing material is missing.

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

Parameters5/5

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

Schema description coverage is 0%, so the description carries the full param burden and does so: it documents all five params (type enum, secret default source, data merge-over-sample semantics, livemode sandbox default, optional target_url POST semantics). This fully compensates for the missing schema descriptions.

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?

Specific verb+resource with scope: 'Build a correctly signed JamiDev webhook delivery for testing a handler locally — no real event needed.' The phrase 'no real event needed' distinguishes it from a real webhook flow and from the sibling jami_verify_webhook. An agent can tell what it does 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 Guidelines4/5

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

Clearly states the use case (testing a handler locally) and the condition for the POST behavior (target_url set, response status reported). It does not explicitly name an alternative like jami_verify_webhook or when-not to use it, so it falls short of a 5.

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

jami_get_balanceGet balanceA
Read-onlyIdempotent

Get the organization's withdrawable JamiDev earnings — the ceiling on what jami_create_withdrawal can pay out.

Returns: { balance_minor, balance, eligible, currency }. eligible is false (and balance 0) when the org can't withdraw yet: it's a sandbox org, Developer Mode is off, or KYC isn't approved. The money itself sits in the owner's unified Jami wallet, so a withdrawal can still fail with 402 if that wallet was spent elsewhere.

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
balanceYes
currencyYes
eligibleYes
balance_minorYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations only cover the read-only/idempotent safety profile, so the description usefully adds behavior: what 'eligible=false' means, why balance can be 0, and that a withdrawal can still fail with 402 because funds live in the owner's unified wallet. That last point is non-obvious operational context not derivable from the schema. It stops short of discussing caching, rate limits, or staleness of the balance.

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?

Three tightly-packed sentences: purpose first, return shape second, failure semantics third. No repetition, no filler, and nothing is buried.

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 an output schema and read-only annotations already present, the description only needs to supply the non-structured context, and it does: eligibility gating and the 402 wallet-spend edge case. Slightly thin on the relationship to the other withdrawal siblings (quote/get/list), but complete enough to call correctly.

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?

Only one parameter (response_format) with 100% schema description coverage including its enum values, so the schema fully documents it. The description adds nothing about parameter semantics, which is acceptable at this coverage level but earns only 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?

Specific verb and resource ('Get the organization's withdrawable JamiDev earnings') with an explicit framing as a ceiling relative to the payout sibling jami_create_withdrawal. An agent can distinguish this read tool from the withdrawal/quote 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 Guidelines4/5

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

It ties the tool to jami_create_withdrawal ('the ceiling on what ... can pay out') and explains the conditions under which the tool is useless (sandbox org, Developer Mode off, KYC not approved). Clear context for use, but it never says explicitly when to prefer it over jami_quote_withdrawal or state a precondition/pre-check step.

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

jami_get_checkout_statusGet checkout statusA
Read-onlyIdempotent

Check a checkout session once. The server reconciles with the payment provider on every call, so this resolves even when webhooks are late.

Args:

  • session_id: from jami_create_checkout.

Returns: { session_id, status: 'open' | 'completed' | 'expired', order_id, order_status, amount_minor, amount, expires_at, failure }. When status is 'expired', failure.code explains why: payment_rejected · payment_failed · payment_canceled · payment_timed_out · initiate_failed · session_expired.

Use jami_wait_for_checkout instead if you want to block until the buyer finishes.

ParametersJSON Schema
NameRequiredDescriptionDefault
session_idYesCheckout session id returned by jami_create_checkout, e.g. "6710c2e8b1a2f0012ab34cd9"
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
amountYesHuman-readable amount, e.g. "150.00 ETB"
statusYes
failureYesWhy the session ended without an order; null unless status is "expired"
order_idYes
expires_atYes
session_idYes
amount_minorYesInteger santim (100 = 1.00 ETB)
order_statusYes

TDQS

A4.3/5.0
Behavior4/5

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

Goes well beyond the annotations (readOnlyHint/idempotentHint/openWorldHint) by disclosing server-side reconciliation on every call and enumerating the failure.code values that explain an expired session. It does duplicate the return-value enumeration that the output schema already carries, which caps this slightly below 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-loaded purpose sentence, then clearly labeled Args/Returns blocks, then the alternative-tool line. Nearly every sentence earns its place; the only drag is the return-value enumeration repeating what the output schema provides.

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 read-only polling tool it covers semantics, error decoding, and the sibling choice. Since an output schema exists, the description is not required to describe return values, so the remaining 'gap' is minor rather than material.

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% and the schema already documents both parameters, including that session_id comes from jami_create_checkout, so the Args line is largely redundant. response_format is not mentioned in the description at all. 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 specific verb and resource ('Check a checkout session once') and immediately names the sibling it is not ('Use jami_wait_for_checkout instead if you want to block'). An agent can pick between the two checkout tools without opening either 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 routing rule with the selecting condition: poll with this tool, block with jami_wait_for_checkout. It also gives the operational reason to prefer it ('server reconciles with the payment provider on every call, so this resolves even when webhooks are late'), which is exactly the when-to-use context needed.

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

jami_get_productGet productA
Read-onlyIdempotent

Fetch one product by its p_… token or id: price, status, and its public page url.

ParametersJSON Schema
NameRequiredDescriptionDefault
product_idYesProduct p_… token or id
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYesPublic Jami page where anyone can buy it (published only)
priceYes
titleYes
tokenYesUse as product_id in jami_create_checkout
statusYes
product_idYes
amount_minorYes
pricing_modelYes
minimum_amount_minorYes

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds only the returned-field summary, which the output schema already carries; it discloses nothing extra about cache behavior, errors on unknown ids, or cross-workspace access.

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?

A single tight sentence that front-loads the action and resource and then names the output fields. There is no filler, hedging, or repetition.

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 an output schema present and rich annotations covering safety and idempotency, the description needn't explain return values, and it does briefly note what comes back. The only gap is the absence of routing guidance against the many sibling product/checkout tools, which is minor here.

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% and both parameters (product_id, response_format) are documented in the schema, so the baseline is 3. The description echoes the token/id form of product_id but adds no semantics, such as what happens if the id belongs to another workspace, beyond what the schema provides.

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

Purpose4/5

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

'Fetch one product by its p_… token or id' names a specific verb (fetch), resource (product), and the lookup key, and it enumerates the salient returned fields (price, status, public page url). It clearly reads as a single-item retrieval, implicitly contrasting with jami_list_products, but no sibling is named explicitly, so it stops short of a 5.

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

Usage Guidelines3/5

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

The phrase 'by its p_… token or id' implies the caller must already hold a product identifier, which hints at usage after a list/search. However, there is no explicit when-to-use statement, no mention of alternatives such as jami_list_products for browsing, and no exclusions, so guidance is only implied.

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

jami_get_withdrawalGet withdrawalA
Read-onlyIdempotent

Fetch one withdrawal by id to track it from pending → processing → completed (or rejected).

Args:

  • withdrawal_id: from jami_create_withdrawal or jami_list_withdrawals.

ParametersJSON Schema
NameRequiredDescriptionDefault
withdrawal_idYes
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
netYes
noteNo
amountYes
statusYes
accountYes
gatewayYes
fee_minorYes
net_minorYesSantim that reaches the destination
tax_minorYes
created_atYes
amount_minorYesGross santim debited
withdrawal_idYes
idempotency_keyNo

TDQS

A4.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered structurally. The description adds genuine value by naming the state progression the caller should expect (pending → processing → completed/rejected), but says nothing about auth, polling cadence, or eventual-consistency behavior.

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?

Purpose sentence first, then a compact Args block. Every line earns its place with no restated or decorative text.

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?

An output schema exists, so return values need not be described, and the description covers purpose, lifecycle, and parameter sourcing. It stops short of the operational details (auth scope, behavior while the withdrawal is still pending) that would make it fully self-sufficient.

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 description coverage is only 50%, so the description must carry some weight for withdrawal_id, and it does by documenting provenance (which sibling tool produces the id). The response_format enum is already fully documented inside the schema, so nothing is lost there.

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?

Starts with a specific verb+resource ('Fetch one withdrawal by id') and adds the lifecycle it exists to observe (pending → processing → completed/rejected). The scope word 'one' plus the required id clearly separates it from jami_list_withdrawals and it is distinct from jami_quote_withdrawal.

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

Usage Guidelines4/5

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

It states the practical context (tracking a withdrawal's status) and tells the agent where the id comes from ('jami_create_withdrawal or jami_list_withdrawals'). It does not, however, say when to prefer this over jami_list_withdrawals or a wait/poll alternative, so no explicit exclusions.

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

jami_list_ordersList ordersA
Read-onlyIdempotent

List the organization's orders, newest first, one page at a time.

Args:

  • status: 'paid' | 'pending' | 'failed' (optional filter).

  • page: 1-based page (default 1).

  • limit: 1–100 per page (default 20).

Returns: { orders: [{ order_id, status, amount_minor, amount, product: { id, title }, customer: { id, email, name }, paid_at, created_at, metadata }], total, page, limit, count, has_more, next_page }.

To total revenue or find a specific buyer, page through with next_page until has_more is false. Amounts are integer santim (100 = 1.00 ETB); this is what buyers paid, before any withdrawal fee.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
limitNo
statusNo
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
countYesRecords in this page
limitYes
totalYesTotal matching records
ordersYes
has_moreYes
next_pageNoPass as `page` to fetch the next page

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description adds genuinely new behavioral context: newest-first ordering, page-at-a-time retrieval with defaults, and the unit/semantics of amounts ('integer santim, 100 = 1.00 ETB ... before any withdrawal fee'). No rate limits or auth requirements are mentioned, keeping it out of 5 territory.

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 purpose sentence followed by tightly formatted Args/Returns/Notes blocks; each line carries information. The Returns block restates a payload that an output schema already defines, which is mild redundancy, though the accompanying santim/fee note justifies its presence.

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?

Beyond pagination mechanics, it supplies the amount unit convention and the 'before withdrawal fee' caveat, which cannot be inferred from the schema or output schema. Combined with the documented filters and paging contract, an agent has everything needed to call and interpret this tool 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 description coverage is only 25%, so the description carries the load and does so for three of four params: status filter values, page being 1-based with default 1, and limit range 1–100 with default 20. It silently omits response_format (markdown vs json), which is the one parameter the schema documents and which materially changes what the agent receives.

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

Purpose4/5

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

States a specific verb and resource ('List the organization's orders') plus scope and ordering ('newest first, one page at a time'). It is clearly distinguishable from sibling list tools on other resources (withdrawals, products), but it never names a sibling or an alternative to route against, so it stops short of a 5.

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

Usage Guidelines4/5

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

Gives a concrete usage path: 'To total revenue or find a specific buyer, page through with next_page until has_more is false.' That tells the agent how to satisfy a goal, which is real guidance. It does not state when *not* to use this tool or name a preferred alternative, so no exclusions are covered.

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

jami_list_productsList productsA
Read-onlyIdempotent

List the organization's products, newest first.

Args: status ('published' | 'draft' | 'archived', optional), page (default 1), limit 1–100 (default 20).

Returns: { products: [{ product_id, token, url, title, status, pricing_model, price }], total, page, limit, count, has_more, next_page }.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
limitNo
statusNo
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
countYesRecords in this page
limitYes
totalYesTotal matching records
has_moreYes
productsYes
next_pageNoPass as `page` to fetch the next page

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive). The description adds genuinely new behavioral context beyond them: the 'newest first' ordering and pagination behavior (has_more, next_page). It stops short of noting auth requirements or how an omitted status filter behaves.

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 purpose, then a compact Args block and a Returns block with no filler. The Returns enumeration is somewhat redundant since an output schema exists, but it is short and does not bloat the definition.

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 an output schema present, return values are already covered, and the description adds the small amount of context an agent needs (ordering, defaults, filters) to invoke it correctly. It lacks only auth/permission notes and filter-combination semantics, which are minor for a read-only list tool.

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 description coverage is only 25%, so the description must compensate, and it documents status enum values, page default, and the limit range (1–100, default 20). The one param it omits, response_format, is the sole param already documented in the schema, so combined coverage is effectively complete.

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

Purpose4/5

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

States a specific verb+resource with scope and ordering: 'List the organization's products, newest first.' It is clearly distinguishable from jami_get_product and jami_create_product by the list/get/create verb, though no sibling is named explicitly.

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

Usage Guidelines3/5

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

Usage is implied by the tool name and the status filter, but there is no explicit statement of when to use this versus jami_get_product or jami_list_orders, and no prerequisites or exclusions are given.

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

jami_list_withdrawalsList withdrawalsA
Read-onlyIdempotent

List the organization's withdrawals, newest first.

Args:

  • status: 'pending' | 'reviewing' | 'approved' | 'rejected' | 'processing' | 'completed' (optional).

  • page (default 1), limit 1–100 (default 20).

Returns: { withdrawals: [...], total, page, limit, count, has_more, next_page }.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
limitNo
statusNo
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
countYesRecords in this page
limitYes
totalYesTotal matching records
has_moreYes
next_pageNoPass as `page` to fetch the next page
withdrawalsYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so safety is covered. The description adds genuinely non-derivable behavior: result ordering (newest first) and that the result set is org-scoped and pageable with has_more/next_page. It stops short of auth requirements or rate-limit/consistency caveats.

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 behavior, then a tidy Args block and a Returns line — well sized and easy to scan. The Returns line is largely redundant given a full output schema exists, which is the only wasted content.

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 an output schema present, the description does not need to explain the payload, yet it still restates the envelope; the more valuable coverage (ordering, filters, pagination limits) is there. What's missing — auth scope, what qualifies as a withdrawal record, and why response_format matters — is minor given the structured fields.

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 description coverage is only 25% (just response_format), so the description must carry the other three parameters — and it does enumerate status values, page default, and the 1–100 limit range. Much of that restates the schema's own enums/defaults, and response_format is never mentioned in the Args block, so it is not fully compensating.

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

Purpose4/5

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

The description gives a specific verb and resource ('List the organization's withdrawals') plus the ordering ('newest first'), so the agent knows exactly what comes back. It does not, however, contrast itself against the close sibling jami_get_withdrawal, leaving the singular-vs-list distinction to be inferred from names alone.

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

Usage Guidelines3/5

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

Usage is implied by the optional status filter and pagination defaults — an agent can infer this is for browsing/filtering the org's withdrawal queue. There is no explicit statement of when to use this instead of jami_get_withdrawal or jami_quote_withdrawal, and no stated prerequisites or exclusions.

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

jami_quote_withdrawalQuote withdrawalA
Read-onlyIdempotent

Preview what reaches the destination for a withdrawal — offline, no API call, works without a token.

The JamiDev usage fee (7% unless Jami set a custom rate on the account) and any government tax are cut FROM the amount: you withdraw amount, the account receives net. Rounding is round-half-up per component. The server is authoritative; the real breakdown comes back on the withdrawal.

Args:

  • amount_minor: gross santim (min 10000 = 100.00 ETB).

  • fee_rate / tax_rate: optional overrides (0–1) if you know the account's real rates.

Returns the breakdown plus whether the amount auto-pays (≤ 10,000 ETB) or goes to manual review, and the per-org 100,000 ETB rolling-24h cap.

ParametersJSON Schema
NameRequiredDescriptionDefault
fee_rateNo
tax_rateNo
amount_minorYesGross amount in integer santim — the fee is cut from this. 10000 = 100.00 ETB (the minimum).
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
fee_rateYes
tax_rateYes
fee_minorYes
net_minorYes
tax_minorYes
auto_payoutYestrue when ≤ 10,000 ETB — paid out without manual review
amount_minorYes
meets_minimumYes
within_daily_capYes

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so safety is carried structurally. The description adds non-obvious behavior: 7% default fee unless a custom rate is set, government tax cut from the gross, round-half-up per component, server is authoritative, and the 10,000 ETB auto-pay threshold and 100,000 ETB rolling-24h cap. This is real behavioral context beyond the annotations.

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 one-line purpose, then the fee/tax mechanics and the return summary, then args. Every sentence carries information; mildly dense but nothing extraneous.

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?

An output schema exists so return values needn't be fully enumerated, and the description still summarizes what comes back (breakdown, auto-pay vs. manual, cap). With annotations covering safety, params and mechanics covered, and boundaries stated, an agent has everything needed to call 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 50%; the description documents amount_minor's meaning (gross santim, minimum 10000), that fee/tax are optional 0–1 overrides representing the account's real rates, and that the fee is cut FROM the gross so the account receives net. It does not describe response_format, leaving that 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?

Specific verb+resource ('preview what reaches the destination for a withdrawal') and immediately distinguishes from the mutation siblings jami_get_withdrawal/jami_list_withdrawals by stating it's offline and needs no token. An agent can route to it or away from it 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 states when to use (preview, no API call, no token) and when not (the authoritative breakdown comes from the real withdrawal). Also fills the critical decision boundary: which amounts auto-pay vs. go to manual review.

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

jami_read_docRead Jami doc pageA
Read-onlyIdempotent

Read one JamiDev docs page as markdown, with every code sample intact.

Args:

  • path: a docs path from jami_search_docs, e.g. "/docs/webhooks", "api/checkout", or a full URL. Use "/docs" for the overview.

  • offset: character offset for long pages (default 0); the result says where to continue.

Returns: { title, url, markdown, offset, next_offset? }.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes
offsetNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYes
titleYes
offsetYes
markdownYes
next_offsetNo

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely new behavior: output is markdown with code samples intact, and long pages are paginated via offset with the result indicating where to continue.

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?

Front-loaded with the core action, then cleanly separated Args and Returns blocks with no filler sentences. Every line either defines a parameter or the return shape.

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?

An output schema exists, and the description still summarizes the return shape ({ title, url, markdown, offset, next_offset? }) and explains pagination, so an agent knows both how to call it and how to handle long pages. Nothing material is missing for a two-argument read tool.

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

Parameters5/5

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

Schema coverage is 0%, so the description must carry parameter meaning, and it does: it gives example path forms ("/docs/webhooks", "api/checkout", full URL), a special value for the overview, and explains offset as a continuation cursor with a default of 0 and a next_offset hint in the result.

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 ("Read one JamiDev docs page as markdown") and adds the format detail that code samples are preserved. It implicitly separates itself from the sibling jami_search_docs by framing itself as reading a single page whose path comes from search.

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

Usage Guidelines4/5

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

It tells the agent where the path argument comes from (jami_search_docs) and gives a concrete fallback ("Use '/docs' for the overview"), which establishes the intended workflow. It stops short of explicit when-not guidance, but the context for selecting this tool versus search is clear.

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

jami_search_docsSearch Jami docsA
Read-onlyIdempotent

Search the official JamiDev developer docs (https://dev.jami.bio/docs) — the source of truth for integrating Jami payments. Works without an API token.

Use this before writing integration code: SDK usage, REST endpoints, webhooks and signature checks, sandbox magic numbers, Sign in with Jami (OAuth/OIDC), the wallet API, the browser storefront, fees and limits.

Args:

  • query: what you need, e.g. "verify webhook signature express", "pay what you want amount", "withdrawal fee".

  • limit: 1–10 results (default 5).

Returns: { results: [{ title, path, url, snippet }] }. Read a full page with jami_read_doc(path).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultsYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, and open-world behavior, so the safety profile is covered. The description adds genuinely useful context beyond that: it works without an API token, and it discloses the return shape and the search-then-read workflow. It doesn't state ranking or pagination behavior, keeping it below 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.

Conciseness5/5

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

Front-loaded purpose sentence, then a scoping paragraph, then Args and Returns blocks. Every line carries information; nothing is padding.

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?

An output schema exists, yet the description still sketches the result fields and points to jami_read_doc for full pages, covering the search-then-read loop end to end. Nothing an agent needs to invoke this 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 0%, so the description must compensate, and it does: it gives concrete query examples ('verify webhook signature express', 'withdrawal fee') and restates the limit default and 1–10 range. It omits the query length constraints (2–200 chars) present in the schema, so not a full 5.

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 ('Search the official JamiDev developer docs') and scopes it as the source of truth for Jami payments. The topic list (SDK, REST, webhooks, OAuth, wallet API) makes it clearly distinct from siblings like jami_read_doc and jami_get_checkout_status.

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?

'Use this before writing integration code' states the when explicitly, and it names the follow-up alternative ('Read a full page with jami_read_doc(path)'), drawing the search-vs-read boundary. No inference required.

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

jami_update_productUpdate productA
Idempotent

Change a product's title, description, status or price amount. The pricing model itself is locked.

Args: product_id (p_… token or id), and any of: title, description, status ('published' | 'draft' | 'archived' — archived stops new sales), amount_minor (fixed price), minimum_amount_minor (flexible floor).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNo
statusNo
product_idYesProduct p_… token or id
descriptionNo
amount_minorNo
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown
minimum_amount_minorNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYesPublic Jami page where anyone can buy it (published only)
priceYes
titleYes
tokenYesUse as product_id in jami_create_checkout
statusYes
product_idYes
amount_minorYes
pricing_modelYes
minimum_amount_minorYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already cover safety (readOnlyHint=false, idempotentHint=true, destructiveHint=false), but the description adds real behavioral context beyond them: pricing model is locked, 'archived' stops new sales, and updates are partial ('any of'). It is silent on auth requirements, error behavior, and what happens if both amount_minor and minimum_amount_minor are sent.

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 purpose, then a compact args list; every sentence is doing work. The terse 'Args:' pseudo-syntax is dense but readable, with only minor redundancy between the first sentence and the field list.

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?

An output schema exists (and response_format is documented in the schema), so return values need no explanation here. For a partial-update tool with annotations present, the description covers the fields and key constraints well; the main gap is how the two price parameters interact when supplied together.

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?

With only 29% schema description coverage, the description carries most of the burden and largely succeeds: it explains product_id's token form, the status enum values with the semantic effect of 'archived', and — critically — that amount_minor is a fixed price while minimum_amount_minor is a flexible floor. It omits response_format and the length bounds, which the schema handles.

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

Purpose4/5

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

States a specific verb and resource ('Change a product's title, description, status or price amount') and enumerates the mutable fields. It clearly is the mutation counterpart to jami_create_product and jami_get_product, but it never explicitly names or contrasts those siblings.

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

Usage Guidelines3/5

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

Usage is implied by 'Change...' and 'any of' (partial update), but there is no explicit when-to-use/when-not-to-use guidance, no prerequisite or permission notes, and no pointer to alternatives such as create vs update. The 'pricing model itself is locked' line hints at a constraint but does not guide tool selection.

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

jami_verify_webhookVerify webhookA
Read-onlyIdempotent

Check whether a webhook delivery is genuine — the same timing-safe HMAC check and replay guard the SDK runs. Use it to debug "signature mismatch" errors in a handler.

Args:

  • payload: the RAW request body exactly as received (not re-serialized JSON — whitespace matters).

  • signature: the X-JamiDev-Signature header, "t=,v1=".

  • secret: the subscription's webhook secret (defaults to JAMI_WEBHOOK_SECRET).

  • tolerance_seconds: max age of the timestamp (default 300). Raise it to check an old captured delivery.

Returns: { valid, reason, event_type, event_id, livemode }. An invalid signature is a normal result (valid: false), not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
secretNo
payloadYesRaw request body
signatureYesX-JamiDev-Signature header value
tolerance_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
validYes
reasonYes
event_idYes
livemodeYes
event_typeYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover safety (readOnly/idempotent/non-destructive), and the description adds real behavioral context beyond them: it discloses the timing-safe HMAC + replay-guard semantics and, crucially, that 'an invalid signature is a normal result (valid: false), not an error' — a key invocation expectation an agent would otherwise get wrong.

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?

Front-loaded purpose sentence, then clearly labeled Args and Returns sections. No filler; each line (raw-body caveat, signature format, default source, invalid-is-normal) earns its place.

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 the 50% schema coverage gap, the description documents all four parameters, the return shape, and the non-error semantics of a failed check. Nothing an agent needs to invoke or interpret this tool correctly is missing.

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

Parameters5/5

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

Schema coverage is only 50% (payload/signature documented; secret/tolerance_seconds not), but the Args block fully compensates: it explains payload must be the RAW body ('whitespace matters'), the exact signature format 't=<unix>,v1=<hex>', that secret defaults to JAMI_WEBHOOK_SECRET, and the tolerance rationale for old deliveries.

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 (check/verify) and resource (webhook delivery), and immediately qualifies what 'genuine' means — 'the same timing-safe HMAC check and replay guard the SDK runs'. An agent can tell this apart from sibling jami_create_test_webhook, which creates rather than verifies.

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

Usage Guidelines4/5

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

Gives a concrete when-to-use scenario: 'Use it to debug "signature mismatch" errors in a handler.' That is clear context, but it names no alternatives or exclusions (e.g. when to generate a test webhook instead), so it stops short of a 5.

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

jami_wait_for_checkoutWait for checkoutA
Read-onlyIdempotent

Poll a checkout session until it's paid or ends, up to timeout_seconds. Reports progress while it waits.

If the buyer hasn't finished when the timeout hits, this returns status 'open' (not an error) — call it again to keep waiting. Sessions expire 30 minutes after creation.

Args:

  • session_id: from jami_create_checkout.

  • timeout_seconds: 5–300 (default 90).

  • interval_seconds: 2–30 between polls (default 3).

Returns the same shape as jami_get_checkout_status.

ParametersJSON Schema
NameRequiredDescriptionDefault
session_idYesCheckout session id returned by jami_create_checkout, e.g. "6710c2e8b1a2f0012ab34cd9"
response_formatNo'markdown' (default) for a readable summary, 'json' for the full structured payloadmarkdown
timeout_secondsNo
interval_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
amountYesHuman-readable amount, e.g. "150.00 ETB"
statusYes
failureYesWhy the session ended without an order; null unless status is "expired"
order_idYes
expires_atYes
session_idYes
amount_minorYesInteger santim (100 = 1.00 ETB)
order_statusYes

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent and non-destructive, but the description adds genuinely new behavior: a timeout returns status 'open' rather than an error, progress is reported while waiting, and sessions expire after 30 minutes. These operational details go meaningfully beyond the annotation set.

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 behavior, then edge case, then a structured Args block. The Args section partially duplicates the schema, but given the missing schema descriptions for two parameters it earns its place rather than being pure repetition.

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?

An output schema exists and the description correctly defers to it by pointing at jami_get_checkout_status for the return shape. The timeout-as-status behavior, retry loop, and expiration window give an agent everything needed to drive it correctly; only the get-vs-wait tradeoff is left implicit.

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?

With only 50% schema coverage, the description carries weight: it supplies the 5–300 range and default 90 for timeout_seconds and 2–30/default 3 for interval_seconds, which the schema declares only as min/max. It omits response_format, which the schema documents, so compensation is partial but effective for the two undocumented parameters.

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

Purpose4/5

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

States a specific verb and resource ('Poll a checkout session until it's paid or ends, up to timeout_seconds') with scope and stopping conditions front-loaded. It distinguishes itself from jami_get_checkout_status by framing itself as a persistent poller rather than a one-shot read, though it never says so explicitly.

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

Usage Guidelines4/5

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

Gives clear context: call it again after a timeout returns 'open', and notes sessions expire 30 minutes after creation. It stops short of an explicit when-not clause naming jami_get_checkout_status as the single-check alternative, so the routing guidance is contextual rather than exhaustive.

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. 16 tool updatesv0.2.0
    • First observedjami_create_checkout
    • First observedjami_create_product
    • First observedjami_create_test_webhook
    • First observedjami_get_balance
    • First observedjami_get_checkout_status
    • First observedjami_get_product
    • First observedjami_get_withdrawal
    • First observedjami_list_orders
    • First observedjami_list_products
    • First observedjami_list_withdrawals
    • First observedjami_quote_withdrawal
    • First observedjami_read_doc
    • First observedjami_search_docs
    • First observedjami_update_product
    • First observedjami_verify_webhook
    • First observedjami_wait_for_checkout

TDQS

A4.1/5.0

Scored across 16 tools

Disambiguation5/5

Each tool targets a distinct resource+action, and the trio of checkout tools (create/get_status/wait) is explicitly differentiated in the descriptions ("use jami_wait_for_checkout instead if you want to block"). Product, order, withdrawal, webhook, and docs tools occupy clearly separate niches with no real overlap.

Naming Consistency5/5

Every tool uses the jami_ prefix followed by a consistent verb_noun pattern (create_checkout, get_product, list_products, verify_webhook, read_doc). No mixed conventions or vague verbs anywhere in the set.

Tool Count5/5

16 tools is well-scoped for a payments platform spanning checkout, products, orders, withdrawals, webhooks, and docs. Each tool earns its place; nothing is redundant padding.

Completeness3/5

The withdrawal lifecycle is notably incomplete: descriptions reference jami_create_withdrawal ("from jami_create_withdrawal or jami_list_withdrawals") but no such tool is exposed, so agents can quote/get/list withdrawals but never initiate one. Orders also lack a single-get or refund operation, though the core checkout and product CRUD flows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers