MCP HeartbeatTHE MCP OBSERVATORY
Public workspace

Explore

Evidence for your next connection.

Independent measurements of remote MCP servers. Every observation has a timestamp.

Read-only probes

MCP server · Payments & trading

afro.tools

Open-source API specs for African providers (payments, SMS, KYC, delivery) for AI agents.

Checks passed
15 / 22

0 failed · 7 not measured

Median response
159 ms

Median of successful probes over 7 days

30-day uptime
Not measured

Share of countable probes over 30 days, including daily rollups. Auth challenges are excluded.

Discovered tools
5

Tool definitions returned by this server

Independent monitoring

Health & checks

Status history

Responded

The server completed its last measured handshake. This is an observation, not a guarantee.

Last checked
Check summary by test group
Test areaPassedFailedUnmeasured
ConnectionCan a client connect and discover tools?
500
Reliability & speedDoes it respond consistently and quickly?
103
Access & authenticationWhat is required to use this server?
102
Tool qualityAre the tool definitions usable by an agent?
400
Publisher identityCan the publisher be traced to its source?
402

Unmeasured means there is not enough evidence to decide. How these checks work

Inspect individual checks 22 recorded

Core

  • Pass
    Reachable

    Latest probe returned HTTP 200 in 156 ms.

  • Pass
    Valid handshake

    protocolVersion 2025-11-25, serverInfo.name afrotools.

  • Pass
    Lists tools

    tools/list returned 5 tools.

  • Pass
    Current protocol

    Negotiated 2025-11-25. The bar is 2025-06-18 or newer.

  • Pass
    HTTPS

    The endpoint URL is https.

Performance

  • Not measured
    Fast (p50)

    Median latency 159 ms over 2 samples in 7 days. The bar is 1000 ms. Need at least 5 samples.

  • Not measured
    Consistent (p95)

    95th percentile 161 ms over 2 samples in 7 days. The bar is 3000 ms. Need at least 20 samples.

  • Not measured
    Reliable (uptime)

    2 of 2 attempts returned a tool list in 30 days (100%). The bar is 99%. Need at least 30 samples.

  • Pass
    Stable tool list

    No tool was removed and no required parameter was added in the last 30 days.

Access

  • Pass
    Open access

    tools/list succeeded with no credential, and the record declares none.

  • Not measured
    Standard auth

    Auth is not required, so the OAuth metadata check does not apply.

  • Not measured
    Free tier cited

    No publisher quote has been checked.

Tools

  • Pass
    Tools described

    Every tool description is at least 20 characters.

  • Pass
    Valid input schemas

    Every inputSchema is a JSON Schema object.

  • Pass
    Parameters documented

    16 of 20 parameters have a description (80%). The bar is 80%.

  • Pass
    Safety hints

    Every tool sets readOnlyHint or destructiveHint.

Publisher

  • Pass
    Verified namespace

    Listed in the Official MCP Registry.

  • Not measured
    Website matches publisher

    This namespace is not a reverse domain, so the website comparison does not apply.

  • Pass
    Source repo linked

    A repository URL is on file.

  • Pass
    Repo owner matches

    The GitHub repository owner matches the namespace login.

  • Pass
    Recently updated

    Updated 2026-10-31T20:27:16.005858Z, within 180 days.

  • Not measured
    Open-source licence

    The GitHub licence lookup has not returned an OSI result yet.

Start using afro.tools

Connect to this server

Choose your client, copy the configuration, then enable the server in your client’s MCP settings.

Run this command in your terminal, then restart Claude Code.

Claude Code

claude mcp add --transport http afro-tools https://mcp.afro.tools/mcp

Capabilities

Tools 5

get_spec

