Sign In

@clervo/mcp

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@clervo/mcp - npm Package Compare versions

Comparing version
0.1.0
to
0.2.0
+1
-1
package.json
{
"name": "@clervo/mcp",
"version": "0.1.0",
"version": "0.2.0",
"description": "Clervo x402 Gateway MCP server — 23 AI models, 8 free. One wallet, pay per call in USDC.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -7,5 +7,7 @@ /**

* Tools exposed:
* clervo_chat — call any model (free or paid)
* clervo_models — list available models with pricing
* clervo_status — check operation status / receipt
* clervo_chat — call any model (free or paid)
* clervo_models — list available models with pricing
* clervo_search — web search (free, no API key)
* clervo_scrape — URL to markdown (free, no API key)
* clervo_status — check operation status / receipt
*/

@@ -21,3 +23,3 @@

name: 'clervo_chat',
description: 'Call an AI model through Clervo x402 Gateway. 8 free models available without payment. Use model "groq/llama-3.1-8b-instant" for fastest free response (170ms).',
description: 'Call an AI model through Clervo x402 Gateway. 13 free models available without payment. Use "groq/llama-3.1-8b-instant" for fastest (170ms) or "groq/llama-3.3-70b" for best free quality.',
inputSchema: {

@@ -29,3 +31,3 @@ type: 'object',

type: 'string',
description: 'Model ID. Free: groq/llama-3.1-8b-instant, groq/llama-3.3-70b, sambanova/deepseek-v3.2, sambanova/llama-3.3-70b, hcn/qwen3.6-35b, hcn/step-3.7-flash, hcn/deepseek-v4-pro, hcn/auto. Paid: tongkhokr/claude-haiku-4.5, tongkhokr/claude-sonnet-5, tongkhokr/claude-opus-5, quickai/gpt-5.4-mini, quickai/gpt-5.5, quickai/gpt-5.6-sol (and more).',
description: 'Model ID. Free: groq/llama-3.1-8b-instant, groq/llama-3.3-70b, groq/qwen3.6-27b, groq/gpt-oss-120b, sambanova/llama-3.3-70b, nvidia/nemotron-ultra-550b, nvidia/deepseek-v4-flash. Paid: tongkhokr/claude-sonnet-5, tongkhokr/claude-opus-5, quickai/gpt-5.4-mini, quickai/gpt-5.5.',
},

@@ -39,4 +41,27 @@ message: { type: 'string', description: 'The user message to send.' },

{
name: 'clervo_search',
description: 'Search the web. Returns structured results with titles, URLs, and snippets. Free, no API key needed. Use for finding current information, documentation, or research.',
inputSchema: {
type: 'object',
required: ['query'],
properties: {
query: { type: 'string', description: 'Search query (max 500 chars).' },
max_results: { type: 'number', description: 'Number of results (1-10, default 5).' },
},
},
},
{
name: 'clervo_scrape',
description: 'Convert any URL to clean markdown. Free, no API key needed. Use for reading web pages, documentation, or extracting content from URLs.',
inputSchema: {
type: 'object',
required: ['url'],
properties: {
url: { type: 'string', description: 'The URL to scrape and convert to markdown.' },
},
},
},
{
name: 'clervo_models',
description: 'List all available Clervo models with pricing. Shows free models (no payment needed) and paid models (x402 USDC). 23 models across Groq, SambaNova, HCN, Claude, and GPT families.',
description: 'List all available Clervo models with pricing. Shows free models (no payment needed) and paid models (x402 USDC on Base). 26 models across Groq, SambaNova, Nvidia, Claude, and GPT families.',
inputSchema: { type: 'object', properties: {} },

@@ -65,6 +90,3 @@ },

method: 'POST',
headers: {
'content-type': 'application/json',
'idempotency-key': crypto.randomUUID(),
},
headers: { 'content-type': 'application/json', 'idempotency-key': crypto.randomUUID() },
body: JSON.stringify({ model, messages, max_completion_tokens: max_tokens || 1024 }),

@@ -74,3 +96,3 @@ });

if (r.status === 402) {
return { content: [{ type: 'text', text: `Payment required for model "${model}". This is a paid model — use a free model like "groq/llama-3.1-8b-instant" or fund a wallet for paid calls.\n\nFree models: groq/llama-3.1-8b-instant, groq/llama-3.3-70b, sambanova/deepseek-v3.2, hcn/qwen3.6-35b` }] };
return { content: [{ type: 'text', text: `Payment required for "${model}". Use a free model instead:\n- groq/llama-3.1-8b-instant (fastest, 170ms)\n- groq/llama-3.3-70b (best free quality)\n- nvidia/nemotron-ultra-550b (largest free model)` }] };
}

@@ -91,2 +113,36 @@

async function handleSearch({ query, max_results }) {
const r = await fetch(`${API}/v1/search`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ query, max_results: max_results || 5 }),
});
const j = await r.json();
if (r.status !== 200) {
return { content: [{ type: 'text', text: `Search error: ${j.error?.message || 'unavailable'}` }], isError: true };
}
let text = `Search results for "${j.query}":\n\n`;
(j.results || []).forEach((result, i) => {
text += `${i + 1}. ${result.title}\n ${result.url}\n ${result.snippet}\n\n`;
});
return { content: [{ type: 'text', text: text.trim() }] };
}
async function handleScrape({ url }) {
const r = await fetch(`${API}/v1/scrape`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ url }),
});
const j = await r.json();
if (r.status !== 200) {
return { content: [{ type: 'text', text: `Scrape error: ${j.error?.message || j.message || 'failed'}` }], isError: true };
}
return { content: [{ type: 'text', text: j.content || 'No content returned.' }] };
}
async function handleModels() {

@@ -99,6 +155,6 @@ const r = await fetch(`${API}/v1/models`);

let text = `Clervo x402 Gateway — ${j.data.length} models\n\n`;
let text = `Clervo x402 Gateway — ${j.data.length} models | Base mainnet USDC\n\n`;
text += `FREE (no wallet needed, just call):\n`;
free.forEach(m => { text += ` ${m.id} — ${m.description || m.name}\n`; });
text += `\nPAID (x402 USDC per request, 10-20% cheaper than BlockRun):\n`;
text += `\nPAID (x402 USDC on Base, 20% cheaper than BlockRun):\n`;
paid.forEach(m => {

@@ -108,2 +164,3 @@ const price = m.paid_pricing?.amount || m.pricing?.amount || '?';

});
text += `\nServices: search (POST /v1/search), scrape (POST /v1/scrape) — both FREE`;
text += `\nQuickstart: ${API}/quickstart.md`;

@@ -136,3 +193,3 @@ return { content: [{ type: 'text', text }] };

capabilities: { tools: {} },
serverInfo: { name: 'clervo', version: '0.1.0' },
serverInfo: { name: 'clervo', version: '0.2.0' },
}});

@@ -148,2 +205,4 @@ } else if (msg.method === 'notifications/initialized') {

if (name === 'clervo_chat') result = await handleChat(args);
else if (name === 'clervo_search') result = await handleSearch(args);
else if (name === 'clervo_scrape') result = await handleScrape(args);
else if (name === 'clervo_models') result = await handleModels();

@@ -162,5 +221,4 @@ else if (name === 'clervo_status') result = await handleStatus(args);

rl.on('close', () => {
// Give pending async operations time to complete
setTimeout(() => process.exit(0), 100);
});
}