Why the Claude Agent SDK + Tabstack
Wiring web access into an agent usually means hand-rolled fetches, HTML parsing, and prompt gymnastics to coax structured data out of messy text. @tabstack/claude-agent replaces that with a hosted API exposed as an in-process MCP server: schema-enforced output, server-side rendering of JS-heavy pages, and one key for extraction, research, generation, and automation. One call builds a ready-to-use server for query(), with no separate process to run.
Quickstart
Install the adapter and set your keys:
npm install @tabstack/claude-agent @anthropic-ai/claude-agent-sdk zod
export TABSTACK_API_KEY="your-tabstack-key"
export ANTHROPIC_API_KEY="your-anthropic-key"@anthropic-ai/claude-agent-sdk and zod are peer dependencies. The Claude Agent SDK requires Zod 4, so this package's zod peer is ^4.0.0.
tabstackServer is a ready-built in-process MCP server, and tabstackAllowedTools pre-approves every Tabstack tool. Wire both into a query() call:
import { query } from "@anthropic-ai/claude-agent-sdk";
import { tabstackServer, tabstackAllowedTools, tabstackMcpServerName } from "@tabstack/claude-agent";
for await (const message of query({
prompt: "What are Vercel's current pricing plans, with sources?",
options: {
mcpServers: { [tabstackMcpServerName]: tabstackServer },
allowedTools: tabstackAllowedTools,
},
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}The server resolves TABSTACK_API_KEY lazily on first tool call, so importing the package never requires a key.
For a custom key, base URL, or a shared client, build the server explicitly:
import { createTabstackClaudeAgentServer } from "@tabstack/claude-agent";
const server = createTabstackClaudeAgentServer({ apiKey: process.env.MY_KEY });
// or pass an SDK client you already have: createTabstackClaudeAgentServer({ client })Assembling the server yourself? createTabstackClaudeAgentTools(config) returns the raw tool array to pass to your own createSdkMcpServer({ name, version, tools }).
The tools
| Tool name | What it does |
|---|---|
extract_structured_data | Pull specific fields from a URL into a JSON shape you define. |
extract_page_content | Fetch a page as clean markdown. |
research_question | Synthesized answer with cited sources across multiple pages. |
generate_structured_data | Fetch a page, then AI-transform it into derived or reshaped JSON. |
automate_browser_task | Run a multi-step, natural-language browser task. |
Claude sees each tool under its fully qualified MCP name, mcp__tabstack__<tool_name>. The names stay in lockstep with the @tabstack/langchain, @tabstack/ai, @tabstack/eve, and Python langchain-tabstack packages.
Good to know
automate_browser_taskruns non-interactively. It does not pause for human-in-the-loop form input, so it never blocks. It returns the final answer plus the data it extracted and the pages it visited.- Failed calls normalize to a
TabstackToolErrorand return as an MCP error result (isError: true), so Claude reads a useful message and can retry or explain rather than seeing a raw exception. - Each tool's input schema is the core Zod schema's raw shape, so the Agent SDK validates the model's arguments before your handler runs.
Common use cases
- Give a Claude agent cited, multi-source research without running a browser.
- Pull structured fields off a page into a shape you define.
- Add web access to an existing
query()call with two imports. - Keep tool names consistent across your TypeScript and Python agents.