Tabstack for the Claude Agent SDK
Give your Claude Agent SDK agents reliable web access with @tabstack/claude-agent: extraction, research, generation, and browser automation as an in-process MCP server.
@tabstack/claude-agent gives your
Claude Agent SDK agents reliable web access:
schema-enforced extraction, multi-source research, AI transformation, and browser automation, exposed
as an in-process MCP server and backed by the official
@tabstack/sdk.
Unlike the other integrations, which hand you tool objects, this one hands you a ready-built MCP
server to drop into a query() call.
Install
Section titled “Install”npm install @tabstack/claude-agent @anthropic-ai/claude-agent-sdk zodpnpm add @tabstack/claude-agent @anthropic-ai/claude-agent-sdk zodyarn add @tabstack/claude-agent @anthropic-ai/claude-agent-sdk zod@anthropic-ai/claude-agent-sdk (v0.3 or later) and zod are peer dependencies.
The agent loop runs on Claude, so ANTHROPIC_API_KEY must be set alongside your Tabstack key.
Create and Setup Your API Key
Before you can start using Tabstack API, you’ll need to create an API key and set it up in your environment.
1. Create Your API Key
- Visit the Tabstack Console
- Sign in to your account (or create one if you haven’t already)
- Navigate to the API Keys section and click the “Manage API Keys”
- Once you are on the API Keys page, Click “Create New API Key”
- Give your key a descriptive name (e.g., “Development”, “Production”) and click the “Create API Key”
- Copy the generated API key and store it securely
2. Set Up Environment Variable
For security and convenience, we recommend storing your API key as an environment variable rather than hardcoding it in your scripts.
macOS/Linux
# Add to your shell profile (~/.bashrc, ~/.zshrc, or ~/.bash_profile)export TABSTACK_API_KEY="your_api_key_here"
# Or set it temporarily for the current sessionexport TABSTACK_API_KEY="your_api_key_here"
# Reload your shell or run:source ~/.bashrc # or ~/.zshrcWindows (Command Prompt)
# Set temporarily for current sessionset TABSTACK_API_KEY=your_api_key_here
# Set permanently (requires restart)setx TABSTACK_API_KEY "your_api_key_here"Windows (PowerShell)
# Set temporarily for current session$env:TABSTACK_API_KEY = "your_api_key_here"
# Set permanently for current user[Environment]::SetEnvironmentVariable("TABSTACK_API_KEY", "your_api_key_here", "User")3. Verify Your Setup
Test that your environment variable is set correctly:
macOS/Linux/Windows (Git Bash):
echo $TABSTACK_API_KEYWindows (Command Prompt):
echo %TABSTACK_API_KEY%Windows (PowerShell):
echo $env:TABSTACK_API_KEYYou should see your API key printed in the terminal.
Quickstart
Section titled “Quickstart”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 { tabstackAllowedTools, tabstackMcpServerName, tabstackServer,} 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.
The tools
Section titled “The tools”| Tool | 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 | Synthesize a cited answer 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 one under its fully qualified MCP name, mcp__tabstack__<tool_name>. That is what
tabstackAllowedTools contains, so it is equivalent to allowing mcp__tabstack__*.
Tool inputs
Section titled “Tool inputs”The model fills these in, but it helps to know the shapes:
extract_structured_data:url,json_schema_json(a JSON-encoded JSON Schema string).extract_page_content:url.research_question:query.generate_structured_data:url,instructions,json_schema_json.automate_browser_task:task, plus optionalurl,guardrails,data,country,max_iterations,max_validation_attempts.
Each tool’s schema is registered with the SDK, so Claude’s arguments are validated before the tool
body runs. See Schema design for writing json_schema_json that extracts
reliably.
Optional inputs
Section titled “Optional inputs”The model can pass these for finer control; they are sent to Tabstack only when present.
extract_structured_data,extract_page_content,generate_structured_data:effort:"min","standard", or"max". Use"max"for JS-heavy pages. See Effort levels.nocache: bypass the cache.country: ISO 3166-1 alpha-2 code for geotargeting.
research_question:mode("fast"or"balanced"),nocache.automate_browser_task:guardrails(constraints on what the agent may do),data(context for form filling),country,max_iterations,max_validation_attempts.
Configuration
Section titled “Configuration”For a custom API key or base URL, or to reuse one client, build the server explicitly:
import { query } from "@anthropic-ai/claude-agent-sdk";import { createTabstackClaudeAgentServer, tabstackAllowedTools, tabstackMcpServerName,} from "@tabstack/claude-agent";
const server = createTabstackClaudeAgentServer({ apiKey: process.env.MY_KEY });// or pass an SDK client you already have: createTabstackClaudeAgentServer({ client })
await query({ prompt: "...", options: { mcpServers: { [tabstackMcpServerName]: server }, allowedTools: tabstackAllowedTools, },});To assemble the server yourself, createTabstackClaudeAgentTools(config) returns the raw tool array
for your own createSdkMcpServer({ name, version, tools }) call.
Error handling
Section titled “Error handling”When a tool call fails, the handler normalizes the failure to a TabstackToolError (a clean message
plus an HTTP status for API errors) and returns it as an MCP error result (isError: true). Claude
reads a useful message and can retry or explain, rather than seeing a raw exception.