@ramp-kit/mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/docs.d.ts +8 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +196 -0
- package/dist/docs.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +249 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Armando Cruz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# @ramp-kit/mcp
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for the
|
|
4
|
+
[LATAM Ramp Kit](https://github.com/armandocodecr/latam-ramp-kit): lets AI
|
|
5
|
+
agents (Claude Code, Claude Desktop, Cursor, or any MCP client) explore,
|
|
6
|
+
explain and **operate** LATAM fiat ramps on Stellar.
|
|
7
|
+
|
|
8
|
+
Works with zero configuration (mock provider) and comes alive with an
|
|
9
|
+
Etherfuse sandbox key — agents can then fetch real quotes, create sandbox
|
|
10
|
+
orders, simulate PIX/SPEI deposits and watch them settle on Stellar Testnet.
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
Claude Code:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
claude mcp add ramp-kit -e ETHERFUSE_API_KEY=api_sand_… -- npx -y @ramp-kit/mcp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Any MCP client (`mcpServers` config):
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"ramp-kit": {
|
|
26
|
+
"command": "npx",
|
|
27
|
+
"args": ["-y", "@ramp-kit/mcp"],
|
|
28
|
+
"env": { "ETHERFUSE_API_KEY": "api_sand_…" }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Environment variables (all optional):
|
|
35
|
+
|
|
36
|
+
| Variable | Effect |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `ETHERFUSE_API_KEY` | Enables live Etherfuse tools (sandbox key: [sandbox.etherfuse.com](https://sandbox.etherfuse.com)) |
|
|
39
|
+
| `MANTECA_API_KEY` | Enables the Manteca provider in routing/comparison |
|
|
40
|
+
| `RAMPKIT_ENV` | `sandbox` (default) or `production` |
|
|
41
|
+
|
|
42
|
+
## Tools
|
|
43
|
+
|
|
44
|
+
| Tool | What it does |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `get_documentation` | Built-in docs: overview, quickstart, sandbox-setup, architecture, production, troubleshooting |
|
|
47
|
+
| `list_providers` | Configured providers + capabilities (countries, rails, networks) |
|
|
48
|
+
| `list_assets` | Tradable assets (environment-specific identifiers) |
|
|
49
|
+
| `get_quote` | Live quote with rate, fees and expiry countdown |
|
|
50
|
+
| `compare_quotes` | Same request fanned out to every eligible provider |
|
|
51
|
+
| `create_order` | Quote → order, returns PIX/SPEI deposit instructions |
|
|
52
|
+
| `get_order` | Normalized order status until settled/failed |
|
|
53
|
+
| `simulate_deposit` | **Sandbox-only**: simulate the incoming fiat payment |
|
|
54
|
+
| `get_wallet_state` | Stellar account existence, balances, pending claimable balances |
|
|
55
|
+
|
|
56
|
+
## Safety
|
|
57
|
+
|
|
58
|
+
- Never handles secret keys — signing stays in the user's wallet
|
|
59
|
+
(`claimPendingBalances` in `@ramp-kit/core` takes a signing callback).
|
|
60
|
+
- `simulate_deposit` refuses to run when `RAMPKIT_ENV=production`.
|
|
61
|
+
- Quotes are session-scoped; orders only execute against the environment the
|
|
62
|
+
server was configured for.
|
|
63
|
+
|
|
64
|
+
## Example agent session
|
|
65
|
+
|
|
66
|
+
> "Quote 100 BRL to USDC on Stellar and walk me through what happens"
|
|
67
|
+
|
|
68
|
+
The agent calls `list_assets` → `get_quote` → explains the rate/fees/expiry,
|
|
69
|
+
then optionally `create_order` → `simulate_deposit` → `get_order` until
|
|
70
|
+
`settled`, and `get_wallet_state` to show the delivered tokens.
|
|
71
|
+
|
|
72
|
+
MIT © [Armando Cruz](https://github.com/armandocodecr) ·
|
|
73
|
+
[Repository](https://github.com/armandocodecr/latam-ramp-kit)
|
package/dist/docs.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedded documentation served by the get_documentation tool. Condensed
|
|
3
|
+
* from the repository docs so agents can answer without network access.
|
|
4
|
+
*/
|
|
5
|
+
export declare const TOPICS: readonly ["overview", "quickstart", "sandbox-setup", "architecture", "production", "troubleshooting"];
|
|
6
|
+
export type Topic = (typeof TOPICS)[number];
|
|
7
|
+
export declare const DOCS: Record<Topic, string>;
|
|
8
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,MAAM,uGAOT,CAAC;AAEX,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5C,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CA2LtC,CAAC"}
|
package/dist/docs.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedded documentation served by the get_documentation tool. Condensed
|
|
3
|
+
* from the repository docs so agents can answer without network access.
|
|
4
|
+
*/
|
|
5
|
+
export const TOPICS = [
|
|
6
|
+
"overview",
|
|
7
|
+
"quickstart",
|
|
8
|
+
"sandbox-setup",
|
|
9
|
+
"architecture",
|
|
10
|
+
"production",
|
|
11
|
+
"troubleshooting",
|
|
12
|
+
];
|
|
13
|
+
export const DOCS = {
|
|
14
|
+
overview: `# LATAM Ramp Kit — overview
|
|
15
|
+
|
|
16
|
+
**Problem it solves:** every LATAM app that moves money between banks and
|
|
17
|
+
blockchains re-integrates ramp providers from scratch. Each provider has its
|
|
18
|
+
own API, auth, KYC model, order states and price-expiry rules — and none
|
|
19
|
+
covers the whole region (the best Brazil/PIX rails don't settle on Stellar;
|
|
20
|
+
the Stellar-native provider is Mexico-first). Weeks of work, duplicated by
|
|
21
|
+
every team.
|
|
22
|
+
|
|
23
|
+
**Solution:** one TypeScript interface (\`RampProvider\`) over real providers,
|
|
24
|
+
with a normalized order lifecycle, a prebuilt React widget, a provider
|
|
25
|
+
router, Stellar-specific helpers, and a production backend. Swap providers
|
|
26
|
+
with one line.
|
|
27
|
+
|
|
28
|
+
**Packages (npm):**
|
|
29
|
+
- \`@ramp-kit/core\` — SDK: EtherfuseProvider (Stellar-native, PIX/SPEI),
|
|
30
|
+
MantecaProvider (LATAM rails, EVM/Tron settlement), MockProvider (dev),
|
|
31
|
+
RampRouter (country/currency routing + live quote comparison), Stellar
|
|
32
|
+
helpers (trustlines, claimable-balance claims, tx signing).
|
|
33
|
+
- \`@ramp-kit/react\` — <RampWidget /> 3-step flow + useQuote/useOrder hooks.
|
|
34
|
+
- \`@ramp-kit/server\` — zero-dependency production proxy (server-held API
|
|
35
|
+
key, endpoint allowlist) + webhook signature verification.
|
|
36
|
+
- \`@ramp-kit/mcp\` — this MCP server.
|
|
37
|
+
|
|
38
|
+
**Proven end-to-end on Stellar Testnet:** 100 BRL entered via PIX (Etherfuse
|
|
39
|
+
sandbox) and settled as 19.0097 USDC in a fresh Stellar wallet — account
|
|
40
|
+
creation sponsored by the provider, tokens delivered via claimable balance,
|
|
41
|
+
claimed with one kit helper. Repo:
|
|
42
|
+
https://github.com/armandocodecr/latam-ramp-kit`,
|
|
43
|
+
quickstart: `# Quickstart
|
|
44
|
+
|
|
45
|
+
## Zero credentials (MockProvider)
|
|
46
|
+
\`\`\`ts
|
|
47
|
+
import { MockProvider } from "@ramp-kit/core";
|
|
48
|
+
const provider = new MockProvider({ autoFundMs: 4000 });
|
|
49
|
+
const assets = await provider.listAssets("stellar");
|
|
50
|
+
const quote = await provider.getQuote({
|
|
51
|
+
direction: "onramp", fiatCurrency: "BRL",
|
|
52
|
+
assetIdentifier: assets[0].identifier, network: "stellar",
|
|
53
|
+
sourceAmount: "100", customerId: "user-1",
|
|
54
|
+
});
|
|
55
|
+
const order = await provider.createOrder(quote);
|
|
56
|
+
// order auto-advances: awaiting_deposit → processing → settled
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
## Real sandbox (Etherfuse, Stellar Testnet, no real money)
|
|
60
|
+
\`\`\`ts
|
|
61
|
+
import { EtherfuseProvider } from "@ramp-kit/core";
|
|
62
|
+
const provider = new EtherfuseProvider({ apiKey, environment: "sandbox" });
|
|
63
|
+
|
|
64
|
+
const org = await provider.getOrganization(); // customerId
|
|
65
|
+
const accounts = await provider.listBankAccounts(); // pick compliant one
|
|
66
|
+
provider.setBankAccount(accounts.find(a => a.compliant)!.bankAccountId);
|
|
67
|
+
await provider.registerWallet(walletAddress, "stellar"); // one-time, required
|
|
68
|
+
|
|
69
|
+
const assets = await provider.listAssets("stellar", { currency: "brl" });
|
|
70
|
+
const quote = await provider.getQuote({ direction: "onramp",
|
|
71
|
+
fiatCurrency: "BRL", assetIdentifier: assets[0].identifier,
|
|
72
|
+
network: "stellar", sourceAmount: "100",
|
|
73
|
+
customerId: org.id, walletAddress });
|
|
74
|
+
const order = await provider.createOrder(quote);
|
|
75
|
+
await provider.simulateFiatReceived(order.id); // sandbox only
|
|
76
|
+
// poll provider.getOrder(order.id) until "settled"
|
|
77
|
+
\`\`\`
|
|
78
|
+
|
|
79
|
+
## React widget
|
|
80
|
+
\`\`\`tsx
|
|
81
|
+
import { RampWidget } from "@ramp-kit/react";
|
|
82
|
+
<RampWidget provider={provider} customerId={org.id} fiatCurrency="BRL"
|
|
83
|
+
network="stellar" walletAddress={wallet} assets={assets} />
|
|
84
|
+
\`\`\`
|
|
85
|
+
|
|
86
|
+
Key rules: quotes expire (Etherfuse: 2 min) — check \`expiresAt\`; never
|
|
87
|
+
hardcode asset identifiers — always discover via listAssets(); wallets must
|
|
88
|
+
be registered before their first order.`,
|
|
89
|
+
"sandbox-setup": `# Etherfuse sandbox setup (one time, ~10 minutes)
|
|
90
|
+
|
|
91
|
+
1. Create an account at https://sandbox.etherfuse.com
|
|
92
|
+
2. Approve your own KYB with the sandbox "Approve KYB" button (instant).
|
|
93
|
+
3. Bank account for the fiat leg:
|
|
94
|
+
- **BRL/PIX (recommended):** dashboard → "Add BRL Bank Account (PIX)" —
|
|
95
|
+
pre-filled with test values, compliant instantly.
|
|
96
|
+
- **MXN/SPEI:** register with test RFC XEXX010101000 (personal) or
|
|
97
|
+
XEX010101000 (business); CLABE must NOT start with 646 (STP rejected).
|
|
98
|
+
API-registered MXN accounts await async approval (email arrives later).
|
|
99
|
+
4. Copy your api_sand_… key from Account → Manage.
|
|
100
|
+
|
|
101
|
+
Sandbox behaviors worth knowing:
|
|
102
|
+
- Base URL: https://api.sand.etherfuse.com — Stellar Testnet settlement.
|
|
103
|
+
- Simulate incoming fiat: POST /ramp/order/fiat_received (≤500 per quote) —
|
|
104
|
+
in the SDK: provider.simulateFiatReceived(orderId).
|
|
105
|
+
- KYC accepts fake data and auto-approves.
|
|
106
|
+
- Fresh wallets don't need funding: Etherfuse sponsors account creation and
|
|
107
|
+
delivers tokens as claimable balances (claim with claimPendingBalances).
|
|
108
|
+
|
|
109
|
+
Manteca sandbox (https://sandbox.manteca.dev/crypto/v2) requires credentials
|
|
110
|
+
from the Manteca team (not self-service): md-api-key header, faucet at
|
|
111
|
+
faucet.manteca.dev, PIX test QRs ("pix", "pixmanualamount"), names containing
|
|
112
|
+
"fail" simulate rejected onboarding.`,
|
|
113
|
+
architecture: `# Architecture
|
|
114
|
+
|
|
115
|
+
## Normalized lifecycle (every provider maps into this)
|
|
116
|
+
created → awaiting_deposit → awaiting_signature? → processing → settled
|
|
117
|
+
↘ failed | cancelled
|
|
118
|
+
|
|
119
|
+
## Provider model mapping
|
|
120
|
+
| Concept | Etherfuse | Manteca | Kit exposes |
|
|
121
|
+
| Pricing | quote (2 min) | price lock (expireAt) | RampQuote.expiresAt |
|
|
122
|
+
| Execution | order | synthetic (stages) | RampOrder.status |
|
|
123
|
+
| Deposit info | CLABE / PIX charge | details.depositAddress | DepositInstructions |
|
|
124
|
+
|
|
125
|
+
## Stellar specifics the kit absorbs
|
|
126
|
+
- Trustlines: receiving any non-XLM asset requires one (+0.5 XLM reserve).
|
|
127
|
+
- Sponsored onboarding: Etherfuse funds new accounts (~1.5 XLM) and delivers
|
|
128
|
+
tokens as claimable balances; claimPendingBalances() builds trustline +
|
|
129
|
+
claim in one tx with callback-based signing (Freighter/hardware pluggable).
|
|
130
|
+
- Provider-built txs expire in ~1-2 min → regenerateTx(orderId) on
|
|
131
|
+
tx_too_late.
|
|
132
|
+
- Asset ids are "CODE:ISSUER" and differ per environment — always discover.
|
|
133
|
+
|
|
134
|
+
## Router
|
|
135
|
+
RampRouter.register(provider…).resolve({country, fiatCurrency}) picks the
|
|
136
|
+
best provider (Stellar-native preferred); compareQuotes() fans out a request
|
|
137
|
+
and returns live quotes sorted by best target amount.
|
|
138
|
+
|
|
139
|
+
## Errors
|
|
140
|
+
RampError { provider, code: auth | quote_expired | tx_expired |
|
|
141
|
+
kyc_required | unsupported | network | provider_error }.`,
|
|
142
|
+
production: `# Path to production
|
|
143
|
+
|
|
144
|
+
## Ready in code today
|
|
145
|
+
- environment: "sandbox" | "production" on every provider flips base URLs;
|
|
146
|
+
stellarConfigFor("production") → mainnet Horizon + passphrase.
|
|
147
|
+
- @ramp-kit/server: createRampServer({ proxy, webhooks }) — API key stays
|
|
148
|
+
server-side; browser reaches an allowlisted surface only (quote/order/
|
|
149
|
+
status/assets); sandbox simulation hard-blocked in production.
|
|
150
|
+
- Webhooks: createEtherfuseWebhookHandler verifies X-Signature (HMAC-SHA256
|
|
151
|
+
over RFC 8785-canonicalized JSON, constant-time compare), acks 2xx fast,
|
|
152
|
+
dispatches typed events. verifyMantecaSignature for Manteca's HMAC.
|
|
153
|
+
- Signing is callback-based → real wallets (Freighter/hardware) plug in.
|
|
154
|
+
|
|
155
|
+
## External steps (provider onboarding, not code)
|
|
156
|
+
1. Etherfuse production KYB (manual legal-entity review, days/weeks) →
|
|
157
|
+
api_prod_… key; register real bank accounts (real CLABE/RFC); confirm
|
|
158
|
+
BRL/PIX production availability (live in sandbox, listed upcoming for
|
|
159
|
+
production).
|
|
160
|
+
2. End-user KYC: hosted identity flow with real documents + liveness.
|
|
161
|
+
3. Manteca: commercial onboarding → production md-api-key, per-country
|
|
162
|
+
permissions (BRL/PIX), webhook secret + signature header confirmation.
|
|
163
|
+
4. Deploy @ramp-kit/server behind HTTPS; register webhook URL via
|
|
164
|
+
POST /ramp/webhook; store the one-time secret.
|
|
165
|
+
5. Persist quote/order idempotency UUIDs and webhook events (dedupe by
|
|
166
|
+
resource id + status).
|
|
167
|
+
|
|
168
|
+
## Frontend switch
|
|
169
|
+
Point the provider at your proxy instead of the sandbox:
|
|
170
|
+
new EtherfuseProvider({ apiKey: "", baseUrl: "https://api.myapp.com/etherfuse" })`,
|
|
171
|
+
troubleshooting: `# Troubleshooting (verified against the real sandbox)
|
|
172
|
+
|
|
173
|
+
- "Wallet not found or not authorized" on POST /ramp/order → the wallet was
|
|
174
|
+
never registered. Call provider.registerWallet(publicKey, "stellar")
|
|
175
|
+
(claimOwnership=true lets a KYB-approved org skip per-wallet KYC).
|
|
176
|
+
- "Bank account is not compliant with KYC requirements" → the selected bank
|
|
177
|
+
account's compliant flag is false. MXN accounts registered via API await
|
|
178
|
+
async approval; dashboard-created BRL/PIX accounts are compliant
|
|
179
|
+
instantly. Pick another account (listBankAccounts shows the flag).
|
|
180
|
+
- "Proxy account not found" on order creation → the bank account is
|
|
181
|
+
compliant but not provisioned for that rail (seen with some BRL accounts).
|
|
182
|
+
Use the PIX account created via the dashboard button.
|
|
183
|
+
- "Query deserialize error: missing field …" on GET /ramp/assets → the
|
|
184
|
+
endpoint requires blockchain + currency + wallet; the SDK fills defaults,
|
|
185
|
+
raw callers must pass all three.
|
|
186
|
+
- STP CLABEs rejected → sandbox refuses CLABEs starting with 646; use
|
|
187
|
+
another bank code (e.g. 012…).
|
|
188
|
+
- tx_too_late on submit → provider-built Stellar txs expire in ~1-2 min;
|
|
189
|
+
call regenerateTx(orderId) and re-sign (signAndSubmit raises
|
|
190
|
+
RampError("tx_expired") to signal this).
|
|
191
|
+
- Quote expired → quotes live 2 minutes; re-quote (useQuote does this
|
|
192
|
+
automatically in React).
|
|
193
|
+
- Claimable balance not received in wallet balance → it's waiting to be
|
|
194
|
+
claimed: getPendingBalances(pub) then claimPendingBalances(pub, sign).`,
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=docs.js.map
|
package/dist/docs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,UAAU;IACV,YAAY;IACZ,eAAe;IACf,cAAc;IACd,YAAY;IACZ,iBAAiB;CACT,CAAC;AAIX,MAAM,CAAC,MAAM,IAAI,GAA0B;IACzC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;gDA4BoC;IAE9C,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCA6C0B;IAEtC,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;qCAuBkB;IAEnC,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDA4ByC;IAEvD,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA4BoE;IAEhF,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;yEAuBsD;CACxE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { EtherfuseProvider, MantecaProvider, MockProvider, RampRouter, getAccountState, getPendingBalances, stellarConfigFor, } from "@ramp-kit/core";
|
|
6
|
+
import { DOCS, TOPICS } from "./docs.js";
|
|
7
|
+
/**
|
|
8
|
+
* MCP server for the LATAM Ramp Kit.
|
|
9
|
+
*
|
|
10
|
+
* Configuration (environment variables):
|
|
11
|
+
* - ETHERFUSE_API_KEY — enables live Etherfuse tools (otherwise mock only)
|
|
12
|
+
* - MANTECA_API_KEY — enables the Manteca provider in the router
|
|
13
|
+
* - RAMPKIT_ENV — "sandbox" (default) | "production"
|
|
14
|
+
*
|
|
15
|
+
* Safety: never handles secret keys — signing stays in the user's wallet.
|
|
16
|
+
* The deposit simulation tool refuses to run outside the sandbox.
|
|
17
|
+
*/
|
|
18
|
+
const environment = (process.env.RAMPKIT_ENV ?? "sandbox");
|
|
19
|
+
const etherfuseKey = process.env.ETHERFUSE_API_KEY;
|
|
20
|
+
const mantecaKey = process.env.MANTECA_API_KEY;
|
|
21
|
+
const mock = new MockProvider({ autoFundMs: 4000 });
|
|
22
|
+
const etherfuse = etherfuseKey
|
|
23
|
+
? new EtherfuseProvider({ apiKey: etherfuseKey, environment })
|
|
24
|
+
: null;
|
|
25
|
+
const manteca = mantecaKey
|
|
26
|
+
? new MantecaProvider({ apiKey: mantecaKey, environment })
|
|
27
|
+
: null;
|
|
28
|
+
const router = new RampRouter();
|
|
29
|
+
if (etherfuse)
|
|
30
|
+
router.register(etherfuse);
|
|
31
|
+
if (manteca)
|
|
32
|
+
router.register(manteca);
|
|
33
|
+
router.register(mock);
|
|
34
|
+
/** Quotes are stateful between get_quote and create_order. */
|
|
35
|
+
const quotes = new Map();
|
|
36
|
+
function resolveProvider(name) {
|
|
37
|
+
if (!name || name === "auto")
|
|
38
|
+
return etherfuse ?? mock;
|
|
39
|
+
const found = [etherfuse, manteca, mock].find((p) => p?.name === name);
|
|
40
|
+
if (!found) {
|
|
41
|
+
throw new Error(`Provider "${name}" not configured. Available: ${[etherfuse, manteca, mock]
|
|
42
|
+
.filter(Boolean)
|
|
43
|
+
.map((p) => p.name)
|
|
44
|
+
.join(", ")}`);
|
|
45
|
+
}
|
|
46
|
+
return found;
|
|
47
|
+
}
|
|
48
|
+
function text(value) {
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: typeof value === "string" ? value : JSON.stringify(value, null, 2),
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const server = new McpServer({ name: "ramp-kit", version: "0.1.0" });
|
|
59
|
+
server.tool("get_documentation", "LATAM Ramp Kit documentation. Topics: overview (what it is and solves), quickstart (code to integrate), sandbox-setup (Etherfuse/Manteca test credentials), architecture (lifecycle, provider mapping, Stellar specifics), production (path to mainnet), troubleshooting (verified error fixes). Start here.", { topic: z.enum(TOPICS).describe("Documentation topic to read") }, async ({ topic }) => text(DOCS[topic]));
|
|
60
|
+
server.tool("list_providers", "List configured ramp providers with their capabilities (countries, fiat currencies, settlement networks, Stellar-native flag) and whether live credentials are present.", {}, async () => text({
|
|
61
|
+
environment,
|
|
62
|
+
providers: [etherfuse, manteca, mock].filter(Boolean).map((p) => ({
|
|
63
|
+
name: p.name,
|
|
64
|
+
live: p.name !== "mock",
|
|
65
|
+
capabilities: p.capabilities,
|
|
66
|
+
})),
|
|
67
|
+
note: etherfuse
|
|
68
|
+
? undefined
|
|
69
|
+
: "No ETHERFUSE_API_KEY set — only the mock provider is available. Get a sandbox key at https://sandbox.etherfuse.com",
|
|
70
|
+
}));
|
|
71
|
+
server.tool("list_assets", "List tradable assets for a provider on a network. Asset identifiers are environment-specific — always use these, never hardcode.", {
|
|
72
|
+
provider: z.string().optional().describe('Provider name or "auto" (default)'),
|
|
73
|
+
network: z.string().optional().describe("Network, default stellar"),
|
|
74
|
+
currency: z.string().optional().describe("Fiat currency hint, e.g. brl"),
|
|
75
|
+
}, async ({ provider, network, currency }) => {
|
|
76
|
+
const p = resolveProvider(provider);
|
|
77
|
+
const assets = await p.listAssets((network ?? "stellar"), {
|
|
78
|
+
currency: currency ?? "brl",
|
|
79
|
+
});
|
|
80
|
+
return text({ provider: p.name, assets });
|
|
81
|
+
});
|
|
82
|
+
server.tool("get_quote", "Get a live ramp quote (fiat→crypto or crypto→fiat). Returns target amount, rate, fees and expiry. The quote id can be passed to create_order before it expires.", {
|
|
83
|
+
provider: z.string().optional(),
|
|
84
|
+
direction: z.enum(["onramp", "offramp"]),
|
|
85
|
+
fiatCurrency: z.string().describe("e.g. BRL, MXN"),
|
|
86
|
+
assetIdentifier: z.string().describe("From list_assets"),
|
|
87
|
+
network: z.string().optional().describe("Default stellar"),
|
|
88
|
+
sourceAmount: z.string().describe("Decimal string, fiat for onramp"),
|
|
89
|
+
walletAddress: z.string().optional().describe("Destination Stellar address"),
|
|
90
|
+
}, async (args) => {
|
|
91
|
+
const p = resolveProvider(args.provider);
|
|
92
|
+
let customerId = "mcp-user";
|
|
93
|
+
if (p instanceof EtherfuseProvider) {
|
|
94
|
+
customerId = (await p.getOrganization()).id;
|
|
95
|
+
}
|
|
96
|
+
const request = {
|
|
97
|
+
direction: args.direction,
|
|
98
|
+
fiatCurrency: args.fiatCurrency,
|
|
99
|
+
assetIdentifier: args.assetIdentifier,
|
|
100
|
+
network: (args.network ?? "stellar"),
|
|
101
|
+
sourceAmount: args.sourceAmount,
|
|
102
|
+
customerId,
|
|
103
|
+
walletAddress: args.walletAddress,
|
|
104
|
+
};
|
|
105
|
+
const quote = await p.getQuote(request);
|
|
106
|
+
quotes.set(quote.id, { provider: p, quote });
|
|
107
|
+
return text({
|
|
108
|
+
quoteId: quote.id,
|
|
109
|
+
provider: quote.provider,
|
|
110
|
+
youPay: `${quote.request.sourceAmount} ${quote.request.fiatCurrency}`,
|
|
111
|
+
youReceive: quote.targetAmount,
|
|
112
|
+
rate: quote.rate,
|
|
113
|
+
fees: quote.fees,
|
|
114
|
+
expiresAt: quote.expiresAt.toISOString(),
|
|
115
|
+
secondsLeft: Math.max(0, Math.floor((quote.expiresAt.getTime() - Date.now()) / 1000)),
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
server.tool("compare_quotes", "Fan the same quote request out to every eligible provider and compare live rates (multi-anchor comparison).", {
|
|
119
|
+
direction: z.enum(["onramp", "offramp"]),
|
|
120
|
+
fiatCurrency: z.string(),
|
|
121
|
+
assetIdentifier: z.string(),
|
|
122
|
+
network: z.string().optional(),
|
|
123
|
+
sourceAmount: z.string(),
|
|
124
|
+
walletAddress: z.string().optional(),
|
|
125
|
+
}, async (args) => {
|
|
126
|
+
let customerId = "mcp-user";
|
|
127
|
+
if (etherfuse)
|
|
128
|
+
customerId = (await etherfuse.getOrganization()).id;
|
|
129
|
+
const request = {
|
|
130
|
+
direction: args.direction,
|
|
131
|
+
fiatCurrency: args.fiatCurrency,
|
|
132
|
+
assetIdentifier: args.assetIdentifier,
|
|
133
|
+
network: (args.network ?? "stellar"),
|
|
134
|
+
sourceAmount: args.sourceAmount,
|
|
135
|
+
customerId,
|
|
136
|
+
walletAddress: args.walletAddress,
|
|
137
|
+
};
|
|
138
|
+
const results = await router.compareQuotes(request, {
|
|
139
|
+
fiatCurrency: request.fiatCurrency,
|
|
140
|
+
network: request.network,
|
|
141
|
+
});
|
|
142
|
+
for (const q of results) {
|
|
143
|
+
const p = [etherfuse, manteca, mock].find((x) => x?.name === q.provider);
|
|
144
|
+
if (p)
|
|
145
|
+
quotes.set(q.id, { provider: p, quote: q });
|
|
146
|
+
}
|
|
147
|
+
return text(results.map((q) => ({
|
|
148
|
+
provider: q.provider,
|
|
149
|
+
quoteId: q.id,
|
|
150
|
+
youReceive: q.targetAmount,
|
|
151
|
+
rate: q.rate,
|
|
152
|
+
expiresAt: q.expiresAt.toISOString(),
|
|
153
|
+
})));
|
|
154
|
+
});
|
|
155
|
+
server.tool("create_order", "Turn a live quote (from get_quote/compare_quotes) into an order. Returns the normalized order with deposit instructions (PIX charge or SPEI CLABE). Sandbox/mock only through this server unless RAMPKIT_ENV=production.", {
|
|
156
|
+
quoteId: z.string().describe("Quote id returned by get_quote"),
|
|
157
|
+
bankAccountId: z
|
|
158
|
+
.string()
|
|
159
|
+
.optional()
|
|
160
|
+
.describe("Etherfuse fiat-leg bank account (defaults to first compliant)"),
|
|
161
|
+
}, async ({ quoteId, bankAccountId }) => {
|
|
162
|
+
const entry = quotes.get(quoteId);
|
|
163
|
+
if (!entry) {
|
|
164
|
+
throw new Error(`Unknown quoteId ${quoteId} — quotes are session-scoped; call get_quote first`);
|
|
165
|
+
}
|
|
166
|
+
const { provider, quote } = entry;
|
|
167
|
+
if (provider instanceof EtherfuseProvider) {
|
|
168
|
+
if (bankAccountId) {
|
|
169
|
+
provider.setBankAccount(bankAccountId);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const accounts = await provider.listBankAccounts();
|
|
173
|
+
const compliant = accounts.find((a) => a.compliant);
|
|
174
|
+
if (!compliant) {
|
|
175
|
+
throw new Error("No compliant bank account found — create a PIX account in the Etherfuse sandbox dashboard");
|
|
176
|
+
}
|
|
177
|
+
provider.setBankAccount(compliant.bankAccountId);
|
|
178
|
+
}
|
|
179
|
+
if (quote.request.walletAddress) {
|
|
180
|
+
await provider.registerWallet(quote.request.walletAddress, quote.request.network);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const order = await provider.createOrder(quote);
|
|
184
|
+
return text({
|
|
185
|
+
orderId: order.id,
|
|
186
|
+
provider: order.provider,
|
|
187
|
+
status: order.status,
|
|
188
|
+
depositInstructions: order.depositInstructions,
|
|
189
|
+
nextStep: provider.name === "etherfuse" && environment === "sandbox"
|
|
190
|
+
? "Fund it with simulate_deposit (sandbox), then poll get_order until settled"
|
|
191
|
+
: "Fund the deposit, then poll get_order until settled",
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
server.tool("get_order", "Fetch the current normalized state of an order (created → awaiting_deposit → processing → settled | failed | cancelled).", {
|
|
195
|
+
provider: z.string().optional(),
|
|
196
|
+
orderId: z.string(),
|
|
197
|
+
}, async ({ provider, orderId }) => {
|
|
198
|
+
const p = resolveProvider(provider);
|
|
199
|
+
const order = await p.getOrder(orderId);
|
|
200
|
+
return text({
|
|
201
|
+
orderId: order.id,
|
|
202
|
+
status: order.status,
|
|
203
|
+
txHash: order.txHash,
|
|
204
|
+
failureReason: order.failureReason,
|
|
205
|
+
updatedAt: order.updatedAt.toISOString(),
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
server.tool("simulate_deposit", "SANDBOX ONLY: simulate the incoming fiat transfer (PIX/SPEI) for an order, as if the user paid. Refuses to run in production.", {
|
|
209
|
+
provider: z.string().optional(),
|
|
210
|
+
orderId: z.string(),
|
|
211
|
+
}, async ({ provider, orderId }) => {
|
|
212
|
+
if (environment === "production") {
|
|
213
|
+
throw new Error("simulate_deposit is sandbox-only");
|
|
214
|
+
}
|
|
215
|
+
const p = resolveProvider(provider);
|
|
216
|
+
if (!("simulateFiatReceived" in p)) {
|
|
217
|
+
throw new Error(`Provider ${p.name} does not support deposit simulation`);
|
|
218
|
+
}
|
|
219
|
+
await p.simulateFiatReceived(orderId);
|
|
220
|
+
return text({
|
|
221
|
+
ok: true,
|
|
222
|
+
note: "Deposit simulated — poll get_order until status is settled",
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
server.tool("get_wallet_state", "Inspect a Stellar wallet: does the account exist, XLM balance, asset balances, and claimable balances waiting to be claimed (sponsored onramp deliveries).", {
|
|
226
|
+
publicKey: z.string().describe("Stellar public key (G…)"),
|
|
227
|
+
assetIdentifier: z
|
|
228
|
+
.string()
|
|
229
|
+
.optional()
|
|
230
|
+
.describe('Optional "CODE:ISSUER" to check a specific trustline'),
|
|
231
|
+
}, async ({ publicKey, assetIdentifier }) => {
|
|
232
|
+
const stellar = stellarConfigFor(environment);
|
|
233
|
+
const pending = await getPendingBalances(publicKey, stellar);
|
|
234
|
+
let state = null;
|
|
235
|
+
if (assetIdentifier) {
|
|
236
|
+
state = await getAccountState(publicKey, assetIdentifier, stellar);
|
|
237
|
+
}
|
|
238
|
+
return text({
|
|
239
|
+
network: environment === "production" ? "mainnet" : "testnet",
|
|
240
|
+
accountState: state,
|
|
241
|
+
pendingClaimableBalances: pending,
|
|
242
|
+
note: pending.length > 0
|
|
243
|
+
? "Claim with claimPendingBalances(publicKey, sign) from @ramp-kit/core — signing happens in the user's wallet, never share secret keys"
|
|
244
|
+
: undefined,
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
const transport = new StdioServerTransport();
|
|
248
|
+
await server.connect(transport);
|
|
249
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ramp-kit/mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for the LATAM Ramp Kit: lets AI agents explore providers, fetch live ramp quotes, create sandbox orders, simulate PIX/SPEI deposits and inspect Stellar wallets — plus built-in documentation tools covering usage, architecture and the path to production",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"ramp-kit-mcp": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
18
|
+
"zod": "^3.23.0",
|
|
19
|
+
"@ramp-kit/core": "0.1.1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^22.0.0",
|
|
23
|
+
"typescript": "^5.6.0"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"author": "Armando Cruz (https://github.com/armandocodecr)",
|
|
30
|
+
"homepage": "https://github.com/armandocodecr/latam-ramp-kit#readme",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/armandocodecr/latam-ramp-kit/issues"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"mcp",
|
|
39
|
+
"model-context-protocol",
|
|
40
|
+
"stellar",
|
|
41
|
+
"onramp",
|
|
42
|
+
"latam",
|
|
43
|
+
"pix",
|
|
44
|
+
"ramp",
|
|
45
|
+
"ai-agents",
|
|
46
|
+
"usdc"
|
|
47
|
+
],
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/armandocodecr/latam-ramp-kit.git",
|
|
51
|
+
"directory": "packages/mcp"
|
|
52
|
+
},
|
|
53
|
+
"mcpName": "io.github.armandocodecr/ramp-kit",
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc -p tsconfig.json && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
57
|
+
}
|
|
58
|
+
}
|