Skip to main content
Glama
GravityFinance

@gravv/mcp

Official

@gravv-infra/mcp

MCP server for the Gravv payments API. Connects an AI assistant to Gravv so it can onboard customers, run KYC, open accounts, add recipients, move money, issue cards, and exchange currency — using your own API key.

Works with Claude, Cursor, VS Code, and any MCP-compatible client.


Quick start

Requires Node.js 20 or later. Check with node --version.

GRAVV_API_KEY=grvSec_sandbox_... npx @gravv-infra/mcp

Get an API key from your Gravv dashboard. Start with a sandbox key — the key itself decides which environment you reach.

To confirm it's wired up, ask your assistant:

What Gravv accounts do I have?

It should call listAccounts and come back with real data. If you have no accounts yet, try "Search the Gravv docs for how to open an account" — the documentation tools work even before you have any.

Any MCP-compatible client works — the server speaks stdio and negotiates protocol version 2025-06-18, falling back to 2024-11-05 for older clients.

claude mcp add gravv --env GRAVV_API_KEY=grvSec_sandbox_... -- npx -y @gravv-infra/mcp

VS Code uses servers, not mcpServers, and requires an explicit type. Put this in .vscode/mcp.json to share with your team, or run MCP: Open User Configuration for a personal one:

{
  "servers": {
    "gravv": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@gravv-infra/mcp"],
      "env": { "GRAVV_API_KEY": "grvSec_sandbox_..." }
    }
  }
}

Or from the CLI:

code --add-mcp '{"name":"gravv","command":"npx","args":["-y","@gravv-infra/mcp"],"env":{"GRAVV_API_KEY":"grvSec_sandbox_..."}}'
codex mcp add gravv --env GRAVV_API_KEY=grvSec_sandbox_... -- npx -y @gravv-infra/mcp

Or in ~/.codex/config.toml:

[mcp_servers.gravv]
command = "npx"
args = ["-y", "@gravv-infra/mcp"]

[mcp_servers.gravv.env]
GRAVV_API_KEY = "grvSec_sandbox_..."

Verify with codex mcp list.

These use the mcpServers shape:

{
  "mcpServers": {
    "gravv": {
      "command": "npx",
      "args": ["-y", "@gravv-infra/mcp"],
      "env": { "GRAVV_API_KEY": "grvSec_sandbox_..." }
    }
  }
}

Client

Config file

Claude Desktop

claude_desktop_config.json (Settings → Developer → Edit Config)

Cursor

~/.cursor/mcp.json, or .cursor/mcp.json per project

Windsurf

~/.codeium/windsurf/mcp_config.json

Cline

the MCP Servers panel, or cline_mcp_settings.json

Zed

settings.json under context_servers

The server is a plain stdio MCP process. Point any client at:

command: npx
args:    ["-y", "@gravv-infra/mcp"]
env:     GRAVV_API_KEY=grvSec_sandbox_...

To try it without a client:

GRAVV_API_KEY=grvSec_sandbox_... npx -y @gravv-infra/mcp

then paste a JSON-RPC frame on stdin:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"manual","version":"1"}}}

Keep the key out of source control. Several clients support environment-variable substitution or secret prompts — prefer those over pasting a live key into a file you might commit. A sandbox key is the right thing to start with either way.


Related MCP server: M-Pesa MCP Server

What you get

Documentation toolssearchGravvDocs and getGravvDocPage search all 177 pages of the Gravv documentation. They need no API key, so you can explore Gravv before you have credentials.

API tools — 87 tools covering customers, KYC, accounts, transfers, cards, wallets, FX, collections, payment links, webhooks, and approvals.

Both matter. The API tools execute calls, but they can't tell you what has to happen first — that an account needs a KYC-verified customer, or that a new recipient must reach active before you can pay them. That's what the guides are for, so they're reachable from the same connector. Ask the assistant how to do something and it can look it up, write your integration, then run it against sandbox to prove it works.

npx @gravv-infra/mcp     # with GRAVV_API_KEY: docs + API tools
npx @gravv-infra/mcp     # without it: docs tools only, still useful

Safety model

Gravv moves real money, and sandbox and live share one base URL — only your key differs. Nothing in a request visually signals danger, so the server signals it.

Money-moving tools take two calls. createTransfer, withdrawFromCard, createFxOrder, createCollection, chargeSavedCard, approveTransfer, and approveFxOrder return a preview on the first call and execute only when called again with confirm: true. The unconfirmed call never reaches the API.