Returns the full spec payload for a provider + capability, including canonical_example.ts source code. Use this to get the complete integration guide — auth pattern, endpoint, schemas, gotchas, and a TypeScript example — before writing API calls. The response includes a "status" field: - "verified": tested against the provider's API, in "sandbox" or "production" (verified_in / verification.environment) - "deprecated": the provider is retiring it — "deprecation" gives the reason, replaced_by (the capability to use instead) and removed_after - anything else (e.g. "ready", "unverified"): written from the provider's documentation, NOT tested against the live API "verification" says how and when it was tested; sandbox proves the request and response shapes, not production behaviour. "open_questions", when present, lists what the provider's docs do not answer: tell the user before relying on the spec. "account", when present, says who can open the provider's account; list_providers and search_specs add its open questions (caps, conditions) and sources. "environments", when present, gives each documented environment's base URL; a missing one is undocumented — ask the user, never guess. "auth.credentials" / "signing" / "token_exchange" / "apply" and "webhook.signature", when present, describe the auth and webhook signature steps exactly: follow them. "parameters", when present, lists the path, query and header parameters; "input_schema" is the request body only. A path parameter fills the {name} placeholder of endpoint.url. "success_condition", when present, names the response field (dotted path) that says the call succeeded: a 2xx response with another value is a failure. If status is not "verified", always warn the user before generating integration code: "This spec has not been tested against the live API yet and may contain errors." Args: - provider (string): Provider slug e.g. "paycard" - capability (string): Capability name e.g. "create_payment" - variant (string[]?): Discriminator values to keep, e.g. ["mobile_money_ghs"] or ["bank", "NGN"]. In every union (oneOf) of input_schema and response_schema, only the branches pinned to one of these values are kept; a union none of them matches is left whole. Without it, all branches are returned. The response lists every value under "variants" (discriminator property → values). A large spec also carries "_mcp_size_note": if your client cut the result, call again with the variant you need. Returns: Full Spec object with canonical_example string (plus _mcp_warning when status is not "verified"). If not found: isError, with { error, available_capabilities } when the provider exists — capability names are each provider's own, pick one from that list — and did_you_mean (closest provider slugs or capability names) when one is close. A capability removed from the registry after a provider deprecation answers isError with removed_in, reason and alternatives. Use search_specs or list_providers first to discover available providers and capabilities.

Discovered
list_providers

