MCP technical details

For developers and app reviewers: server URL, OAuth, scopes, confirmations, limits and errors.

For developers building or reviewing an MCP client. To connect Claude or ChatGPT, see Use Wafeq with Claude or ChatGPT.

SettingValue
Server URLhttps://mcp.wafeq.com/mcp
TransportStreamable HTTP, stateless, JSON responses
AuthenticationOAuth 2.1 (API keys don't work here)
Scopesmcp.read (always granted), mcp.write
ToolsSee the tool reference

Authentication

Wafeq follows the MCP authorization spec.

WhatURL
Protected resource metadatahttps://mcp.wafeq.com/.well-known/oauth-protected-resource/mcp
Authorization server metadatahttps://app.wafeq.com/.well-known/oauth-authorization-server/oauth2/mcp
Issuerhttps://app.wafeq.com/oauth2/mcp

Take the authorize, token, registration and revocation endpoints from the authorization server metadata, with their trailing slashes.

  • Register with a Client ID Metadata Document (an HTTPS URL as client_id) or dynamic client registration (RFC 7591).
  • Authenticate with token_endpoint_auth_method none (the default) or private_key_jwt, signed with ES256 or RS256 keys from jwks_uri or jwks. Wafeq issues no client secrets.
  • PKCE S256 is required.
  • resource=https://mcp.wafeq.com/mcp is required on the authorization request and code exchange. On a refresh it's optional, but must match.
  • iss comes back on the redirect (RFC 9207).
  • Redirect URIs match exactly. Loopback http URIs may differ only in port.
  • Scopes: no scope requested means both. Without mcp.write, write tools are hidden, and calling one returns HTTP 403 with WWW-Authenticate: Bearer error="insufficient_scope". Authorize again with mcp.write to get write access.
TokenLifetime
Authorization code10 minutes
Access token1 hour
Refresh tokenRotates on every use. A replaced token is refused, and reusing it after 60 seconds ends the connection.
Connection90 days from approval, then the user connects again

A connection stops working while the user is deactivated or in none of the shared organizations, and ends when they change their password. Members with the Integrations permission can see each connection on the Integrations page in Wafeq and disconnect it there.

Permissions and confirmations

  • Tools follow the user's role and the organization's plan. Call get_capabilities first for the shared organizations, then with an organization_id to see which tools work there. Pass organization_id on every other call.
  • No tool moves money. create_payment only records a payment.
  • Thirteen tools can ask before acting, including send_invoice, report_invoice, void_invoice, merge_contacts and delete_branch. They return a summary, warnings and a confirmation_token. Show these to the user, and if they agree, repeat the same call with confirmation_token added. The token lasts 10 minutes.
  • Those thirteen and every delete_* tool can't be undone. report_* and void_invoice report to ZATCA or the FTA when the organization is connected; only a credit note reverses that.
  • Pass a new UUID as idempotency_key wherever a tool accepts it, and reuse it when retrying.

Limits and errors

Each Wafeq user gets 120 read and 30 write calls per minute, shared across all their connected apps. Lists return up to 100 rows per page.

A failed call returns isError: true with a text block of JSON: {"code", "retryable", "message"}. Retry only when retryable is true.

CodeRetry?
invalid_arguments, invalid_request, not_foundYes, with fixed arguments
rate_limitedYes, after the wait in the message
permission_denied, plan_upgrade_required, record_locked, not_possibleNo
internal_errorNo. After a write, read the record: it may have been saved.

Requests with an Origin header other than https://app.wafeq.com get 403 Forbidden Origin, so browser-based clients can't connect.

Support

Help center · help@wafeq.com · Status · Privacy policy