Approving is included because releasing a held instruction has the same consequence as initiating one. Rejecting is not gated — it only prevents execution.

> Send $50 from acc_1 to acc_2

  createTransfer({ amount: 50, ... })
  -> { status: "confirmation_required",
       willDo: "Transfer 50 USD from acc_1 to internal_account acc_2.
                Once submitted this cannot be reversed from the API." }

  [assistant shows this to you, you agree]

  createTransfer({ amount: 50, ..., confirm: true })
  -> { data: { transfer_id: "trf_1", status: "pending" } }

A live key needs a second independent signal. Money movement on a grvSec_live_ key is refused unless GRAVV_ALLOW_LIVE_WRITES=true is also set. Confirmation alone is not enough. An unrecognised key format is treated as live — it fails closed.

Cardholder data is never exposed. The endpoints returning card PAN, CVV, and PIN are not registered as tools under any configuration, and responses are scanned for card_number / cvv / pin and redacted on the way out. Use the client-side decryption flow for those.

Idempotency is automatic. Every write that needs an Idempotency-Key gets one, and the key used is returned with the result so a deliberate retry can reuse it.

--read-only disables every non-GET tool, for reporting deployments.


Toolsets

Everything except account-applications loads by default. Account onboarding carries large schemas and is an infrequent, deliberate flow, so it is opt-in.

npx @gravv-infra/mcp                                       # default
npx @gravv-infra/mcp --toolsets=customers,accounts,cards   # specific groups
npx @gravv-infra/mcp --toolsets=all                        # everything

Toolset

Default

Covers

customers

create, list, get, update customers

accounts

accounts and status

transfers

transfers, rates, supported countries and currencies

transactions

history, volume, export

external-accounts

recipients, verification, institutions

kyc

KYC start, server-to-server, document upload, status

cards

issue, balance, status, withdraw, applications

wallets

blockchain wallet creation and lookup

fx

quotes, rates, OTC orders

collections

card payment intents, saved cards, and pix / mobile money / bank transfer collections

payment-links

stablecoin payment links

features

feature eligibility and activation

webhooks

event history, delivery calls, retry

approvals

approve/reject transfers, recipients and FX orders

account-applications

account onboarding


Tool reference

* marks a tool that moves money and therefore requires confirm: true.

Documentation — always available, no API key needed searchGravvDocs · getGravvDocPage

customers createCustomer · getCustomer · listCustomers · updateCustomer

kyc startCustomerKyc · startCustomerKycS2S · uploadCustomerKycDocument · getCustomerKycDocuments · getCustomerKycStatus

accounts createAccount · getAccount · listAccounts · updateAccountStatus

external-accounts — recipients you pay out to createExternalAccount · getExternalAccount · listExternalAccounts · verifyExternalAccount · listExternalAccountInstitutions

transfers createTransfer* · getTransferRates · listTransferSupportedCurrencies · listTransferSupportedCountries · listTransferSupportedCountriesForAddress

transactions listTransactions · getTransaction · getTransactionsVolume · exportTransactions

cards createCard · getCard · listCards · getCardBalance · updateCardStatus · withdrawFromCard* · createCardApplication · getCardApplication · listCardApplications

wallets createWallet · getWallet · listWallets

fx getFxQuote · listFxRates · listFxCurrencyPairs · createFxOrder* · getFxOrder · listFxOrders · cancelFxOrder · listFxPendingApprovals

collections — taking money in

Card payments go through createCardPaymentIntent. It returns the same hosted payment link as a collection, plus the intent id and the card token that recurring and merchant-initiated charges need. createCollection covers the rails a payment intent cannot express — pix, mobile money, and bank transfer.

createCardPaymentIntent · chargeSavedCard* · listSavedCards · getSavedCard · deleteSavedCard · createCollection* · getCollection

payment-links createPaymentLink · getPaymentLink · listPaymentLinks · updatePaymentLink · updatePaymentLinkStatus · deletePaymentLink · getPublicPaymentLink

features listFeatures · checkFeatureEligibility · activateFeature

webhooks getWebhookHistory · getWebhookEventDetail · getWebhookCallHistory · retryWebhookEvent

approvals — sign off on held instructions approveTransfer* · rejectTransfer · approveExternalAccount · rejectExternalAccount · approveFxOrder* · rejectFxOrder · searchWebhookIngestion

account-applications — opt-in via --toolsets=account-applications createAccountApplication · updateAccountApplication · getAccountApplication · listAccountApplications · listPendingAccountApplications · deleteAccountApplication · submitAccountApplication · processAccountApplication · submitAndProcessAccountApplication · getAccountApplicationHistory · validateAccountApplication · completeAccountApplicationTos

Each tool's description carries its own prerequisites — several operations depend on something else having happened first, and the assistant reads those before calling.


A worked example

Asking an assistant to "pay a supplier in Nigeria 200 USD from my main account":

1. searchGravvDocs("send money to a Nigerian bank account")
   -> finds the remittance guide, learns the recipient must be `active`
      before a transfer will succeed

2. listAccounts()
   -> finds the funded USD account to pay from

3. listExternalAccountInstitutions({ country: "NG" })
   -> resolves the recipient's bank

4. createExternalAccount({ ...recipient details })
   -> returns status "pending" — not yet usable

5. getExternalAccount({ external_account_id })
   -> polls until status is "active"

6. createTransfer({ amount: 200, source, destination })
   -> returns a PREVIEW, does not execute:
      "Transfer 200 USD from acc_1 to external_account ext_9.
       Once submitted this cannot be reversed from the API."

   [you review and agree]

7. createTransfer({ ...same arguments, confirm: true })
   -> executes; returns transfer_id and status

Step 1 is what stops step 6 failing. Without the guides, an assistant tends to create the recipient and immediately transfer to it, before the payment rail has finished setting them up.


Going live

  1. Test the whole flow with your sandbox key first. Sandbox and live hold entirely separate data — an id from one does not exist in the other.

  2. Swap GRAVV_API_KEY for your live key. The base URL does not change.

  3. Reads and non-financial writes work immediately.

  4. Money movement stays blocked until you also set GRAVV_ALLOW_LIVE_WRITES=true. This is deliberate: swapping the key alone should not silently arm real payments.

{
  "mcpServers": {
    "gravv": {
      "command": "npx",
      "args": ["-y", "@gravv-infra/mcp"],
      "env": {
        "GRAVV_API_KEY": "grvSec_live_...",
        "GRAVV_ALLOW_LIVE_WRITES": "true"
      }
    }
  }
}

Consider a second, separate entry running --read-only against your live key for reporting, and keep writes on sandbox.


Troubleshooting

The server doesn't start Check node --version is 20 or later. Without GRAVV_API_KEY the server still starts, but only the two documentation tools load — that's expected, not a failure.

401 on every call The key was rejected. Confirm it is current and that you copied the whole value.

404 on an id you know exists You're probably in the other environment. Sandbox and live hold separate data. The environment field in every response tells you which one you're in.

"tool exists but its toolset is not loaded" Restart with --toolsets=all, or name the group the error mentions.

"Not available over MCP" on card PAN, CVV, or PIN Intentional and not configurable. Use the client-side decryption flow.

A transfer returned confirmation_required instead of running Working as designed. Call again with confirm: true after reviewing the preview.

422 mentioning an idempotency key The same key was reused with a different payload. A genuinely new operation needs a new key; the server generates one per call, so this usually means a retry changed the body.

Repeated 429 Lower GRAVV_RATE_PER_MINUTE.

Documentation search returns nothing It's keyword-based, not semantic. Rephrase using the vocabulary the docs use — "transfer" rather than an unusual synonym — or drop the section filter.


Configuration

Variable

Default

Purpose

GRAVV_API_KEY

Sandbox or live key; selects the environment. Omit for docs-only mode

GRAVV_ALLOW_LIVE_WRITES

unset

true permits money movement on a live key

GRAVV_RATE_PER_MINUTE

60

Client-side request throttle

GRAVV_BASE_URL

https://api.gravv.xyz

Override the API host

GRAVV_TOOLSETS

default set

Same as --toolsets

The client throttles requests locally and backs off on 429. If you hit rate limits, lower GRAVV_RATE_PER_MINUTE. See Rate limits.

Your API key is read from the environment and sent only to the Gravv API. It is never written to disk, logged, or included in tool output.


Notes

If a documentation search comes back empty, rephrase it. Search matches wording rather than meaning, so an unusual phrasing occasionally misses a page that does exist.


License

MIT — see LICENSE.

Available Tools

2 tools
getGravvDocPageA

Fetch the full text of one Gravv documentation page by slug, as returned by searchGravvDocs. Use when an excerpt is not enough — for worked examples, complete request/response bodies, or a full flow diagram.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugYesPage slug without the .md suffix, e.g. 'platform/wallets/create-a-wallet' or 'recipes/remit-funds-to-a-recipient'.

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the transparency burden and clearly communicates a read-only fetch operation. It does not mention edge cases like invalid slugs or response format, but the core behavior (returns full text) is transparent.

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

Conciseness5/5

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

Two sentences, each serving a distinct purpose: the first states the action, the second gives usage guidance. No wasted words and the key information is front-loaded.

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

Completeness4/5

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

For a simple one-parameter read tool, the description covers purpose, usage, and parameter provenance. It does not explicitly state the return type (e.g., plain text vs. markdown) or error behavior, but this is a minor gap given the tool's simplicity.

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

Parameters4/5

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

Schema coverage is 100% and the slug parameter already has a strong description with examples. The tool description adds the important semantic link 'as returned by searchGravvDocs,' telling the agent where to obtain the slug.

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

Purpose5/5

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

The description states a specific verb and resource: 'Fetch the full text of one Gravv documentation page by slug.' It clearly distinguishes from sibling searchGravvDocs by emphasizing full text vs. excerpt.

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

Usage Guidelines5/5

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

Explicitly says 'Use when an excerpt is not enough' and lists concrete use cases (worked examples, request/response bodies, flow diagram), which implies when not to use it and which alternative (searchGravvDocs) to prefer.

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

searchGravvDocsA

Search the Gravv documentation — integration guides, recipes, and API reference (177 pages). Use this BEFORE implementing any Gravv integration, and whenever a call fails in a way the error does not fully explain. The guides carry the ordering, prerequisites, and corridor rules that the API tool schemas do not. Returns ranked pages with excerpts; follow up with getGravvDocPage for full text.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum results. Default 6.
queryYesWhat you want to know, in natural language. e.g. 'create a wallet on polygon', 'why is my transfer pending', 'idempotency key rules'.
sectionNoOptional filter. 'Get Started' and 'Recipes' hold end-to-end flows; 'Developer Platform' holds per-feature guides; 'API Reference' holds per-endpoint detail.

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses that the tool returns ranked pages with excerpts, that the docs contain ordering/prerequisites/corridor rules not in schemas, and that it can help explain failures. It does not discuss rate limits or error behavior, but for a search tool the disclosed behavioral traits are sufficient.

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

Conciseness5/5

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

The description is concise and well-structured: it opens with the core purpose, then gives usage timing and alternatives, and ends with a follow-up action. Every sentence adds value with no redundancy.

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

Completeness5/5

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

Given the tool's simplicity (3 parameters, no nested objects, no output schema) and the presence of a sibling for full text, the description covers purpose, usage, return format, and follow-up behavior. It is fully complete for an agent to select and invoke this tool correctly.

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

Parameters3/5

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

The input schema already provides 100% description coverage for all parameters, including examples for query. The description does not add additional parameter-specific semantics, so the baseline of 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool searches the Gravv documentation with specific resource types (integration guides, recipes, API reference) and page count (177 pages). It distinguishes itself from the sibling tool getGravvDocPage by explicitly indicating that this tool returns ranked excerpts and that getGravvDocPage should be used for full text.

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

Usage Guidelines5/5

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

The description gives explicit timing: use before implementing any Gravv integration and whenever a call fails with an unclear error. It also names the alternative (getGravvDocPage) as a follow-up step, providing clear when-to-use and when-to-use-other guidance.

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.

  1. 2 tool updatesv0.1.0
    • First observedgetGravvDocPage
    • First observedsearchGravvDocs

TDQS

A4.6/5.0
Disambiguation5/5

Each tool has a distinct, non-overlapping purpose: one searches documentation, the other fetches a specific page by slug. No ambiguity between them.

Naming Consistency5/5

Both tools follow a consistent CamelCase pattern with a verb (search, get) followed by the subject (GravvDocs, GravvDocPage). Naming is uniform and predictable.

Tool Count4/5

With only 2 tools, the server is on the lean side, but for a documentation-searching purpose the pair is reasonable and well-scoped.

Completeness4/5

The tools cover the core documentation workflow—search and retrieve full text. A minor gap is the lack of a browse-all-pages feature, but the essential operations are present.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for AgentPay — the payment gateway for autonomous AI agents. Fund a wallet once, give your agent the key, and it discovers, provisions, and pays for tool APIs on its own. One key, every tool.
    112
    1
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A local MCP server that lets AI agents interact with the Adaptis (MEG) payment gateway, enabling payment link creation, transaction queries, refunds, and integration helpers like generating signed forms and verifying callbacks.
    -

Latest Blog Posts

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/GravityFinance/gravv-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server