Lists every provider in the registry with what it offers. Every listed provider is AI Ready: its specs give you a structured description to integrate it from (endpoints, fields, errors, gotchas taken from the provider's docs). verified_count says how many of its capabilities were also tested against the provider's API; all_verified is true when all of them were. When you show this list, present what each provider offers and give the tested capabilities per provider (e.g. "3/4 tested"), not a headline such as "only one provider is fully verified": a capability not tested yet is still documented and usable, it may contain errors. Before integrating one, check its "status" with get_spec and tell the user if it was not tested. "account", when present, says who can open the account the API needs, from the provider's own pages: holder is "business_only" (a registered business) or "business_or_individual", for all its countries except those in country_exceptions; documents lists what the pages ask for; open_questions gives caps, conditions and what the pages leave unsaid — tell the user, they can change the answer; sources link to those pages (with checked_at, the reading date). A country with no answer (no holder, not in country_exceptions), or no "account" at all, is not documented: tell the user to check with the provider before signing up, never guess. note is present when the list was trimmed to stay readable: description first, then the accounts' sources and checked_at (each provider's page on afro.tools shows the description, links the sources and gives the date) — never an account's answers or open questions. It says which. Returns: { note?, providers: Array<{ slug, name, category, channels?, all_verified, verified_count, capabilities, country_code, docs_public, docs_url, description?, account? }> }

Discovered
report_integration

Builds a pre-filled GitHub link to report how an integration went against a spec — it worked, or the spec is wrong. Call it when the user confirms an integration works against the real API (sandbox or production), or when you find the spec does not match the API. Reports are how specs get verified and fixed. Nothing is posted: the user reviews the text and submits it on GitHub. One report per provider, covering every capability of the flow (e.g. payment init, status, webhook): each one is verified on its own. Args: - provider (string): Provider slug e.g. "paycard" - capabilities (array): Every capability the integration used, each with its own result e.g. [{ "capability": "create_payment", "result": "worked" }, { "capability": "webhook", "result": "wrong: status is SUCCESSFUL, spec says succeeded" }] - summary (string): One line about the flow, e.g. "checkout flow works in sandbox" - details (string): What was called, what came back, what differed from the spec. NEVER include API keys, tokens, phone numbers or personal data. - tested_on (string?): Date of the test, YYYY-MM-DD Returns: { url, next_step } — give the url to the user and follow next_step. If a spec does not exist: isError, with { error, available_capabilities } when the provider exists.

Discovered
request_spec

Logs a request for a spec that doesn't exist yet and notifies maintainers. Call this when a user asks for a provider or capability that has no spec in the registry (check list_providers first), or needs a capability in a country where no listed provider offers it (search_specs with country first). This helps maintainers prioritize which specs and providers to add next. Args: - capability (string): Capability name e.g. "create_payment", or what is needed e.g. "ussd" - provider (string?): Provider slug e.g. "wave" — omit when no provider is named - country_code (string?): ISO 3166-1 alpha-2 code e.g. "SN" — required when provider is omitted - follow_up ("none" | "github_issue", default "none"): "none" records the request only; "github_issue" also returns issue_url, a pre-filled GitHub issue the user can review and submit Returns: { logged: true, count, issue_url? } if the request was recorded — count is the all-time number of times this provider + capability (or, without a provider, capability + country) was requested, including this one (a repeated request counts again). count is absent if it could not be determined: do not guess a number. issue_url only with follow_up "github_issue": give it to the user, who submits it. { logged: false, reason: "spec already exists" }: the spec is in the registry — use the existing spec (get_spec) instead. isError if the request could not be stored: tell the user it was NOT recorded.

Discovered
search_specs

Searches specs by words and filters by category, channel, provider, country, currency, status or capability type. Returns the matching providers, each with its countries, currencies, sandbox flag, docs URL and the matching capabilities (name, type, status, example_prompt) — no endpoints, schemas, gotchas or canonical_example source. Use get_spec with the exact capability name to retrieve the full payload. A capability with "variants" has several request/response shapes (e.g. one per payment method or corridor): pass the ones you need to get_spec "variant" to receive only those. Each result includes a "status" field: - "verified": tested against the provider's API, in "sandbox" or "production" (verified_in / verification.environment) - "deprecated": the provider is retiring it — get_spec says what replaces it - anything else (e.g. "ready", "unverified"): written from the provider's documentation, NOT tested against the live API — may contain errors Always check the status field. If status is not "verified", inform the user that the spec is experimental and may contain errors. Args: - query (string?): Words, e.g. "wave", "mobile money senegal", "send sms", "kyc", "XOF". Every word must match somewhere: provider name or slug, capability, description, example_prompt, countries (code or English/French name), currencies, channels (a few synonyms: momo, otp, kyc, payout…). Providers the query names come first. - category (string?): Filter by category, e.g. "payment", "communications" (SMS, WhatsApp, USSD, voice and email providers — "sms" is accepted as a legacy alias), "identity" (KYC, document verification, AML), "logistics" (delivery and courier providers). The registry adds categories over time: list_providers shows every category that exists - channel ("sms"|"whatsapp"|"ussd"|"voice"|"email"?): Only providers that offer this channel - provider (string?): Provider slug e.g. "paycard" - country_code (string?): ISO 3166-1 alpha-2 e.g. "GN" - currency (string?): ISO 4217 e.g. "XOF" - status ("verified"|"ready"|"unverified"?): e.g. "verified" for specs tested against the provider's API - capability_type ("synchronous"|"asynchronous"|"webhook"|"sdk"?): Filter by capability type Returns: { providers: ProviderMatch[], note?: string, hint?: string, unverified_count: number, warning?: string } Each provider may carry "account": who can open its account, with its open questions (see list_providers, which also has the sources). note is present when a wide result was trimmed to stay readable: example_prompt first, then variants, then the whole account (never an account's answers without its open questions) — it says which; call list_providers for the accounts, get_spec for the variants. hint is present when nothing matched: widen the search before telling the user a provider is unavailable. unverified_count counts matching capabilities whose status is not "verified"; warning is present only when it is > 0.

Discovered

Recent measurements

Probe history

View status
Latest stored probes. Raw probe rows are kept for 14 days.
CheckedResultResponseTools
Connected156 ms5
Connected161 ms5