quarryDocs

Frameworks and SDKs

Load quarry's tools into LangChain, LlamaIndex, the OpenAI Agents SDK, Pydantic AI, ADK, CrewAI, the AI SDK, Mastra, or model APIs.

Every framework on this page loads quarry's tools from one MCP server:

https://quarry.market/api/mcp

Your agent gets search (free, across every dataset), get_dataset, ask, and the account tools described in MCP server. The examples send an API key so the agent can use your subscriptions. They read it from the QUARRY_API_KEY environment variable:

export QUARRY_API_KEY=qk_...

Without a key, remove the QUARRY_API_KEY line and the header or auth argument: the agent can still search quarry and read free datasets. To pay per question from a wallet instead, see Paying with x402.

Each example also needs its model provider's key: ANTHROPIC_API_KEY for the Claude models used here, OPENAI_API_KEY for the OpenAI examples and CrewAI, GOOGLE_API_KEY for Google ADK, and AI_GATEWAY_API_KEY for the Vercel AI SDK. The TypeScript examples use top-level await, so run them as ES modules, for example with npx tsx agent.mts.

Python

LangChain and LangGraph

LangChain's MCP support ships in the mcp extra of langchain 1.4 and later. It's still in beta.

pip install "langchain[mcp,anthropic]>=1.4"
import asyncio
import os

from fastmcp.client import Client
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]


async def main():
    # auth= is sent as "Authorization: Bearer <key>".
    quarry = Client("https://quarry.market/api/mcp", auth=QUARRY_API_KEY)
    async with MCPAdapter(quarry) as adapter:
        tools = await adapter.list_tools()
        agent = create_agent("anthropic:claude-sonnet-5", tools)
        result = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "Find sources on chip lead times and cite them."}]}
        )
        print(result["messages"][-1].content)


asyncio.run(main())

Still on the older langchain-mcp-adapters package? It connects the same way:

from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient({
    "quarry": {
        "transport": "http",
        "url": "https://quarry.market/api/mcp",
        "headers": {"Authorization": f"Bearer {QUARRY_API_KEY}"},
    }
})
tools = await client.get_tools()  # inside an async function, as above

LlamaIndex

pip install llama-index-tools-mcp llama-index-llms-anthropic
import asyncio
import os

from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.anthropic import Anthropic
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]


async def main():
    quarry = BasicMCPClient(
        "https://quarry.market/api/mcp",
        headers={"Authorization": f"Bearer {QUARRY_API_KEY}"},
    )
    tools = await McpToolSpec(client=quarry).to_tool_list_async()
    agent = FunctionAgent(
        tools=tools,
        llm=Anthropic(model="claude-sonnet-5"),
        system_prompt="Answer with quarry's sources and cite them.",
    )
    print(await agent.run("Find sources on chip lead times and cite them."))


asyncio.run(main())

OpenAI Agents SDK

pip install openai-agents
import asyncio
import os

from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]


async def main():
    async with MCPServerStreamableHttp(
        name="quarry",
        params={
            "url": "https://quarry.market/api/mcp",
            "headers": {"Authorization": f"Bearer {QUARRY_API_KEY}"},
        },
        cache_tools_list=True,
        # The default is 5 seconds; a search can take longer.
        client_session_timeout_seconds=30,
    ) as quarry:
        agent = Agent(
            name="Researcher",
            instructions="Answer with quarry's sources and cite them.",
            mcp_servers=[quarry],
        )
        result = await Runner.run(agent, "Find sources on chip lead times and cite them.")
        print(result.final_output)


asyncio.run(main())

Pydantic AI

pip install "pydantic-ai-slim[mcp,anthropic]"
import os

from pydantic_ai import Agent
from pydantic_ai.mcp import MCPToolset

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]

quarry = MCPToolset(
    "https://quarry.market/api/mcp",
    headers={"Authorization": f"Bearer {QUARRY_API_KEY}"},
)
agent = Agent("anthropic:claude-sonnet-5", toolsets=[quarry])

result = agent.run_sync("Find sources on chip lead times and cite them.")
print(result.output)

MCPToolset replaced MCPServerStreamableHTTP in Pydantic AI 2.

Google ADK

pip install google-adk mcp
import os

from google.adk.agents import Agent
from google.adk.tools.mcp_tool import McpToolset, StreamableHTTPConnectionParams

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]

