httpay-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/README.md +95 -0
- package/dist/endpoints.d.ts +20 -0
- package/dist/endpoints.js +157 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +118 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# httpay-mcp
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server that exposes **121+ httpay.xyz crypto API endpoints** as tools for AI assistants.
|
|
4
|
+
|
|
5
|
+
## What is httpay.xyz?
|
|
6
|
+
|
|
7
|
+
[httpay.xyz](https://httpay.xyz) is a crypto API bazaar with 121+ endpoints covering:
|
|
8
|
+
- 🎭 **Fun** — Fortune cookies, roasts, pickup lines, rap battles
|
|
9
|
+
- 🛠️ **Tools** — Gas oracle, ENS lookup, token prices, wallet risk scores
|
|
10
|
+
- 📊 **Analysis** — Market sentiment, DeFi yields, token comparisons
|
|
11
|
+
- 🎲 **Games** — Coin flip, magic 8-ball, crypto trivia
|
|
12
|
+
- 🔮 **Predictions** — Moon predictions, vibe checks, zodiac portfolios
|
|
13
|
+
- 🏗️ **Dev** — Solidity roasts, gas golfing tips, audit bingo
|
|
14
|
+
- 🎪 **Novelty** — Crypto poems, dream interpreter, wen lambo calculator
|
|
15
|
+
- 💬 **Social** — GM/GN messages, bio generators
|
|
16
|
+
- 📦 **Proprietary** — x402 stats, ERC-8004 lookups (exclusive data)
|
|
17
|
+
- 🔗 **L2 Data** — Real-time gas costs across L2s
|
|
18
|
+
|
|
19
|
+
All endpoints are pay-per-call via the [x402 protocol](https://x402.org), costing $0.001–$0.05 per request.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g @anthropic-alfred/httpay-mcp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or use directly with npx:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx @anthropic-alfred/httpay-mcp
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
### Claude Desktop
|
|
36
|
+
|
|
37
|
+
Add to your `claude_desktop_config.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"httpay": {
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["@anthropic-alfred/httpay-mcp"],
|
|
45
|
+
"env": {
|
|
46
|
+
"HTTPAY_API_KEY": "your-api-key-if-needed"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Cursor
|
|
54
|
+
|
|
55
|
+
Add to your MCP settings:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"httpay": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["@anthropic-alfred/httpay-mcp"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Environment Variables
|
|
67
|
+
|
|
68
|
+
| Variable | Description | Default |
|
|
69
|
+
|----------|-------------|---------|
|
|
70
|
+
| `HTTPAY_BASE_URL` | Base URL for httpay API | `https://httpay.xyz` |
|
|
71
|
+
| `HTTPAY_API_KEY` | API key (if required) | — |
|
|
72
|
+
|
|
73
|
+
## Example Usage
|
|
74
|
+
|
|
75
|
+
Once connected, you can ask your AI assistant things like:
|
|
76
|
+
|
|
77
|
+
- "Get me a crypto fortune cookie"
|
|
78
|
+
- "What's the current gas price across chains?"
|
|
79
|
+
- "Roast my wallet 0x..."
|
|
80
|
+
- "Compare ETH and SOL"
|
|
81
|
+
- "What's the live price of BTC?"
|
|
82
|
+
- "Find the cheapest L2 for a swap"
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://github.com/alfredz0x/httpay-mcp
|
|
88
|
+
cd httpay-mcp
|
|
89
|
+
npm install
|
|
90
|
+
npm run dev
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All httpay.xyz endpoints, scraped from the site.
|
|
3
|
+
* Each entry defines the MCP tool metadata + how to call the API.
|
|
4
|
+
*/
|
|
5
|
+
export interface EndpointParam {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
in: "path" | "query";
|
|
10
|
+
}
|
|
11
|
+
export interface Endpoint {
|
|
12
|
+
name: string;
|
|
13
|
+
method: "GET";
|
|
14
|
+
path: string;
|
|
15
|
+
description: string;
|
|
16
|
+
price: string;
|
|
17
|
+
category: string;
|
|
18
|
+
params: EndpointParam[];
|
|
19
|
+
}
|
|
20
|
+
export declare const ENDPOINTS: Endpoint[];
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All httpay.xyz endpoints, scraped from the site.
|
|
3
|
+
* Each entry defines the MCP tool metadata + how to call the API.
|
|
4
|
+
*/
|
|
5
|
+
function ep(category, path, description, price, params = []) {
|
|
6
|
+
// Derive tool name from path: /api/roast-my-wallet/:address -> roast_my_wallet
|
|
7
|
+
const name = path
|
|
8
|
+
.replace(/^\/api\//, "")
|
|
9
|
+
.replace(/\/:[^/]+/g, "")
|
|
10
|
+
.replace(/[/-]/g, "_");
|
|
11
|
+
return { name, method: "GET", path, description, price, category, params };
|
|
12
|
+
}
|
|
13
|
+
const p = (name, description, inType = "path") => ({
|
|
14
|
+
name,
|
|
15
|
+
description,
|
|
16
|
+
required: true,
|
|
17
|
+
in: inType,
|
|
18
|
+
});
|
|
19
|
+
const qp = (name, description, required = false) => ({
|
|
20
|
+
name,
|
|
21
|
+
description,
|
|
22
|
+
required,
|
|
23
|
+
in: "query",
|
|
24
|
+
});
|
|
25
|
+
export const ENDPOINTS = [
|
|
26
|
+
// 🎭 Fun
|
|
27
|
+
ep("Fun", "/api/fortune", "Crypto fortune cookie", "$0.001"),
|
|
28
|
+
ep("Fun", "/api/pickup-line", "Crypto/web3 themed pickup lines", "$0.001"),
|
|
29
|
+
ep("Fun", "/api/roast", "Get roasted by the blockchain (no wallet needed)", "$0.001"),
|
|
30
|
+
ep("Fun", "/api/roast-my-wallet/:address", "Roast someone's on-chain activity", "$0.002", [p("address", "Wallet address to roast")]),
|
|
31
|
+
ep("Fun", "/api/explain-like-im-5/:topic", "ELI5 any crypto concept", "$0.001", [p("topic", "Crypto topic to explain")]),
|
|
32
|
+
ep("Fun", "/api/rap-battle/:token1/:token2", "Rap battle between two tokens", "$0.003", [p("token1", "First token"), p("token2", "Second token")]),
|
|
33
|
+
ep("Fun", "/api/horoscope/:sign", "Crypto-themed daily horoscope", "$0.001", [p("sign", "Zodiac sign")]),
|
|
34
|
+
ep("Fun", "/api/name-my-token", "Generate creative token names", "$0.001"),
|
|
35
|
+
ep("Fun", "/api/write-whitepaper/:idea", "Generate a parody whitepaper", "$0.005", [p("idea", "Token/project idea")]),
|
|
36
|
+
ep("Fun", "/api/crypto-excuse", "Excuse for why you lost money in crypto", "$0.001"),
|
|
37
|
+
ep("Fun", "/api/crypto-haiku", "Generate a crypto-themed haiku", "$0.001"),
|
|
38
|
+
ep("Fun", "/api/shower-thought", "Crypto shower thoughts", "$0.001"),
|
|
39
|
+
ep("Fun", "/api/token-obituary/:token", "Write an obituary for a dead/dying token", "$0.002", [p("token", "Token name/symbol")]),
|
|
40
|
+
ep("Fun", "/api/wojak-moment", "Which Wojak are you today?", "$0.001"),
|
|
41
|
+
ep("Fun", "/api/vc-pitch/:idea", "Generate a VC pitch for any dumb idea", "$0.005", [p("idea", "Your startup idea")]),
|
|
42
|
+
ep("Fun", "/api/exit-strategy", "Generate a random crypto exit strategy", "$0.001"),
|
|
43
|
+
ep("Fun", "/api/fud-generator/:token", "Generate FUD about any token", "$0.001", [p("token", "Token to FUD")]),
|
|
44
|
+
ep("Fun", "/api/apology-letter/:token", "Write an apology to a token you paper-handed", "$0.002", [p("token", "Token you sold")]),
|
|
45
|
+
ep("Fun", "/api/blockchain-pickup/:chain", "Pickup lines for specific blockchains", "$0.001", [p("chain", "Blockchain name")]),
|
|
46
|
+
ep("Fun", "/api/degen-name", "Generate your degen alter ego name", "$0.001"),
|
|
47
|
+
ep("Fun", "/api/motivational-degen", "Motivational quotes for degens", "$0.001"),
|
|
48
|
+
ep("Fun", "/api/conspiracy/:topic", "Crypto conspiracy theories", "$0.002", [p("topic", "Conspiracy topic")]),
|
|
49
|
+
ep("Fun", "/api/crypto-insult", "Get roasted by the blockchain", "$0.001"),
|
|
50
|
+
ep("Fun", "/api/breakup-text/:token", "Write a breakup text to a token", "$0.002", [p("token", "Token to break up with")]),
|
|
51
|
+
ep("Fun", "/api/tweet-generator/:topic", "Generate a crypto Twitter banger", "$0.001", [p("topic", "Tweet topic")]),
|
|
52
|
+
ep("Fun", "/api/shill-generator/:token", "Generate a shill post for any token", "$0.002", [p("token", "Token to shill")]),
|
|
53
|
+
ep("Fun", "/api/panic-button", "Press the crypto panic button", "$0.001"),
|
|
54
|
+
ep("Fun", "/api/cope-post/:loss", "Generate a cope post for your losses", "$0.002", [p("loss", "Your loss amount/description")]),
|
|
55
|
+
ep("Fun", "/api/unpopular-opinion", "Unpopular crypto opinions", "$0.001"),
|
|
56
|
+
ep("Fun", "/api/acronym-generator/:letters", "Turn any letters into a crypto acronym", "$0.001", [p("letters", "Letters to acronymize")]),
|
|
57
|
+
ep("Fun", "/api/memecoin-generator", "Generate a complete memecoin concept", "$0.002"),
|
|
58
|
+
ep("Fun", "/api/defi-jargon-generator", "Generate fake but believable DeFi jargon", "$0.001"),
|
|
59
|
+
ep("Fun", "/api/ser-or-madam", "Are you a ser or a madam in crypto?", "$0.001"),
|
|
60
|
+
ep("Fun", "/api/one-liner", "Random crypto one-liner joke", "$0.001"),
|
|
61
|
+
// 🛠️ Tools
|
|
62
|
+
ep("Tools", "/api/gas-oracle", "Current gas prices across chains (simulated)", "$0.005"),
|
|
63
|
+
ep("Tools", "/api/token-lookup/:symbol", "Token info and stats (simulated)", "$0.005", [p("symbol", "Token symbol e.g. ETH")]),
|
|
64
|
+
ep("Tools", "/api/ens-whois/:name", "ENS name availability and info", "$0.005", [p("name", "ENS name e.g. vitalik.eth")]),
|
|
65
|
+
ep("Tools", "/api/contract-explain/:address", "Explain what a contract does (simulated)", "$0.01", [p("address", "Contract address")]),
|
|
66
|
+
ep("Tools", "/api/tx-decode/:hash", "Decode and explain a transaction (simulated)", "$0.008", [p("hash", "Transaction hash")]),
|
|
67
|
+
ep("Tools", "/api/portfolio-grade/:address", "Grade a wallet's portfolio (simulated)", "$0.01", [p("address", "Wallet address")]),
|
|
68
|
+
ep("Tools", "/api/airdrop-check/:address", "Check potential airdrop eligibility (simulated)", "$0.008", [p("address", "Wallet address")]),
|
|
69
|
+
ep("Tools", "/api/whale-alert", "Recent large transactions (simulated)", "$0.005"),
|
|
70
|
+
ep("Tools", "/api/wallet-age/:address", "Estimate wallet age and activity level", "$0.005", [p("address", "Wallet address")]),
|
|
71
|
+
ep("Tools", "/api/fee-calculator/:amount/:chain", "Calculate transaction fees for a transfer", "$0.005", [p("amount", "Transfer amount"), p("chain", "Blockchain")]),
|
|
72
|
+
ep("Tools", "/api/impermanent-loss/:change", "Calculate impermanent loss for a given price change", "$0.008", [p("change", "Price change percentage")]),
|
|
73
|
+
ep("Tools", "/api/unit-converter/:amount/:unit", "Convert between crypto units (wei, gwei, ETH, etc)", "$0.005", [p("amount", "Amount to convert"), p("unit", "Source unit")]),
|
|
74
|
+
ep("Tools", "/api/address-checksum/:address", "Validate and checksum an Ethereum address", "$0.005", [p("address", "Ethereum address")]),
|
|
75
|
+
ep("Tools", "/api/epoch-converter/:timestamp", "Convert between epoch and human-readable timestamps", "$0.005", [p("timestamp", "Epoch timestamp or date string")]),
|
|
76
|
+
ep("Tools", "/api/hex-converter/:value", "Convert between hex, decimal, and other formats", "$0.005", [p("value", "Value to convert")]),
|
|
77
|
+
ep("Tools", "/api/rate-my-portfolio/:holdings", "Rate your portfolio composition", "$0.01", [p("holdings", "Comma-separated token symbols")]),
|
|
78
|
+
ep("Tools", "/api/gas-worth-it/:amount/:chain", "Is it worth paying gas for this transaction?", "$0.005", [p("amount", "Transaction amount"), p("chain", "Blockchain")]),
|
|
79
|
+
ep("Tools", "/api/wallet-risk/:address", "Wallet risk score via Base RPC (live data)", "$0.008", [p("address", "Wallet address")]),
|
|
80
|
+
ep("Tools", "/api/ens-lookup/:name", "Resolve ENS name to Ethereum address (live)", "$0.008", [p("name", "ENS name")]),
|
|
81
|
+
ep("Tools", "/api/token-price/:symbol", "Live token price in USD from CoinGecko", "$0.005", [p("symbol", "Token symbol")]),
|
|
82
|
+
ep("Tools", "/api/trending-tokens", "Top trending tokens from CoinGecko (live)", "$0.008"),
|
|
83
|
+
ep("Tools", "/api/gas-compare", "Compare real-time gas costs across 10 chains in USD", "$0.01"),
|
|
84
|
+
ep("Tools", "/api/web-scrape", "Fetch and return readable content from any URL", "$0.01", [qp("url", "URL to scrape", true)]),
|
|
85
|
+
ep("Tools", "/api/news/crypto", "Latest crypto headlines from aggregated RSS feeds", "$0.005"),
|
|
86
|
+
ep("Tools", "/api/contract-info/:address", "Get contract name, verified status, ABI summary from Basescan", "$0.01", [p("address", "Contract address")]),
|
|
87
|
+
ep("Tools", "/api/weather", "Weather forecast for any location via Open-Meteo", "$0.002", [qp("lat", "Latitude", true), qp("lon", "Longitude", true)]),
|
|
88
|
+
ep("Tools", "/api/translate", "Translate text between languages via LibreTranslate", "$0.003", [qp("text", "Text to translate", true), qp("source", "Source language code", true), qp("target", "Target language code", true)]),
|
|
89
|
+
ep("Tools", "/api/dns/:domain", "DNS lookup — returns A, AAAA, MX, TXT records", "$0.001", [p("domain", "Domain name to look up")]),
|
|
90
|
+
// 📊 Analysis
|
|
91
|
+
ep("Analysis", "/api/market-mood", "Current crypto market sentiment analysis", "$0.02"),
|
|
92
|
+
ep("Analysis", "/api/alpha-report", "Daily alpha/opportunity report", "$0.05"),
|
|
93
|
+
ep("Analysis", "/api/compare/:token1/:token2", "Compare two tokens head-to-head", "$0.02", [p("token1", "First token"), p("token2", "Second token")]),
|
|
94
|
+
ep("Analysis", "/api/risk-score/:protocol", "DeFi protocol risk assessment", "$0.02", [p("protocol", "Protocol name")]),
|
|
95
|
+
ep("Analysis", "/api/meme-potential/:token", "Rate a token's meme potential", "$0.02", [p("token", "Token name/symbol")]),
|
|
96
|
+
ep("Analysis", "/api/yield-finder", "Find the best yield opportunities (simulated)", "$0.02"),
|
|
97
|
+
ep("Analysis", "/api/narrative-tracker", "Track hot crypto narratives", "$0.02"),
|
|
98
|
+
ep("Analysis", "/api/portfolio-builder/:amount", "Build a portfolio for a given budget", "$0.05", [p("amount", "Budget in USD")]),
|
|
99
|
+
ep("Analysis", "/api/chain-compare/:chain1/:chain2", "Compare two blockchains", "$0.02", [p("chain1", "First chain"), p("chain2", "Second chain")]),
|
|
100
|
+
ep("Analysis", "/api/defi-health-check", "Overall DeFi ecosystem health check", "$0.02"),
|
|
101
|
+
ep("Analysis", "/api/nft-roast/:collection", "Roast an NFT collection", "$0.02", [p("collection", "NFT collection name")]),
|
|
102
|
+
ep("Analysis", "/api/twitter-sentiment", "Twitter/X sentiment for a query via web search", "$0.02", [qp("q", "Search query", true)]),
|
|
103
|
+
ep("Analysis", "/api/defi-yields", "Top DeFi yields across protocols on Base via DeFiLlama", "$0.01"),
|
|
104
|
+
ep("Analysis", "/api/x402-recent-txns", "Real-time x402 transaction monitor on Base", "$0.05"),
|
|
105
|
+
// 🎲 Games
|
|
106
|
+
ep("Games", "/api/coin-flip", "Flip a blockchain-verified* coin", "$0.001"),
|
|
107
|
+
ep("Games", "/api/magic-8ball/:question", "Ask the crypto magic 8-ball", "$0.001", [p("question", "Your question")]),
|
|
108
|
+
ep("Games", "/api/would-you-rather", "Crypto 'Would You Rather' scenarios", "$0.001"),
|
|
109
|
+
ep("Games", "/api/two-truths-one-lie", "Two truths and a lie about crypto", "$0.001"),
|
|
110
|
+
ep("Games", "/api/this-or-that", "Quick crypto this-or-that preference poll", "$0.001"),
|
|
111
|
+
ep("Games", "/api/rekt-leaderboard", "Hall of fame for biggest crypto disasters", "$0.003"),
|
|
112
|
+
ep("Games", "/api/degen-dice", "Roll the degen dice", "$0.001"),
|
|
113
|
+
ep("Games", "/api/crypto-trivia", "Random crypto trivia question", "$0.001"),
|
|
114
|
+
ep("Games", "/api/crypto-achievement", "Unlock a random crypto achievement", "$0.001"),
|
|
115
|
+
// 🔮 Predictions
|
|
116
|
+
ep("Predictions", "/api/when-moon/:token", "Predict when a token will moon", "$0.003", [p("token", "Token name/symbol")]),
|
|
117
|
+
ep("Predictions", "/api/vibe-check", "Get the current crypto vibe check", "$0.002"),
|
|
118
|
+
ep("Predictions", "/api/bottom-signal", "Check if we've hit the bottom", "$0.003"),
|
|
119
|
+
ep("Predictions", "/api/top-signal", "Check if we've hit the top", "$0.003"),
|
|
120
|
+
ep("Predictions", "/api/zodiac-portfolio/:sign", "Portfolio allocation based on your zodiac sign", "$0.005", [p("sign", "Zodiac sign")]),
|
|
121
|
+
ep("Predictions", "/api/chain-fortune/:chain", "Fortune for a specific blockchain", "$0.002", [p("chain", "Blockchain name")]),
|
|
122
|
+
// 🏗️ Dev
|
|
123
|
+
ep("Dev", "/api/solidity-roast/:code", "Roast a Solidity function name", "$0.005", [p("code", "Solidity function name")]),
|
|
124
|
+
ep("Dev", "/api/smart-contract-idea", "Generate a random smart contract idea", "$0.005"),
|
|
125
|
+
ep("Dev", "/api/gas-golfing-tip", "Random Solidity gas optimization tip", "$0.005"),
|
|
126
|
+
ep("Dev", "/api/audit-bingo", "Generate an audit bingo card of common vulnerabilities", "$0.005"),
|
|
127
|
+
ep("Dev", "/api/dev-excuse", "Why the smart contract isn't deployed yet", "$0.003"),
|
|
128
|
+
// 🎪 Novelty
|
|
129
|
+
ep("Novelty", "/api/rate-my-address/:address", "Rate an Ethereum address's aesthetic appeal", "$0.002", [p("address", "Ethereum address")]),
|
|
130
|
+
ep("Novelty", "/api/blockchain-poem/:topic", "Generate a blockchain-themed poem", "$0.002", [p("topic", "Poem topic")]),
|
|
131
|
+
ep("Novelty", "/api/crypto-band-name", "Generate a crypto-themed band name", "$0.001"),
|
|
132
|
+
ep("Novelty", "/api/crypto-dating-profile", "Generate a crypto bro dating profile", "$0.002"),
|
|
133
|
+
ep("Novelty", "/api/what-if/:amount/:token/:date", "What if you'd invested X in Y on date Z?", "$0.003", [p("amount", "Investment amount"), p("token", "Token symbol"), p("date", "Date (YYYY-MM-DD)")]),
|
|
134
|
+
ep("Novelty", "/api/rename-my-nft/:name", "Get a better name for your NFT", "$0.001", [p("name", "Current NFT name")]),
|
|
135
|
+
ep("Novelty", "/api/blockchain-mad-libs", "Crypto-themed mad libs story", "$0.002"),
|
|
136
|
+
ep("Novelty", "/api/crypto-baby-name", "Name your baby after crypto", "$0.001"),
|
|
137
|
+
ep("Novelty", "/api/crypto-dream-interpreter/:dream", "Interpret your dream through a crypto lens", "$0.002", [p("dream", "Describe your dream")]),
|
|
138
|
+
ep("Novelty", "/api/wen-lambo/:portfolio_size", "Calculate when you can afford a Lambo", "$0.002", [p("portfolio_size", "Portfolio size in USD")]),
|
|
139
|
+
ep("Novelty", "/api/is-it-a-scam/:name", "Is this crypto project a scam? (satirical)", "$0.002", [p("name", "Project name")]),
|
|
140
|
+
ep("Novelty", "/api/how-early/:narrative", "How early are you to a crypto narrative?", "$0.002", [p("narrative", "Crypto narrative")]),
|
|
141
|
+
ep("Novelty", "/api/protocol-name-generator", "Generate a DeFi protocol name", "$0.001"),
|
|
142
|
+
ep("Novelty", "/api/wallet-personality/:address", "Determine your wallet's personality type", "$0.003", [p("address", "Wallet address")]),
|
|
143
|
+
ep("Novelty", "/api/timelock-message/:hours", "Get a motivational message locked to a future time", "$0.002", [p("hours", "Hours to lock")]),
|
|
144
|
+
// 💬 Social
|
|
145
|
+
ep("Social", "/api/discord-bio", "Generate a Discord bio for a crypto person", "$0.001"),
|
|
146
|
+
ep("Social", "/api/twitter-bio", "Generate a Crypto Twitter bio", "$0.001"),
|
|
147
|
+
ep("Social", "/api/gm", "Get a GM (Good Morning) message", "$0.001"),
|
|
148
|
+
ep("Social", "/api/gn", "Get a GN (Good Night) message", "$0.001"),
|
|
149
|
+
// 📦 Proprietary
|
|
150
|
+
ep("Proprietary", "/api/x402-stats", "Aggregated x402 ecosystem stats — EXCLUSIVE to httpay.xyz", "$0.05"),
|
|
151
|
+
ep("Proprietary", "/api/x402-services", "Complete directory of all known x402-enabled services", "$0.01"),
|
|
152
|
+
ep("Proprietary", "/api/erc8004-lookup/:agentId", "Look up ERC-8004 registered agent details from Base registry", "$0.01", [p("agentId", "Agent ID to look up")]),
|
|
153
|
+
// 📦 L2 Data
|
|
154
|
+
ep("L2 Data", "/api/l2-costs", "Real-time gas costs across 7 L2s in USD", "$0.05"),
|
|
155
|
+
ep("L2 Data", "/api/cheapest-chain/:operation", "Find cheapest L2 for an operation", "FREE", [p("operation", "Operation type: ethTransfer/erc20Transfer/nftMint/swap")]),
|
|
156
|
+
ep("L2 Data", "/api/gas/:chain", "Gas cost for a specific chain", "FREE", [p("chain", "Chain name: base/optimism/arbitrum/ethereum/zksync/linea/polygon-zkevm")]),
|
|
157
|
+
];
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* httpay-mcp: MCP server exposing 121+ httpay.xyz crypto API endpoints as tools.
|
|
4
|
+
*
|
|
5
|
+
* Each endpoint is a paid API (via x402 protocol) that costs fractions of a cent.
|
|
6
|
+
* This MCP server lets any MCP-compatible client (Claude, Cursor, etc.) call them.
|
|
7
|
+
*
|
|
8
|
+
* Transport: stdio (standard for local MCP servers)
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* httpay-mcp: MCP server exposing 121+ httpay.xyz crypto API endpoints as tools.
|
|
4
|
+
*
|
|
5
|
+
* Each endpoint is a paid API (via x402 protocol) that costs fractions of a cent.
|
|
6
|
+
* This MCP server lets any MCP-compatible client (Claude, Cursor, etc.) call them.
|
|
7
|
+
*
|
|
8
|
+
* Transport: stdio (standard for local MCP servers)
|
|
9
|
+
*/
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { ENDPOINTS } from "./endpoints.js";
|
|
14
|
+
const BASE_URL = process.env.HTTPAY_BASE_URL || "https://httpay.xyz";
|
|
15
|
+
/**
|
|
16
|
+
* Build the URL for an endpoint, substituting path params and appending query params.
|
|
17
|
+
*/
|
|
18
|
+
function buildUrl(endpoint, args) {
|
|
19
|
+
let path = endpoint.path;
|
|
20
|
+
// Substitute path params
|
|
21
|
+
for (const param of endpoint.params.filter((p) => p.in === "path")) {
|
|
22
|
+
path = path.replace(`:${param.name}`, encodeURIComponent(args[param.name] || ""));
|
|
23
|
+
}
|
|
24
|
+
// Build query string
|
|
25
|
+
const queryParams = endpoint.params.filter((p) => p.in === "query");
|
|
26
|
+
const queryParts = [];
|
|
27
|
+
for (const param of queryParams) {
|
|
28
|
+
if (args[param.name]) {
|
|
29
|
+
queryParts.push(`${param.name}=${encodeURIComponent(args[param.name])}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const url = `${BASE_URL}${path}`;
|
|
33
|
+
return queryParts.length > 0 ? `${url}?${queryParts.join("&")}` : url;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Call an httpay.xyz endpoint. These are x402-enabled — the server handles
|
|
37
|
+
* payment negotiation. For now we just make a simple GET request.
|
|
38
|
+
* Users can set HTTPAY_API_KEY env var if the server supports it.
|
|
39
|
+
*/
|
|
40
|
+
async function callEndpoint(endpoint, args) {
|
|
41
|
+
const url = buildUrl(endpoint, args);
|
|
42
|
+
const headers = {
|
|
43
|
+
Accept: "application/json",
|
|
44
|
+
"User-Agent": "httpay-mcp/0.1.0",
|
|
45
|
+
};
|
|
46
|
+
const apiKey = process.env.HTTPAY_API_KEY;
|
|
47
|
+
if (apiKey) {
|
|
48
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(url, { headers });
|
|
52
|
+
if (response.status === 402) {
|
|
53
|
+
// x402 payment required — return the payment details so the client can handle it
|
|
54
|
+
const paymentInfo = await response.text();
|
|
55
|
+
return JSON.stringify({
|
|
56
|
+
status: 402,
|
|
57
|
+
message: "Payment required (x402). This endpoint costs " + endpoint.price,
|
|
58
|
+
endpoint: url,
|
|
59
|
+
paymentInfo: paymentInfo.substring(0, 2000),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
return JSON.stringify({
|
|
64
|
+
error: true,
|
|
65
|
+
status: response.status,
|
|
66
|
+
message: await response.text().catch(() => response.statusText),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const contentType = response.headers.get("content-type") || "";
|
|
70
|
+
if (contentType.includes("application/json")) {
|
|
71
|
+
const data = await response.json();
|
|
72
|
+
return JSON.stringify(data, null, 2);
|
|
73
|
+
}
|
|
74
|
+
return await response.text();
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return JSON.stringify({
|
|
78
|
+
error: true,
|
|
79
|
+
message: error instanceof Error ? error.message : String(error),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Create the MCP server
|
|
84
|
+
const server = new McpServer({
|
|
85
|
+
name: "httpay",
|
|
86
|
+
version: "0.1.0",
|
|
87
|
+
});
|
|
88
|
+
// Register every endpoint as an MCP tool
|
|
89
|
+
for (const endpoint of ENDPOINTS) {
|
|
90
|
+
// Build Zod schema from params
|
|
91
|
+
const schemaShape = {};
|
|
92
|
+
for (const param of endpoint.params) {
|
|
93
|
+
const field = z.string().describe(param.description);
|
|
94
|
+
schemaShape[param.name] = param.required ? field : field.optional();
|
|
95
|
+
}
|
|
96
|
+
const description = [
|
|
97
|
+
endpoint.description,
|
|
98
|
+
`Category: ${endpoint.category}`,
|
|
99
|
+
`Price: ${endpoint.price}`,
|
|
100
|
+
`Endpoint: ${endpoint.method} ${endpoint.path}`,
|
|
101
|
+
].join("\n");
|
|
102
|
+
server.tool(endpoint.name, description, schemaShape, async (args) => {
|
|
103
|
+
const result = await callEndpoint(endpoint, args);
|
|
104
|
+
return {
|
|
105
|
+
content: [{ type: "text", text: result }],
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Start the server
|
|
110
|
+
async function main() {
|
|
111
|
+
const transport = new StdioServerTransport();
|
|
112
|
+
await server.connect(transport);
|
|
113
|
+
console.error(`httpay MCP server started with ${ENDPOINTS.length} tools`);
|
|
114
|
+
}
|
|
115
|
+
main().catch((error) => {
|
|
116
|
+
console.error("Fatal error:", error);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "httpay-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server exposing 121+ httpay.xyz crypto API endpoints as tools",
|
|
5
|
+
"author": "Alfred Zhang",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"httpay-mcp": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"dev": "tsx src/index.ts"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
23
|
+
"zod": "^3.25.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"typescript": "^5.7.0",
|
|
27
|
+
"tsx": "^4.0.0",
|
|
28
|
+
"@types/node": "^22.0.0"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"mcp",
|
|
32
|
+
"httpay",
|
|
33
|
+
"crypto",
|
|
34
|
+
"x402",
|
|
35
|
+
"api",
|
|
36
|
+
"model-context-protocol"
|
|
37
|
+
],
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/alfredz0x/httpay-mcp"
|
|
41
|
+
}
|
|
42
|
+
}
|