---
title: Changelog | Tabstack
description: All notable changes to the Tabstack SDK and API, newest first.
---

### **Packages:**

- [`@tabstack/sdk`](https://www.npmjs.com/package/@tabstack/sdk) (TypeScript)
- [`tabstack`](https://pypi.org/project/tabstack/) (Python)

---

Subscribe to the [RSS feed](/changelog.xml)

**Latest breaking change: [2.0.0](#200--2026-01-16).&#x20;**&#x42;reaking: deprecated MCP server tool schemes removed. Code mode is the only supported scheme. Added: intent parameter on the MCP execute tool; SDK package renamed to @tabstack/sdk. [Review the migration below](#200--2026-01-16) before upgrading across it.

---

## 2.6.1 - 2026-05-05

AddedDocs

**Endpoint-specific timeouts.** `/automate` and `/research` now apply a 600 s (10 min) default timeout at the SDK level. This overrides any shorter global timeout set on the client. Long-running automations and research tasks will no longer be cut off.

**`task:trace_context` event.** The `/automate` stream now emits a `task:trace_context` event as the first event after task acceptance (before `task:started`). Its payload carries `traceId`, a W3C 32-character hex trace ID you can use to deep-link into Cloud Trace, Cloud Logging, or your own distributed tracing UI for the run.

```
for await (const event of stream) {
  if (event.event === "task:trace_context") {
    console.log("Trace ID:", event.data.traceId);
  }
}
```

**Custom headers via environment variable.** Set `TABSTACK_CUSTOM_HEADERS` to a newline-separated list of `Key: value` pairs to inject default headers into every request without code changes.

```
TABSTACK_CUSTOM_HEADERS="X-My-Header: value
X-Another: value2"
```

**Scroll browser action.** Automation agents can now scroll pages during task execution. Appears as an `agent:action` event with `action: "scroll"`.

- `extract.json` null behavior clarified: if a field in your schema cannot be populated from the page, the response returns `null` for that field. The call does not fail.
- Quickstart standardized to `TABSTACK_API_KEY` as the environment variable name.

---

## 2.6.0 - 2026-04-24

Changed

**`AutomateEvent` is now a fully typed discriminated union.** `complete`, `error`, and `done` are first-class members of the union. Handle them with explicit `case` branches. The prior pattern of catching them in a `default` branch with manual casts is no longer necessary and should be removed.

```
for await (const event of stream) {
  switch (event.event) {
    case "task:completed":
      console.log(event.data.finalAnswer);
      break;
    case "complete":
      console.log(`Done in ${event.data.stats.durationMs}ms`);
      if (!event.data.success) console.error(event.data.error?.message);
      break;
    case "done":
      break;
    case "error":
      console.error(event.data.error.message);
      break;
  }
}
```

**`complete` event data fields:**

- `finalAnswer: string | null` - the agent’s result
- `stats: { durationMs, iterations, actions, startTime, endTime }` - run metrics
- `success: boolean`
- `error?: { code, message }` - present when the agent aborted

**`error` event data fields:**

- `error: { code: string, message: string, timestamp: string }` - `timestamp` is ISO-8601
- `success: false`

[]()

2.5.0 - 2026-04-22 · Fixed

**`/research` default mode is `fast`.** The SDK documentation incorrectly listed `balanced` as the default. The actual default is `fast`. If you need balanced mode, pass `mode: 'balanced'` explicitly.

[]()

2.4.0 - 2026-04-09 · Added

**Interactive mode.** `client.agent.automateInput(requestId, { fields })` added. When an automation task emits an `interactive:form_data:request` event and needs human-supplied field values to continue, call this method with the `requestId` from the event and the field values. Pass `cancelled: true` to abort the interaction.

```
for await (const event of stream) {
  if (event.event === "interactive:form_data:request") {
    const data = event.data as { requestId: string };
    const response = await client.agent.automateInput(data.requestId, {
      fields: [{ ref: "email", value: "user@example.com" }],
    });
  }
}
```

See the [interactive mode guide](/guides/interactive-mode/index.md) for the full pattern.

**`geo_target` added to `extract.json`, `extract.markdown`, and `generate.json`.** Pass an ISO 3166-1 alpha-2 country code to proxy the request through a matching geo. (Was already available on `/automate` since 2.1.0.)

```
const data = await client.extract.json({
  url: "https://example.com/pricing",
  json_schema: { type: "object", properties: { price: { type: "string" } } },
  geo_target: { country: "GB" },
});
```

[]()

2.3.0 - 2026-03-12 · Added

**`effort` parameter** added to `extract.json`, `extract.markdown`, and `generate.json`. Controls the speed vs. capability tradeoff:

| Value        | Time    | Use when                         |
| ------------ | ------- | -------------------------------- |
| `'min'`      | 1-5 s   | Static pages, fastest possible   |
| `'standard'` | 3-15 s  | Default, balanced reliability    |
| `'max'`      | 15-60 s | JS-heavy SPAs, complex rendering |

```
const data = await client.extract.json({
  url: "https://example.com",
  json_schema: { type: "object", properties: { title: { type: "string" } } },
  effort: "max", // full browser rendering
});
```

[]()

2.2.0 - 2026-02-11 · FixedChanged

- Memory leak with abort signals in the HTTP client resolved. Relevant if you cancel in-flight requests.
- Abort listener was removed too early in some edge cases. Fixed.
- MCP server package renamed. Update your MCP server configuration if you use the Tabstack MCP server directly.

[]()

2.1.0 - 2026-01-30 · Added

**`/research` endpoint.** `client.agent.research({ query, mode?, fetch_timeout?, nocache? })` for multi-source autonomous web research with cited answers. Always streams `ResearchEvent` via SSE.

```
const stream = await client.agent.research({
  query: "What are the top TypeScript ORM libraries in 2025?",
  mode: "fast", // 'fast' (default) | 'balanced'
});


for await (const event of stream) {
  if (event.event === "complete") {
    console.log(event.data.report);
    console.log(`Sources: ${event.data.metadata.totalPagesAnalyzed}`);
  }
  if (event.event === "done") break;
}
```

---

## 2.0.0 - 2026-01-16

BreakingAdded

**Breaking changes to the MCP server.** Read this before upgrading across 2.0.0.

**MCP server deprecated tool schemes removed.** Code mode is the only supported scheme going forward. If you were passing tool scheme flags, drop them and point your client at the hosted MCP server, which runs Code Mode by default:

```
https://tabstack.stlmcp.com
```

See the [MCP setup guide](/getting-started/mcp/index.md) for client configuration.

- MCP server: `intent` parameter added to the execute tool.
- SDK package renamed to `@tabstack/sdk`.