root_agent = Agent(
    name="researcher",
    model="gemini-flash-latest",
    instruction="Answer with quarry's sources and cite them.",
    tools=[
        McpToolset(
            connection_params=StreamableHTTPConnectionParams(
                url="https://quarry.market/api/mcp",
                headers={"Authorization": f"Bearer {QUARRY_API_KEY}"},
            )
        )
    ],
)

ADK loads root_agent from your agent's agent.py. Start it with adk run or adk web.

CrewAI

pip install crewai mcp
import os

from crewai import Agent
from crewai.mcp import MCPServerHTTP

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]

researcher = Agent(
    role="Researcher",
    goal="Answer questions with quarry's sources, cited",
    backstory="You search quarry and cite the passages you use.",
    mcps=[
        MCPServerHTTP(
            url="https://quarry.market/api/mcp",
            headers={"Authorization": f"Bearer {QUARRY_API_KEY}"},
            streamable=True,
        )
    ],
)
print(researcher.kickoff("Find sources on chip lead times and cite them.").raw)

CrewAI uses OpenAI by default; pass llm= to the agent to change the model.

TypeScript

Vercel AI SDK

For AI SDK 7. The model string goes through the Vercel AI Gateway; use a provider package such as @ai-sdk/anthropic to call a provider directly.

npm install ai @ai-sdk/mcp
import { createMCPClient } from "@ai-sdk/mcp";
import { generateText, isStepCount } from "ai";

const quarry = await createMCPClient({
  transport: {
    type: "http",
    url: "https://quarry.market/api/mcp",
    headers: { Authorization: `Bearer ${process.env.QUARRY_API_KEY}` },
  },
});

try {
  const { text } = await generateText({
    model: "anthropic/claude-sonnet-5",
    tools: await quarry.tools(),
    stopWhen: isStepCount(5),
    prompt: "Find sources on chip lead times and cite them.",
  });
  console.log(text);
} finally {
  await quarry.close();
}

The AI SDK doesn't follow redirects to an MCP server, so use the address exactly as written: no www, no trailing slash. With streamText, close the client in onEnd instead.

Mastra

npm install @mastra/core @mastra/mcp
import { Agent } from "@mastra/core/agent";
import { MCPClient } from "@mastra/mcp";

const quarry = new MCPClient({
  id: "quarry",
  servers: {
    quarry: {
      url: new URL("https://quarry.market/api/mcp"),
      requestInit: { headers: { Authorization: `Bearer ${process.env.QUARRY_API_KEY}` } },
    },
  },
});

export const researcher = new Agent({
  id: "researcher",
  name: "Researcher",
  instructions: "Answer with quarry's sources and cite them.",
  model: "anthropic/claude-sonnet-5",
  tools: await quarry.listTools(),
});

const result = await researcher.generate("Find sources on chip lead times and cite them.");
console.log(result.text);
await quarry.disconnect();

Mastra prefixes each tool with the server name: quarry_search, quarry_ask, and so on.

Model APIs

OpenAI and Anthropic can call quarry for you during a request, from their own servers. Two consequences:

  • Always send an API key, even for free datasets. Without one, quarry limits requests by where they come from, and these providers send requests for many customers from the same addresses.
  • These calls can't pay per question from your wallet. Paid datasets need a subscription.

OpenAI Responses API

import os

from openai import OpenAI

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]

client = OpenAI()  # reads OPENAI_API_KEY
response = client.responses.create(
    model="gpt-6-astra",
    input="Find sources on chip lead times and cite them.",
    tools=[
        {
            "type": "mcp",
            "server_label": "quarry",
            "server_url": "https://quarry.market/api/mcp",
            "headers": {"Authorization": f"Bearer {QUARRY_API_KEY}"},
            "require_approval": "never",
        }
    ],
)
print(response.output_text)

By default, OpenAI asks for your approval before each call to quarry; "require_approval": "never" skips that step.

Anthropic Messages API

import os

import anthropic

QUARRY_API_KEY = os.environ["QUARRY_API_KEY"]

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY
response = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=2048,
    messages=[{"role": "user", "content": "Find sources on chip lead times and cite them."}],
    mcp_servers=[
        {
            "type": "url",
            "url": "https://quarry.market/api/mcp",
            "name": "quarry",
            # Anthropic adds "Bearer " itself: pass the bare key.
            "authorization_token": QUARRY_API_KEY,
        }
    ],
    tools=[{"type": "mcp_toolset", "mcp_server_name": "quarry"}],
    betas=["mcp-client-2025-11-20"],
)
print("".join(block.text for block in response.content if block.type == "text"))

Every server in mcp_servers needs a matching mcp_toolset entry in tools.

On this page

View as Markdown