Why the Claude Agent SDK + Tabstack
Adding web access to an agent usually means writing your own fetch and parse code. @tabstack/claude-agent replaces that with a hosted API registered as in-process Claude Agent SDK tools: schema-enforced output, server-side rendering of JS-heavy pages, and one key for extraction, research, generation, and automation. One call builds the tools 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 registers the Tabstack tools as in-process Claude Agent SDK tools, 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 does not wait on a person. 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.