Wayl MCP
This server integrates the Wayl payments API (Iraqi Dinar) into AI assistants, enabling creation, management, and monitoring of payment links, products, refunds, and webhooks.
Payment Link Creation:
create_payment_link– full control over line items, webhooks, redirects, and custom parameters.sell_item/sell_book– quick sale with automatic price breakdowns, unique reference IDs, and checkout URL generation.
Order & Link Management:
check_order_paid– verify if an order is paid and safe to fulfil (distinguishes sandbox vs. real payments).get_payment_link– fetch a single link by reference ID.list_payment_links– list all links, filterable by status.get_payment_links_batch– look up to 100 links at once with missing-ID report.invalidate_payment_link– cancel a link unconditionally (irreversible).invalidate_payment_link_if_pending– cancel only if still pending.
Product Catalog:
list_products– list all products (Digital, Physical, Service) with stock and variants.get_product– fetch details for a single product.
Refunds:
create_refund– request a refund with a 100–1500 character justification.list_refunds– list refund requests, filterable by status or order reference.get_refund– fetch a single refund by its Wayl ID.cancel_refund– withdraw a pending refund request.
Webhooks & Diagnostics:
parse_webhook– verify HMAC-SHA256 signature and report payment status.verify_webhook– perform signature check only (local, no network).verify_auth_key– test API key validity.wayl_status– show server configuration without network calls.
wayl-mcp
An MCP server for the Wayl payments API — take payments online in Iraq from an AI assistant.
Ask your assistant to "charge 25,000 dinars for a consultation" and it creates the payment link, hands you the checkout URL, and can tell you later whether the customer actually paid. Works for anything you sell: physical goods, digital downloads, services, tickets, invoices.
Wayl is an Iraqi payment gateway. All amounts are in Iraqi Dinar (IQD).
Setup
You need an API key. Wayl's guide says to email jisr@wayl.io to request a merchant
token; their API reference says it is in your merchant dashboard. Try the dashboard
first, then email. Your store must be verified before it can create links.
uv syncThen set the key:
export WAYL_API_KEY="your-merchant-token"Check it works:
uv run python -c "import asyncio, wayl_mcp.server as s; print(asyncio.run(s.verify_auth_key()))"Related MCP server: PayPal
Connecting it
Claude Code
claude mcp add wayl --env WAYL_API_KEY=your-merchant-token -- uv run --directory /absolute/path/to/wayl_MCP wayl-mcpClaude Desktop
In claude_desktop_config.json:
{
"mcpServers": {
"wayl": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/wayl_MCP", "wayl-mcp"],
"env": {
"WAYL_API_KEY": "your-merchant-token",
"WAYL_ENV": "test"
}
}
}
}Use an absolute path — the server is launched from an arbitrary working directory.
Configuration
Variable | Default | Purpose |
| — | Required. Merchant token, sent as |
|
| Default environment for new links: |
|
| API host. |
| — | Default webhook URL for new links. |
| — | Default webhook signing secret (10–255 chars). |
| — | Where buyers land after paying. |
|
| Prefix for generated order IDs. |
|
| HTTP timeout in seconds. |
WAYL_ENV defaults to test so nothing moves real money until you opt in. Set it
to live when you are ready to actually sell, or pass env="live" per call.
While in test mode, check_order_paid and parse_webhook report paid: true for a
completed sandbox checkout but safeToFulfil: false — the payment is simulated, so the
order should not be fulfilled. Branch on safeToFulfil, not paid.
Tools
Selling
Tool | Does |
| Create a checkout link for a simple sale, with the price breakdown filled in. |
| Answer whether an order is paid and safe to fulfil. |
| Create a payment link with full control over every field. |
Links
Tool | Does |
| Fetch one link and its status. |
| List links, newest first, filterable by status. |
| Look up to 100 links at once; reports which were missing. |
| Cancel an unpaid link. |
| Cancel it only if still pending. |
Products
Tool | Does |
| List your Wayl catalogue (Digital, Physical, Service). |
| Fetch one product's details. |
Refunds
Tool | Does |
| Request a refund. Needs a 100+ character justification. |
| List refund requests. |
| Fetch one refund. |
| Withdraw a refund still in |
Webhooks and diagnostics
Tool | Does |
| Verify a webhook's signature and report whether the order is paid. |
| Signature check alone. |
| Confirm the API key works. |
| Show how the server is configured, without calling the API. |
Read-only tools are marked readOnlyHint; refunds and invalidations are marked
destructiveHint so your client can ask before running them.
Taking a payment
Creating the link:
Sell "Wireless keyboard" for 30000 IQD with 5000 delivery
sell_item builds the line items, generates a unique reference ID, and returns a
checkout URL like https://checkout.thewayl.com/pay/I94F590I. Send that to the
customer. It works the same for a service, a ticket or a digital download — set
delivery_fee=0 when nothing ships.
For full control over webhooks, redirects and custom line items, use
create_payment_link instead.
Finding out whether they paid — either poll:
Has order order-wireless-keyboard-a1b2c3 been paid?
or receive a webhook. Set webhookUrl and webhookSecret when creating the link, then
pass each incoming request to parse_webhook, which verifies the signature and tells
you whether to fulfil.
Webhooks
Wayl signs each delivery with HMAC-SHA256 over the raw request body, sending the
hex digest in the x-wayl-signature-256 header.
Three things that break integrations:
Hash the raw bytes.
json.dumps(json.loads(body))changes whitespace and key order, so the digest will not match. Verify before you parse.Wayl sends
Content-Type: text/plain, so JSON body parsers may hand you an empty body. Read the raw body yourself.Deduplicate on the payload's
id. There is no timestamp in the signature, so a captured request replays forever — and Wayl retries on timeout, so duplicates happen in normal operation too.
The webhook reports paymentStatus: "Paid", which is not one of the eight link
statuses the REST API uses. parse_webhook handles that distinction.
Development
uv run pytestuv run ruff check src testsSee CLAUDE.md for architecture notes and the API's sharp edges.
Licence
MIT
Available Tools
18 toolscancel_refundADestructive
Withdraw a refund request before Wayl acts on it, so no money is returned.
Only refunds still in status 'Requested' can be cancelled. Once Wayl has moved one
to Refunded or Rejected this call will not take it back, so check with `get_refund`
first when you are unsure of the state.
`refund_id` is Wayl's own ID for the refund — the `id` returned by `create_refund`
— not your order's reference ID. If you only have the order, find it with
`list_refunds(reference_id=...)`.
This touches the refund request only; the payment link and the buyer's completed
payment are unaffected. To stop a buyer paying in the first place, use
`invalidate_payment_link_if_pending` instead.
Confirm with the user before calling. Undoing it means filing a fresh refund with
a new 100-character reason, and Wayl reviews that from scratch.
| Name | Required | Description | Default |
|---|---|---|---|
| refund_id | Yes | Wayl's own ID for the refund — the `id` field in the `create_refund`, `get_refund` or `list_refunds` response. NOT your order's reference ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark the tool as destructive, but the description adds meaningful context: it only affects the refund request, not the payment link or buyer's payment, requires user confirmation, and the undo involves filing a fresh refund with a new reason and re-review. This goes well beyond the annotation hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries necessary information—state constraints, ID disambiguation, side effects, alternatives, and caution. The structure flows logically from action to limitations to confirmation, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, state-dependent tool, the description covers prerequisites, scope of impact, user confirmation, and consequences. An output schema exists, so return-value documentation is not needed here. The description is fully self-sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already thoroughly describes refund_id with 100% coverage. The description reinforces this and adds how to find the ID when only the order reference is available (list_refunds with reference_id). This exceeds the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Withdraw a refund request before Wayl acts on it, so no money is returned.' It clearly identifies the resource (refund request) and the effect, and differentiates from sibling tools like invalidate_payment_link_if_pending.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use and when-not-to-use guidance: only for 'Requested' status, not for 'Refunded' or 'Rejected', suggests checking get_refund first, and names the alternative invalidate_payment_link_if_pending for stopping payment. Also gives direction to list_refunds when only the order reference is known.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_order_paidARead-onlyIdempotent
Answer whether an order is paid and safe to fulfil, from your reference ID.
Returns `paid: true` only for statuses Complete or Delivered. Wayl documents the
names of its eight link statuses and nothing else, so this server treats only
those two as settled. Check this before sending a download link or shipping a
copy — a link in status Created or Pending means the buyer has not paid yet.
`paid` and `safeToFulfil` are not the same thing. While this server is in test
mode, a settled payment is a sandbox simulation that moved no real money, so
`safeToFulfil` stays false even when `paid` is true. Act on `safeToFulfil`.
Read-only, so poll it as often as you need. When a webhook delivery arrives use
`parse_webhook` instead — it authenticates the payload and reads the webhook's
separate `paymentStatus` vocabulary. For the full link record use
`get_payment_link`; to reconcile many orders use `get_payment_links_batch`.
The returned `total` is a string, as Wayl sends it. Parse it before arithmetic.
| Name | Required | Description | Default |
|---|---|---|---|
| reference_id | Yes | Your own order ID — the referenceId used when the link was created. Not Wayl's internal link ID and not the checkout `code`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only and idempotent annotations, the description explains the exact semantics of `paid` (only Complete or Delivered statuses), the crucial distinction between `paid` and `safeToFulfil`, the test-mode behavior where `safeToFulfil` stays false, and the string type of `total`. This adds substantive context not available from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
While the description is long, every sentence earns its place by explaining status mappings, the safeToFulfil distinction, usage guidance, and return field types. It is well-structured, front-loaded with the core answer, and contains no redundant fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully accounts for the tool's complexity by explaining the return fields (`paid`, `safeToFulfil`, `total`), the test-mode edge case, and the correct usage context. Even with an output schema present, it adds necessary business logic not inferable from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description for `reference_id` already provides 100% coverage, explaining it is the user's own order ID and not Wayl's internal link ID or checkout code. The description adds no new parameter syntax or format, so it does not significantly enhance the schema's semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'Answer whether an order is paid and safe to fulfil, from your reference ID,' which is specific and distinguishes it from related tools like `parse_webhook` and `get_payment_link` by referencing alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs when to use the tool ('Check this before sending a download link or shipping a copy') and provides alternative tools for other scenarios ('When a webhook delivery arrives use `parse_webhook` instead; for the full link record use `get_payment_link`; to reconcile many orders use `get_payment_links_batch`').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_payment_linkA
Create a Wayl payment link and return the checkout URL to send the buyer.
This is the general-purpose builder. For selling a book, `sell_book` is usually less
work — it derives the line items and reference ID for you.
The returned `url` is the hosted checkout page. Nothing is charged until the buyer
completes payment there; poll `check_order_paid` or handle the webhook to learn when
that happens. env='live' takes the buyer's real money; env='test' charges nobody.
`reference_id` must be unique across every link you have ever created; omit it and
one is generated. Passing `webhook_url` without `webhook_secret` is refused — an
unsigned notification cannot be authenticated.
Record the response's `code` and any `webhook_secret` you pass: neither is returned
by any other Wayl endpoint, and no read endpoint reports a link's `env` either. This
call is never retried and Wayl has no idempotency key, so after a timeout check
`get_payment_link` before creating a second link.
| Name | Required | Description | Default |
|---|---|---|---|
| env | No | 'live' takes real money, 'test' is a sandbox that charges nobody. Defaults to 'test'. | |
| total | Yes | Amount to charge in whole IQD. Minimum 1000. | |
| currency | No | Currency code. Wayl settles in IQD only. | IQD |
| line_items | No | Optional cost breakdown shown at checkout. The amounts must reconcile to `total` — increases minus decreases, or the plain sum of every amount; Wayl does not document which, so either is accepted. | |
| webhook_url | No | URL Wayl POSTs to when the payment status changes. | |
| reference_id | No | Your unique order ID. Must never repeat across your links. Omit to have one generated. | |
| webhook_secret | No | Shared secret used to sign webhooks, so you can prove a notification really came from Wayl. | |
| redirection_url | No | Where to send the buyer after paying. Wayl appends referenceId and orderid as query parameters. | |
| custom_parameter | No | Free-form string echoed back to you, for your own tracking. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, openWorldHint=true), the description reveals crucial behaviors: 'Nothing is charged until the buyer completes payment there,' env='test' charges nobody, uniqueness requirements for reference_id, refusal of unsigned webhooks, and the fact that `code` and `webhook_secret` are not retrievable later. It also notes the call is never retried and has no idempotency key, providing comprehensive operational transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet information-dense, with each sentence serving a distinct purpose: purpose, alternative, charge behavior, reference_id uniqueness, webhook constraint, data irrecoverability, and idempotency warning. It is front-loaded with the primary action and avoids redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (9 parameters, output schema, annotations), the description covers all critical operational aspects: return value semantics, environmental differences, webhook security pairing, uniqueness constraints, data persistence caveats, and retry behavior. It leaves no major gaps that would cause an agent to misuse the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds significant value by explaining parameter interdependencies (e.g., 'Passing `webhook_url` without `webhook_secret` is refused'), uniqueness requirements, and the ambiguity in line_items reconciliation. It also clarifies the meaning of env values and the irrecoverability of `code` and `webhook_secret`, enriching the schema's bare definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create a Wayl payment link and return the checkout URL to send the buyer,' a specific verb+resource statement that clearly distinguishes this from siblings like `sell_book` and `get_payment_link`. It further clarifies that this is the 'general-purpose builder,' reinforcing its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly contrasts with the sibling tool: 'For selling a book, `sell_book` is usually less work — it derives the line items and reference ID for you.' It also explains when to poll `check_order_paid` and warns about the env distinction, giving clear context for when to use this tool vs alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_refundADestructive
Request a refund against a paid order. This sends real money back to a customer.
The order must already be paid and linked to a customer, and `amount` may not exceed
what the buyer actually paid — run `check_order_paid` first if you are unsure the
order settled.
Wayl reviews the request, so the refund starts in status 'Requested' rather than being
applied immediately; while it sits there you can still withdraw it with `cancel_refund`.
Once Wayl moves it to 'Refunded' there is no undo, so confirm the amount with the user
before calling.
This POST is never retried automatically and Wayl offers no idempotency key: call it
twice and you have two refunds. Save the returned `id` — `get_refund` and `cancel_refund`
need it, and `list_refunds` is the only other place to recover it.
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | Amount to return in whole IQD. Minimum 1000, and no more than what the buyer actually paid. | |
| reason | Yes | Why the refund is warranted. Wayl requires 100-1500 characters — state what was bought, what went wrong, and what the customer asked for. | |
| reference_id | Yes | Reference ID of the paid order to refund. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotation `destructiveHint: true`, the description discloses critical behavioral traits: the refund is irreversible once 'Refunded', there is no idempotency key so duplicate calls create duplicate refunds, and the returned `id` must be saved for `get_refund`/`cancel_refund`. It also notes the POST is never retried. This is rich, non-obvious context that annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet information-dense. Every sentence serves a purpose: what it does, prerequisites, approval flow, cancellation option, irreversibility warning, idempotency caveat, and ID recovery advice. The structure is logical, moving from action to lifecycle to cautions, with no redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's destructive nature and the existence of an output schema, the description covers all essential context: prerequisite conditions, workflow states, error-prone amount ceiling, no-undo warning, duplicate-risk, retry policy, and how to recover the ID. It fully equips an agent to invoke the tool correctly and handle follow-ups.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage with clear descriptions for `reference_id`, `reason`, and `amount`. The description reinforces the amount constraint ('may not exceed what the buyer actually paid') and the reason length requirement, but adds no new per-parameter semantics beyond what the schema states. This meets the baseline for fully documented schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Request a refund against a paid order.' It clarifies the real-world effect ('sends real money back') and distinguishes from sibling tools like `list_refunds`, `get_refund`, and `cancel_refund` by focusing on the creation action. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance. It instructs calling `check_order_paid` first if unsure, notes that Wayl reviews the request so it starts as 'Requested', and explains that `cancel_refund` can withdraw it while pending. This clearly orients the agent relative to alternatives and prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_payment_linkARead-onlyIdempotent
Fetch one payment link by your reference ID, including its current status.
Use this to inspect a single order: status, total, timestamps, checkout url. To
answer "can I deliver yet?", call `check_order_paid` instead — it applies the
paid / safeToFulfil verdict rather than leaving you to interpret the status. For many
orders use `get_payment_links_batch`; to browse without knowing IDs use
`list_payment_links`.
Read-only, no side effects. The checkout `code` is returned only by link creation,
and `lineItem` and `webhookSecret` are never echoed back by any endpoint — this call
cannot recover them. `total` comes back as a string, so parse it before doing
arithmetic, and `env` is absent because Wayl never reports which environment a link
belongs to.
| Name | Required | Description | Default |
|---|---|---|---|
| reference_id | Yes | Your own order reference ID, exactly as passed when the link was created. This is not Wayl's internal link `id`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, openWorldHint, idempotentHint), the description adds valuable behavioral specifics: 'Read-only, no side effects,' plus the caveats that checkout `code` is only returned at creation, `lineItem` and `webhookSecret` are never echoed, `total` arrives as a string needing parsing, and `env` is never reported. These are non-obvious traits that help the agent avoid misinterpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then adds compact usage guidance and caveats in four sentences. Every sentence adds relevant information (alternatives, side effects, field behaviors, type gotcha), with no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has one parameter and an output schema, but the description still covers return fields (status, total, timestamps, checkout url) and details which fields are absent. It also covers when to use it vs. siblings, making it complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully describes `reference_id` (100% coverage) including that it is the user's reference ID and not Wayl's internal link `id`. The description adds little beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Fetch one payment link by your reference ID, including its current status,' which is a specific verb+resource. It clearly distinguishes the tool from siblings like check_order_paid, get_payment_links_batch, and list_payment_links by explaining what unique role this tool serves.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: 'Use this to inspect a single order...' and then directly states when to use alternatives: 'To answer "can I deliver yet?", call check_order_paid instead... For many orders use get_payment_links_batch; to browse without knowing IDs use list_payment_links.' This fully clarifies when to use this tool vs. alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_payment_links_batchARead-onlyIdempotent
Look up many payment links at once by your own reference IDs (1-100 per call).
Use this when reconciling a batch of orders — far cheaper than calling
`get_payment_link` in a loop. For a single order use `get_payment_link`, or
`check_order_paid` when the question is whether to deliver.
Reference IDs Wayl does not recognise are silently skipped rather than raising, so
`totalFound` below `totalRequested` is normal; the ones that came back missing are
listed under `missingReferenceIds`.
Returns Wayl's raw envelope — `data` alongside `totalRequested` and `totalFound` —
not the enriched record `get_payment_link` gives you. Rows carry no paid verdict:
only status Complete or Delivered counts as settled, and `total` is a string. This is
a POST that creates nothing, but it is not retried on a transient failure.
| Name | Required | Description | Default |
|---|---|---|---|
| reference_ids | Yes | Your own reference IDs — the ones you set when creating each link, not Wayl's internal `id`. Between 1 and 100 per call. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only and idempotent hints, but the description adds crucial behavior: unrecognized reference IDs are silently skipped, `totalFound` may be below `totalRequested` with missing IDs listed in `missingReferenceIds`, returns the raw envelope rather than enriched records, lacks a paid verdict, `total` is a string, and no retry on transient failures. These details far exceed 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Each paragraph covers a distinct aspect: purpose/usage, missing-ID behavior, response envelope, status interpretation, and HTTP/no-retry semantics. The description is front-loaded with the primary purpose and is efficient given the rich behavioral nuances that need disclosure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a batch lookup tool, the description covers batch limits, silent skip behavior, response shape (`data`, `totalRequested`, `totalFound`, `missingReferenceIds`), status settlement rules (Complete/Delivered), `total` as a string, and retry semantics. This is complete guidance for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully describes `reference_ids`, including its meaning (your own IDs, not Wayl's internal `id`) and constraints (1-100 per call). The description adds context about behavior with unrecognized IDs, but the parameter itself is fully covered by the schema, so the baseline for 100% coverage applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete action: 'Look up many payment links at once by your own reference IDs (1-100 per call).' It explicitly contrasts with `get_payment_link` for single orders and `check_order_paid` for delivery decisions, distinguishing this batch tool from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states 'Use this when reconciling a batch of orders — far cheaper than calling get_payment_link in a loop' and directs to `get_payment_link` or `check_order_paid` when appropriate. This explicit when-to-use guidance covers both recommended contexts and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_productARead-onlyIdempotent
Fetch one product's basic details by ID. Use it when you already have the ID from
list_products or a product URL — there is no lookup by name or slug.
Returns a reduced field set: id, name, price, status, url, image, tags and
description. Stock (`qt`, `unlimited`), variants (`inventories`), discounts and
downloadable files are NOT returned here — for those, page `list_products` and
filter by id.
`price` is a string of whole IQD; parse it before doing arithmetic. Read-only:
nothing in the catalogue changes and nobody is charged. A blank product_id is
rejected before any request is made. The catalogue is unrelated to payment links —
selling still means creating one with `sell_book` or `create_payment_link`.
| Name | Required | Description | Default |
|---|---|---|---|
| product_id | Yes | Wayl's own product ID, as returned in the `id` field by `list_products`. Not the product name, slug or public URL. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly and idempotent hints, but the description adds significant behavioral context: 'nothing in the catalogue changes and nobody is charged,' 'A blank product_id is rejected before any request is made,' and the format warning that '`price` is a string of whole IQD; parse it before doing arithmetic.' This goes well beyond the structured hints and helps the agent anticipate edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: it leads with the purpose, then usage, exclusions (what's NOT returned), a critical data-format caveat, read-only reassurance, and a cross-tool clarification. Every sentence carries distinct, useful information; there is no filler or repetition of schema/annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity is low (one parameter), the description is nevertheless thorough. It covers the full field set returned (and what is omitted), the alternative for richer data, the ID source, and a payment-link disambiguation. An output schema exists, so return format is already defined, but the description adds the 'NOT returned' list, which is very helpful. No meaningful context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the param description already explains the ID is Wayl's own ID, not name/slug/URL. The tool description adds value by tying the ID source to `list_products` or a product URL, and by confirming no lookup by name is possible. This reinforces and slightly extends the schema without redundancy, though the core meaning is already present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource: 'Fetch one product's basic details by ID.' It clearly distinguishes from sibling tools like `list_products` and `get_payment_link` by stating it's for a single product and only basic details. No ambiguity about the tool's core function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use it when you already have the ID from `list_products` or a product URL — there is no lookup by name or slug.' It also names an alternative for extended fields: 'for those, page `list_products` and filter by id.' Plus it clarifies the tool is unrelated to payment links, guiding against misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_refundARead-onlyIdempotent
Fetch one refund request by its Wayl refund ID: reason, linkId, referenceId, amount, initiatedBy and current status ('Requested', 'Refunded', 'Rejected' or 'Cancelled').
Use it to poll a refund you raised with `create_refund` — that call returns the `id` you
pass here. If all you have is the order's reference ID, use `list_refunds` with
`reference_id` instead; nothing on the payment link points back to its refunds.
Read-only: it never changes a refund. To withdraw one still in 'Requested', call
`cancel_refund`.
Wayl omits the refund's own ID from this response, so the server re-attaches it as
`refundId`. Amount is a number in whole IQD, unlike a link's `total`, which is a string.
| Name | Required | Description | Default |
|---|---|---|---|
| refund_id | Yes | The refund's Wayl ID, as returned in `id` by `create_refund` or `list_refunds`. Not your order reference ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description reinforces the read-only nature and adds non-obvious behavioral details: the server re-attaches the refund ID as `refundId` when omitted, and the amount is a number in whole IQD (unlike link's string `total`). No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but every sentence earns its place: purpose, return fields, usage guidance, alternative tools, and two subtle response quirks. It opens with a clear, specific summary and avoids fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only one required parameter and an output schema present, the description is more than sufficient. It covers the tool's role, its relationship to sibling tools, and key data type nuances, making the tool fully comprehensible in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents `refund_id` with 100% coverage, but the description enriches it by clarifying that this ID is what `create_refund` returns and is not the order reference ID. This helps prevent misuse without repeating schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it fetches one refund request by its Wayl refund ID and enumerates the returned fields (reason, linkId, referenceId, amount, initiatedBy, status). It distinguishes itself from siblings by explicitly contrasting with `list_refunds` and `cancel_refund`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use guidance: poll a refund you raised with `create_refund`, and if you have only the order's reference ID, use `list_refunds` instead. It also tells users to call `cancel_refund` to withdraw a pending refund, covering both when and when-not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invalidate_payment_linkADestructive
Cancel a payment link unconditionally so it can no longer be used.
Irreversible: the buyer will not be able to pay through that URL afterwards, and you
would have to issue a new link with a fresh reference ID — reference IDs are unique
across every link you have ever created and cannot be reused.
This does NOT check the link's status first, and Wayl documents no error for
invalidating a link that has already been paid — the outcome in that case is
undefined. Prefer `invalidate_payment_link_if_pending`, or confirm with
`check_order_paid` first.
It cancels the checkout, not the money: if the buyer already paid, use `create_refund`.
Returns Wayl's raw envelope, and the write is not retried on a transient failure.
| Name | Required | Description | Default |
|---|---|---|---|
| reference_id | Yes | Your reference ID for the link to cancel — the one you set at creation, not Wayl's internal `id`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the operation as destructive, but the description adds crucial context: irreversibility, reference ID uniqueness and non-reusability, lack of status checking, undefined outcome for paid links, non-retry on transient failures, and the raw envelope return. This far exceeds the annotation baseline and fully discloses behavioral nuances.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action, then delivers necessary warnings and alternatives without redundant language. Every sentence provides distinct value, and the structure (purpose, consequences, caveats, alternatives, return behavior) is logical and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, irreversible operation, the description covers all key aspects: irreversible consequences, unique ID constraints, undefined behavior on paid links, alternative tools, and retry behavior. The output schema exists, so return values need no explanation, and the description still manages to mention it returns the raw envelope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers the parameter with 100% description, and the tool description reinforces it by explaining that reference IDs are unique and cannot be reused, and that the parameter is the user-set reference ID, not Wayl's internal ID. This adds meaningful semantic context beyond the schema, though the schema already carries the primary definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Cancel a payment link unconditionally so it can no longer be used.' It clearly distinguishes from the sibling `invalidate_payment_link_if_pending` by emphasizing 'unconditionally' and from `create_refund` by noting it cancels the checkout, not the money.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided: 'Prefer `invalidate_payment_link_if_pending`, or confirm with `check_order_paid` first.' It also directs users to `create_refund` if the buyer already paid, and warns that invalidating a paid link yields undefined behavior. This is comprehensive when-to-use and when-not-to-use advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invalidate_payment_link_if_pendingADestructive
Cancel a payment link only if it is still pending; otherwise do nothing.
Use this to retire a checkout the buyer abandoned, or to withdraw a link you priced
wrong before anyone pays it. It is the safe version of `invalidate_payment_link`,
which cancels without checking status first.
A success response does NOT mean the link was cancelled — Wayl also answers with
success when the link was not pending and nothing happened. Do not report the order
as cancelled on the strength of this call alone; confirm with `get_payment_link`.
Cancellation is irreversible: nobody can pay through that URL afterwards and you
would have to issue a new link with a fresh reference ID. This never moves money —
to return money on an order that was already paid, use `create_refund`.
| Name | Required | Description | Default |
|---|---|---|---|
| reference_id | Yes | Reference ID of the link to cancel. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already flag this as destructive, the description adds crucial behavioral nuances: success does not imply cancellation (the tool no-ops on non-pending links), cancellation is irreversible, and it never moves money. It also advises confirming with `get_payment_link`, which is high-value 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat verbose (four paragraphs) but every sentence carries meaningful information: purpose, use cases, a critical caveat about success responses, and irreversible consequences. It is front-loaded with the main purpose and structured logically. Slightly dense but earns its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, conditional behavior, alternatives, side effects, and verification steps. With an output schema present, it doesn't need to detail return values. This is a complete and self-contained guide for a destructive, conditional operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage for the single parameter `reference_id` with a clear description. The tool description doesn't add much parameter-specific detail beyond what the schema already says, but it does reference 'fresh reference ID' when mentioning issuing new links, which is indirect. Baseline 3 is appropriate given full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise, conditional statement: 'Cancel a payment link only if it is still pending; otherwise do nothing.' This clearly identifies the verb (cancel/invalidate), resource (payment link), and the unique condition (pending). It also distinguishes itself from the sibling tool `invalidate_payment_link` by calling itself the 'safe version' that checks status first.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit use cases: retiring abandoned checkouts or withdrawing incorrectly priced links. It also contrasts with `invalidate_payment_link` (the non-conditional version) and directs users to `create_refund` for returning money, making when-to-use and alternatives very clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_payment_linksARead-onlyIdempotent
List your payment links, newest first, optionally filtered by status.
Use statuses=['Complete', 'Delivered'] to review paid orders, or statuses=['Pending']
to find checkouts a buyer started but never finished; omit `statuses` for every state.
When you already know the reference IDs, use `get_payment_link` or
`get_payment_links_batch` instead of paging through this.
Wayl returns no total count, so do not treat the number of rows as the number of
orders. Keep paging with `nextSkip` while `hasMore` is true — it is a heuristic, true
whenever a full page came back.
Rows are raw Wayl records: `total` is a string, and only status Complete or Delivered
means paid. Nothing here reports which environment a link belongs to, so test and live
orders look identical — confirm with `check_order_paid` before delivering anything.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | How many to skip before this page starts. Pass the `nextSkip` returned by the previous call. | |
| take | No | How many links to return. | |
| statuses | No | Filter by payment status. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, and idempotent, but the description adds substantial behavioral context beyond that: no total count returned, `hasMore` is a heuristic, `total` is a string, only status Complete/Delivered means paid, and the environment is not reported. The warning to confirm with `check_order_paid` before delivery is extra value not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries unique operational guidance, and the description is front-loaded with the core purpose. While it is longer than minimal, there is no filler or repetition; it earns its length with dense, useful detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers all critical operational aspects: pagination behavior, status semantics, raw record format, environment ambiguity, and cross-tool confirmation via `check_order_paid`. The output schema exists, so no need to describe return values, making this complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover all three parameters, so the baseline is 3. However, the description adds meaningful usage semantics for `statuses` (recommended combinations and omission for all states) and explains the `skip`/`nextSkip` pagination pattern, going beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List your payment links, newest first, optionally filtered by status.' It clearly states the sort order and filtering capability. It also distinguishes itself from siblings by explicitly naming `get_payment_link` and `get_payment_links_batch` as alternatives when you already know reference IDs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides direct when-to-use guidance: `statuses=['Complete', 'Delivered']` for paid orders, `statuses=['Pending']` for abandoned checkouts, and omit `statuses` for all states. It also explicitly names alternatives (`get_payment_link`, `get_payment_links_batch`) and warns against treating row count as order count, making the usage context unmistakable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_productsARead-onlyIdempotent
List the products in your Wayl catalogue, newest first.
Covers Digital, Physical and Service products; Subscription products are not
returned by this endpoint. Digital products are the relevant kind for selling
ebooks, since they carry downloadable files.
This returns richer records than `get_product` does — stock (`qt`, `unlimited`),
variants (`inventories`), discounts and the downloadable file URL appear only here.
To inspect one product's stock, page this endpoint and filter by `id`.
Wayl returns no total count, so do not treat the number of rows as the size of the
catalogue: keep paging with `nextSkip` while `hasMore` is true. `price` comes back
as a string of whole IQD. Listing changes nothing and charges nobody — selling still
means creating a link with `sell_book` or `create_payment_link`.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | How many to skip, for paging. | |
| take | No | How many products to return. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already declare readOnlyHint, openWorldHint, and idempotentHint, the description adds critical context: listing changes nothing and charges nobody, returns no total count, requires paging via nextSkip/hasMore, returns price as a string, and provides richer records than get_product. This goes far beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, front-loaded with the core purpose, and every sentence provides useful information—no fluff. It covers scope, exclusions, returned record details, paging, price format, side effects, and alternatives without being redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and comprehensive annotations, the description fills remaining gaps: it explains the richer record content, paging limitations, price representation, and product type filters. This is complete for a list tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both skip and take, each with clear descriptions. The description does not elaborate on parameter usage beyond what schema provides, though it does mention paging behavior (nextSkip/hasMore) that relates to skip. Baseline 3 is appropriate given high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear specific action: 'List the products in your Wayl catalogue, newest first.' It identifies the resource (products) and the ordering, and later distinguishes from siblings like get_product and sell_book by clarifying what this endpoint does and does not return.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states scope (Digital, Physical, Service) and exclusions (Subscription products are not returned), when to use it for stock inspection ('To inspect one product's stock, page this endpoint'), and names alternatives for selling (sell_book or create_payment_link). It also warns about paging semantics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_refundsARead-onlyIdempotent
List refund requests, newest first, optionally filtered by order reference or status.
Use this to recover a refund's Wayl `id`: `create_refund` returns it once, and it is the
only handle `get_refund` and `cancel_refund` accept. Pass `reference_id` to see every
refund raised against one order. When you already hold the refund ID, call `get_refund`
instead of paging this.
Refund statuses are 'Requested' (awaiting Wayl's decision, still cancellable),
'Refunded', 'Rejected' and 'Cancelled'. Amounts come back as numbers in whole IQD,
unlike a link's `total`, which is a string.
Wayl returns no total count, so do not read the row count as the number of refunds.
Keep paging with `nextSkip` while `hasMore` is true.
| Name | Required | Description | Default |
|---|---|---|---|
| skip | No | How many to skip, for paging. | |
| take | No | How many refunds to return. | |
| statuses | No | Filter by refund status. | |
| reference_id | No | Your order reference ID — the one passed to `create_payment_link`. Shows every refund raised against that one order; omit to list refunds across all orders. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations by explaining status meanings ('Requested' is cancellable), amount format (whole IQD numbers vs. string), and paging semantics (no total count, use nextSkip/hasMore). No contradiction with readOnlyHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose. Each paragraph covers a distinct aspect (usage, statuses, paging) with no redundant or filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description doesn't need return details. It covers purpose, alternatives, filtering, statuses, amount types, and paging instructions, making it comprehensive for this list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already covers all parameters, but description adds valuable semantics for statuses and reference_id. The paging reference to 'nextSkip' is slightly ambiguous against the 'skip' parameter, but overall it enriches parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists refund requests with ordering and optional filters. It explicitly distinguishes from get_refund by emphasizing when to use this list vs. fetching a single refund by ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use cases: recovering a refund ID when only order reference is known, and instructing to use get_refund instead when the ID is already held. Also clarifies the reference_id filter behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parse_webhookARead-onlyIdempotent
Verify a Wayl webhook and summarise what it says about the order.
Use this for any incoming delivery: it authenticates the signature, parses the
payload and reports whether the order is paid, all locally with no network call.
Use `verify_webhook` when a bare valid/invalid boolean is enough, and
`check_order_paid` when polling by reference ID rather than handling a push.
The webhook's `paymentStatus` is a different vocabulary from the REST API's link
`status` — it reports "Paid", which is not one of the eight link statuses. This
tool reads the right field so you do not have to.
Never act on a payload where `verified` is false; that result carries no order
details. `paid` and `safeToFulfil` are deliberately different: while this server is
in test mode a settled payment is simulated, so `safeToFulfil` stays false even when
`paid` is true. Branch on `safeToFulfil`.
Deduplicate on `eventId` before delivering — Wayl retries, and the signature has no
timestamp, so a replayed request stays valid forever. A verified body that is not a
JSON object raises an error rather than returning a false verdict.
| Name | Required | Description | Default |
|---|---|---|---|
| secret | No | The webhookSecret used when this link was created. Wayl scopes secrets per link, so pass the one matching this order. | |
| headers | No | The webhook's headers; the signature header is found automatically. | |
| raw_body | Yes | The webhook request body exactly as received, byte for byte. Wayl sends it with Content-Type: text/plain, so read the raw body rather than relying on a JSON body parser. | |
| signature | No | Value of the x-wayl-signature-256 header. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations by revealing critical behaviors: it operates 'all locally with no network call,' handles the different paymentStatus vocabulary, simulates payment in test mode via safeToFulfil, and warns about replay attacks due to missing timestamps. This is valuable context not present in readOnlyHint or idempotentHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although long, every sentence earns its place for a security-sensitive webhook tool. It opens with the core purpose, moves to usage alternatives, then covers essential caveats. The structure is logical, front-loaded, and densely informative without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the full operational context: authentication, payload parsing, safety fields, idempotency, replay risks, and error behavior. Given the tool's complexity and the presence of an output schema for return values, this is comprehensive and leaves no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter meaning is already documented. The description adds extra semantic guidance, such as reading raw_body byte-for-byte because Wayl sends text/plain, and that headers/signature are found automatically. This supplements the schema with practical context, though it does not systematically walk through each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence immediately states the specific verb and resource: 'Verify a Wayl webhook and summarise what it says about the order.' It distinguishes itself from siblings by explicitly naming the alternatives and their different use cases, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance on when to use this tool: 'Use this for any incoming delivery.' It also explicitly contrasts with alternatives: 'Use verify_webhook when a bare valid/invalid boolean is enough, and check_order_paid when polling by reference ID.' It adds operational warnings like deduplicating on eventId and never acting on unverified payloads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sell_bookA
Create a checkout link for a book order, with the price breakdown filled in.
Builds the line items (copies, discount, delivery), computes the total as
price * quantity + delivery_fee - discount, generates a unique reference ID from
the title, and creates the payment link. Returns the checkout `url` to send the
buyer. The total must reach Wayl's 1000 IQD minimum or the call is rejected.
The buyer sees an itemised breakdown rather than a bare number, which is what you
want for anything beyond a single flat-priced copy.
Creating the link charges nobody — it only produces a checkout page, and a link
created with env='test' never moves real money at all. Do NOT deliver the book
(send a download link, ship a copy) until `check_order_paid` or `parse_webhook` returns
`safeToFulfil: true`. That is a different field from `paid`: a sandbox payment
settles and is still not something to ship against.
Use `create_payment_link` instead when you need a webhook, redirect or custom
line items for one order: here those URLs come from the server's
WAYL_WEBHOOK_URL, WAYL_WEBHOOK_SECRET and WAYL_REDIRECT_URL settings and cannot
be set per call. Persist the returned `code` — no other endpoint returns it.
| Name | Required | Description | Default |
|---|---|---|---|
| env | No | 'live' takes real money, 'test' is a sandbox that charges nobody. Defaults to 'test'. | |
| price | Yes | Price of one copy in whole IQD — no decimal subunits. The order total after delivery and discount must still reach 1000 IQD. | |
| title | Yes | Book title, used as the checkout line-item label. Long titles are truncated to Wayl's 255-character label limit; very short ones are padded to its 3-character minimum. | |
| discount | No | Discount to subtract from the whole order, in whole IQD — not per copy. | |
| quantity | No | How many copies. | |
| delivery_fee | No | Delivery or handling charge in IQD. Use 0 for ebooks. | |
| reference_id | No | Your order ID, unique across all your links. Generated from the title if omitted. | |
| customer_note | No | Free-form note stored on the order as `customParameter` and echoed back on reads, for your own tracking. May be visible at checkout, so keep secrets out of it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses side effects: creating the link 'charges nobody', env='test' 'never moves real money at all', and it stresses the safeToFulfil requirement. This goes well beyond the annotations (readOnlyHint=false, destructiveHint=false) by explaining the real-world impact and the distinction between paid and safeToFulfil.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but tightly packed: every sentence adds a distinct piece of information (purpose, calculation, minimum, env behavior, fulfillment warning, alternative tool, persistence hint). It's structured with clear paragraphs and no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema already present, the description still covers the key returned fields (`url`, `code`), the rejection condition (total below 1000 IQD), and the critical fulfillment check (`safeToFulfil`). Together with the rich annotations and schema, an agent has everything it needs to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all 8 parameters at 100%, but the description adds the exact formula (`price * quantity + delivery_fee - discount`), the 1000 IQD minimum, and title truncation/padding details. It also clarifies that discount applies to the whole order, not per copy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names the exact action and output: 'Create a checkout link for a book order, with the price breakdown filled in.' It goes on to specify the mechanics (line items, total computation, reference ID) and explicitly contrasts with create_payment_link, so the purpose is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It tells the agent exactly when to prefer this tool: 'Use `create_payment_link` instead when you need a webhook, redirect or custom line items for one order.' It also gives the negative condition ('for anything beyond a single flat-priced copy') and warns about fulfillment timing, which is crucial usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_auth_keyARead-onlyIdempotent
Check that the configured Wayl API key is accepted by the API.
Call this first when payment tools start failing — it distinguishes a bad or missing
key from a problem with the request itself. Returns the key's validity alongside the
base URL and default environment this server is using.
Makes one network call. To inspect configuration without touching the network —
whether a key is set at all, which env new links default to — use `wayl_status`.
Wayl authenticates before routing, so an unknown path answers 401 rather than 404: a
failure here means the key was rejected *or* WAYL_BASE_URL is wrong, and the status
code cannot tell the two apart. Success says nothing about test versus live — Wayl
uses one key for both, and the environment is chosen per link with `env`.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds significant behavioral context beyond the annotations: makes one network call, explains the 401-vs-404 routing behavior, and clarifies that success does not indicate test vs. live because Wayl uses a single key for both. This is genuinely useful nuance not derivable from readOnlyHint/openWorldHint/idempotentHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but each sentence earns its place: purpose, usage context, alternative, and caveats are all covered in a compact format. Front-loaded with the core purpose, then expands with relevant details without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter diagnostic tool with a rich output schema, the description covers all necessary context: when to use, what it returns, key behavioral caveats, and the alternative. Nothing important seems missing, and the output schema handles return-form specifics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema confirms this with 100% coverage. The description adds value by explaining what the return communicates (key validity, base URL, default environment), which is more than expected for a no-parameter tool. Baseline 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: verifying that the configured Wayl API key is accepted. It uses a specific verb ('check') and resource ('API key'), and distinguishes itself from siblings by positioning it as the first diagnostic step when payment tools fail, in contrast to wayl_status for configuration inspection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: call this first when payment tools start failing to distinguish bad key from request issues. It also names the alternative wayl_status for offline configuration inspection, giving a clear when-to-use vs. when-not-to-use distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_webhookARead-onlyIdempotent
Check a webhook's HMAC-SHA256 signature and return only a valid/invalid answer.
Prefer `parse_webhook` for an incoming delivery — it verifies the signature *and*
extracts the payment status, event ID and a paid/not-paid verdict in one call.
Reach for this tool only when the boolean alone is what you need.
Runs locally; makes no network call. Treat a `valid: false` result as an attack
or a misconfiguration and ignore the payload — an unverified "payment complete"
event is exactly how someone gets a book without paying.
Pass the body exactly as received; the digest covers the raw request bytes, so
re-serialising the JSON breaks it. Secrets are per link, not per account. This
errors instead of answering when no signature or secret is available, or when the
secret falls outside Wayl's 10-255 characters — one that short cannot have signed
a real delivery.
`valid: true` does not mean the event is new. There is no timestamp or nonce, so a
captured delivery verifies forever. Deduplicate on the payload's `id`.
| Name | Required | Description | Default |
|---|---|---|---|
| secret | No | The webhookSecret for this link. Defaults to WAYL_WEBHOOK_SECRET. | |
| headers | No | The webhook's request headers. The signature header is found automatically, so you can pass the whole map instead of extracting it. | |
| raw_body | Yes | The webhook request body exactly as received, byte for byte. Do not reformat or re-serialise it — that changes the signature. | |
| signature | No | Signature from the webhook's signature header. Omit if you pass `headers` instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent hints, the description discloses key behaviors: errors on missing signature/secret or out-of-range secret, no timestamp/nonce (so valid:true does not imply freshness), and instructs to treat invalid as an attack. It adds security-critical context without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized into tight paragraphs, front-loading the core purpose and then layering context. Every sentence adds value, covering usage, failure modes, and security caveats without redundant fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is security-sensitive and the description covers all essential context: what it verifies, when to use it, what invalid means, how to pass the body, error conditions, and idempotency/deduplication guidance. The output schema exists, so return values need no extra explanation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and parameter descriptions already explain each field. The tool description complements by reinforcing raw_body must be byte-for-byte, headers can be passed whole because signature is auto-found, and secrets are per link. This adds practical nuance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Check a webhook's HMAC-SHA256 signature and return only a valid/invalid answer', using a specific verb and resource, and explicitly names the sibling 'parse_webhook' as an alternative that does more. This fully distinguishes the tool from its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: 'Prefer parse_webhook for an incoming delivery' and 'Reach for this tool only when the boolean alone is what you need.' It also notes the tool runs locally with no network call, providing clear contextual usage direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wayl_statusARead-onlyIdempotent
Report how this server is configured, without calling the Wayl API.
Call this first when something looks misconfigured: it returns the base URL, whether
an API key is present, which environment new links default to (`defaultEnv` and
`liveMode`), which optional defaults are set, the reference prefix, and the fixed IQD
currency with its 1000 IQD minimum charge.
It reports presence, not validity — `apiKeyConfigured: true` only means a key was
found in the environment. Use `verify_auth_key` to confirm the key actually works.
Secret values are never returned, only booleans saying whether they are set.
Config is read once at start-up, so editing environment variables changes nothing
until the server is restarted. Makes no network call and changes no state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description enriches them with important behavioral details: it 'Makes no network call and changes no state,' never returns secrets (only booleans), and notes that config is read once at startup so env changes require restart. It also clarifies that `apiKeyConfigured` reports presence, not validity. These go beyond annotation-provided safety hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: main purpose, when to call, return fields (condensed), presence-vs-validity caveat, secret handling, startup read behavior, and side-effect note. The structure is logical and front-loaded with the most important information. Despite length, it is compact for the amount of nuanced content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and a likely simple output schema, the description still covers edge cases (misconfiguration detection, key validity, env var changes, secret masking) and explicitly states side effects. It gives the agent everything needed to decide and invoke correctly, and it complements annotations and output schema without redundancy.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4. There are no parameter semantics to explain, and the description correctly avoids inventing any. The schema coverage is 100% (empty), so no compensation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Report how this server is configured, without calling the Wayl API.' This clearly distinguishes it from sibling tools, which focus on links, products, refunds, webhooks, etc. The scope (configuration/status) is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is given: 'Call this first when something looks misconfigured.' It also provides a direct alternative for a related need: 'Use `verify_auth_key` to confirm the key actually works.' This tells the agent exactly when to choose this tool versus a sibling.
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. Dates show when Glama detected each change.
18 tool updates
v0.1.0- First observed
cancel_refund - First observed
check_order_paid - First observed
create_payment_link - First observed
create_refund - First observed
get_payment_link - First observed
get_payment_links_batch - First observed
get_product - First observed
get_refund - First observed
invalidate_payment_link - First observed
invalidate_payment_link_if_pending - First observed
list_payment_links - First observed
list_products - First observed
list_refunds - First observed
parse_webhook - First observed
sell_book - First observed
verify_auth_key - First observed
verify_webhook - First observed
wayl_status
TDQS
Every tool has a distinctly defined purpose, and the descriptions carefully cross-reference related tools (e.g., get_payment_link vs get_payment_links_batch vs check_order_paid, invalidate_payment_link vs invalidate_payment_link_if_pending). This makes selection unambiguous for an agent.
Most tools follow a clear verb_noun pattern (create_, get_, list_, invalidate_, cancel_, verify_, parse_). The only outlier is wayl_status, which could have been get_status, but it remains understandable.
18 tools is on the heavier side, but the server covers payment links, products, refunds, webhooks, and configuration—each area justifies several tools. The count feels appropriate for the scope, though some consolidation might be possible.
The core workflow (create payment link, monitor payment, verify webhook, refund) is fully covered. Minor gaps: product tools are read-only only, and there is no update operation for payment links, but these are not essential for the server's stated purpose of selling books.
Maintenance
Related MCP Connectors
MCP Server for agents to onboard, pay, and provision services autonomously with InFlow
Paid remote MCP for server-card validation, auth checks, trust packets, and readiness.
Related MCP Servers
- AlicenseCqualityNot gradedmaintenanceThis is an MCP server to manage PayPal12-
- AlicenseNot gradedqualityCmaintenanceThe PayPal Model Context Protocol server allows you to integrate with PayPal APIs through function calling. This protocol supports various tools to interact with different PayPal services.603190-
- AlicenseAqualityCmaintenanceA Model Context Protocol (MCP) server for integrating with the SATIM payment gateway system in Algeria, enabling AI assistants to process CIB/Edhahabia card payments through the SATIM-ePAY platform.51815GPL 3.0
- AlicenseAqualityBmaintenanceMCP server for JazzCash mobile wallet and payments (Pakistan). Supports wallet payments, mobile account payments, vouchers, refunds, and balance inquiries.5201MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/muthanii/waylMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server