MCP server
One MCP endpoint for every agent. Search for free, then ask for cited passages with a subscription, an API key, or x402.
quarry is one Model Context Protocol server, served over Streamable HTTP:
https://quarry.market/api/mcpIt works without an account. Searching the catalog and reading dataset details are free. Full, cited passages are paid per question: with your subscription when your quarry account or an API key is connected, or with an x402 payment from the agent's own wallet.
| Endpoint | Sign-in | Use |
|---|---|---|
/api/mcp | Optional | The endpoint to give any agent. Account tools ask the client to sign in when called |
/api/agent/mcp | Required | Same tools, signed in from the start. Also serves the older tool names search_datasets and query_dataset |
Connect a client
Any client that supports remote MCP servers over Streamable HTTP can connect. Exact setup per client, including API keys:
- Assistants: Claude, ChatGPT, Meta Muse
- Coding agents: Claude Code, Cursor, VS Code, Devin Desktop and Windsurf, Goose, OpenClaw
- Frameworks and APIs: LangChain, LlamaIndex, Vercel AI SDK, OpenAI, Anthropic, Pydantic AI, Google ADK, CrewAI, Mastra
- Platforms: Microsoft Copilot Studio, OpenAPI
Clients that use an mcpServers configuration generally accept:
{
"mcpServers": {
"quarry": { "type": "http", "url": "https://quarry.market/api/mcp" }
}
}To use your subscriptions from code that can't run a sign-in, create an
API key and send it as Authorization: Bearer qk_….
Tools
| Tool | Access | What it does |
|---|---|---|
search | Free | Searches every published dataset for sources that answer a question |
get_dataset | Free | One dataset's description, prices, response format and your access |
ask | Paid per question | The passages that answer a question, with citations |
quote_access | Account | Whether a question is included in your subscription |
get_my_access | Account | Your subscriptions and remaining quotas |
request_subscription | Account | Prepares a monthly subscription for you to confirm in Stripe Checkout |
x402_payment_guide | Free | How to pay per question with a USDC wallet |
Every tool has a title and read-only or destructive annotations. Calling an
account tool without signing in returns HTTP 401 with an OAuth challenge
(resource_metadata points to
/.well-known/oauth-protected-resource/api/mcp), which clients use to start
sign-in.
search
| Parameter | Type | Description |
|---|---|---|
query | string, required | The question or topic, in natural language (max 500 characters) |
category | string, optional | Restrict to one category (see available_categories) |
limit | integer, optional | 1–10, default 5 |
Datasets are ranked by meaning, not just keywords, across the whole catalog.
Each result includes username, slug, name, description, category, score,
price_usdc (null when the dataset only sells subscriptions), free (true
when questions cost nothing),
subscription_offer, number of documents, listed_at, content_updated_at,
listing_url and endpoint.
The top five results also carry a free snippet: at most 200 characters of the
best-matching passage, with its filename and page. It is a preview to judge
relevance, not the answer. snippet is null when the creator turned previews
off or a preview limit was reached.
ask
| Parameter | Type | Description |
|---|---|---|
username, slug | string, required | The dataset, as returned by search |
query | string, required | The question (max 2,000 characters) |
top_k | integer, optional | Passages to return, 1–20, default 5 |
request_id | string, optional | Idempotency key for subscription retries |
ask tries, in order:
- Free datasets. A dataset priced at 0 answers without any payment or account, within rate limits.
- Your subscription, when your account or API key is connected and has
quota left for this dataset. One successful call uses one question. Pass a
request_idand reuse it only to retry the identical request, so a retry is never counted twice. - An x402 payment sent with the call (see below).
- Otherwise it returns
isError: truewith the price and how to pay.
A successful answer contains results, each with content, score and a
citation: filename, page_start, page_end, heading_path,
document_updated_at and listing_url. paid_with is subscription, x402
or free. Cite the file, page and listing URL. document_updated_at is when
the file was last updated on quarry, not when the source was written; rely on
dates stated in the passage itself when timing matters.
When ask cannot answer without payment, the second text block also carries
dataset_id and, when a monthly plan exists,
next: { tool: "request_subscription", dataset_id, offer_id }.
Pay per question with x402 inside MCP
quarry follows the x402 MCP transport. When ask has
no payment, the result is:
isError: true;structuredContent: the x402PaymentRequiredobject (x402Version,resource,acceptswith scheme, network, asset, amount andpayTo);- a second text block with quarry's hints (price, monthly plan, how to connect an account).
Sign a payment for one of the accepts entries with your wallet and call ask
again with the identical arguments and the PaymentPayload in
_meta["x402/payment"]. A settled call returns the passages and the settlement
(transaction hash, payer, network) in _meta["x402/payment-response"]. A
payment that is invalid, already used or refused at settlement returns
PaymentRequired again with the reason in error, and no passages. You are
charged only when passages are returned.
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const payer = new x402Client();
registerExactEvmScheme(payer, { signer: privateKeyToAccount(process.env.AGENT_PRIVATE_KEY) });
const args = { username: "alice", slug: "sec-filings", query: "Which segment grew fastest?" };
const unpaid = await mcp.callTool({ name: "ask", arguments: args });
const payment = await payer.createPaymentPayload(unpaid.structuredContent);
const paid = await mcp.callTool({ name: "ask", arguments: args, _meta: { "x402/payment": payment } });Limits
- Requests to the endpoint: 60 per minute per IP address, or per token when you send one (OAuth or API key).
search: 20 per minute and 300 per day, per signed-in account or per IP, and a global daily ceiling for the free tier.- Free datasets: the same per-caller limit as paid questions.
- Free snippets: 30 per day for each caller and dataset, and a per-dataset cap.
- Paid questions: 30 per minute per paying wallet or subscription.
Errors inside a tool result set isError: true and include an error object
with a code and message. Check the tool result as well as the HTTP status.