Skip to main content
ClaudeWave

The open-source checkpoint layer for AI agents — checkpoints, replay, durable queues, cron, cancellation, gates, and live state, in your own Postgres.

MCP ServersOfficial Registry1 stars0 forksTypeScriptNOASSERTIONUpdated today
Install in Claude Code / Claude Desktop
Method: NPX · @tidebase/sdk
Claude Code CLI
claude mcp add tidebase -- npx -y @tidebase/sdk
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "tidebase": {
      "command": "npx",
      "args": ["-y", "@tidebase/sdk"],
      "env": {
        "TIDEBASE_URL": "<tidebase_url>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
TIDEBASE_URL
Use cases

MCP Servers overview

<p align="center">
  <img src="apps/studio/static/tidebase-mark.svg" alt="Tidebase" width="56" height="56" />
</p>

<h1 align="center">Tidebase</h1>

<p align="center">
  Checkpoints, queues, schedules, gates, live state, and cancellation for agent workflows — in your own Postgres.
</p>

<p align="center">
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-0aabc0.svg" alt="License: Apache-2.0"></a>
  <a href="https://github.com/BlueprintLabIO/tidebase/releases"><img src="https://img.shields.io/github/v/release/BlueprintLabIO/tidebase?color=0aabc0" alt="Latest release"></a>
  <a href="https://github.com/BlueprintLabIO/tidebase/actions/workflows/ci.yml"><img src="https://github.com/BlueprintLabIO/tidebase/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <img src="https://img.shields.io/badge/SDK-TypeScript%20%C2%B7%20Python-0e6f80.svg" alt="TypeScript and Python SDKs">
  <img src="https://img.shields.io/badge/storage-Postgres-0e6f80.svg" alt="Postgres storage">
</p>

<p align="center">
  <a href="#quick-start">Quick start</a>
  ·
  <a href="#api-shape">API</a>
  ·
  <a href="#what-tidebase-stores">Storage contract</a>
  ·
  <a href="#current-scope">Scope</a>
</p>

![Tidebase Studio](docs/assets/dashboard-shot.png)

Tidebase is an open-source checkpoint layer for AI agents: wrap your steps, and failed runs resume from the last safe point — in your own Postgres, without moving execution into a new runtime.

Your code still runs in your app, worker, or job process. Tidebase stores checkpoints, state, events, gates, channel deliveries, recovery attempts, and usage records in Postgres, so "this run died at step 7 — is it safe to rerun?" always has an answer.

Docs: <https://tidebase.dev> · Community: [Discord](https://discord.gg/JQ5sutdP8Y) · For AI assistants: [/llms.txt](https://tidebase.dev/llms.txt)

## Why Tidebase

Agent products usually grow the same operational plumbing:

- status tables for runs and steps
- checkpoint blobs for partial progress
- retry flags and manual-review states
- progress streaming to the UI
- approval gates for risky actions
- token and cost ledgers
- webhook glue for recovery and external review surfaces

Tidebase packages that layer around your existing code. It is not an LLM proxy, queue, hosted worker runtime, or secret broker.

## Quick Start

**Fastest path (no Node needed)** — prebuilt server image:

```bash
docker compose --profile server up -d   # Postgres + ghcr.io/blueprintlabio/tidebase on :7373
```

Then point any SDK at `http://localhost:7373` (`npm i @tidebase/sdk` or `pip install tidebase`).

**Dev setup (server + Studio from source):**

Start Postgres:

```bash
docker compose up -d postgres
```

Install dependencies:

```bash
pnpm install
```

Run the server and Studio:

```bash
pnpm dev
```

- Server: http://localhost:7373
- Studio: http://localhost:5173

Run the example workflow:

```bash
pnpm example
```

Force a failure after two completed checkpoints:

```bash
FAIL_WRITE=1 pnpm example
```

Copy the run id from Studio or the API, then resume:

```bash
TIDEBASE_RUN_ID=run_xxx pnpm example
```

The `plan` and `fetch-sources` steps are returned from checkpoints. Only `write-report` executes again.

<p align="center">
  <img src="docs/assets/crash-resume.gif" width="820" alt="Kill the process mid-run, re-invoke with the same run id, and the workflow resumes from the last checkpoint">
</p>

## Using Tidebase with AI coding agents

Make every AI session in your project use Tidebase correctly:

```bash
npx @tidebase/sdk init        # writes a Tidebase section into AGENTS.md/CLAUDE.md (idempotent)
```

Give your assistant direct access to runs, gates, and recovery via MCP:

```bash
claude mcp add tidebase -e TIDEBASE_URL=http://localhost:7373 -- npx -y @tidebase/mcp
```

Or install the Claude Code plugin (skill + MCP server in one):

```
/plugin marketplace add BlueprintLabIO/tidebase
/plugin install tidebase@tidebase
```

Agent-readable docs live at [tidebase.dev/llms.txt](https://tidebase.dev/llms.txt); every docs page also serves a raw `.md` twin.

## Queues, schedules, and cancellation (v0.5)

Tidebase can now decide **when** your code runs — while still never executing it:

```typescript
// durable queue: dedupe, delay, retries with backoff, concurrency caps
await tide.enqueue('generate-report', {
  queue: 'reports',
  input: { topic },
  dedupeKey: `report:${topic}`,
  maxAttempts: 3,
  deadlineMs: 600_000
})

// pull-mode worker: claims ready runs and executes registered workflows
tide.workflow('generate-report', generateReport)
await tide.work({ queues: ['reports'] })

// cron (UTC, 5-field) — double-fires are structurally impossible
await tide.schedules.set('daily-digest', {
  cron: '0 9 * * *',
  workflowName: 'daily-digest'
})

// authoritative, one-way cancellation — workers observe it at step/gate
// boundaries; complete/fail can never resurrect a cancelled run
await tide.runs.cancel(runId, { reason: 'customer asked', actor: 'support' })
```

Push-mode dispatch is also available: configure a queue with an `invokeUrl` and Tidebase delivers signed `run.invoke` webhooks to your app instead of waiting for a claim. A queued job IS a run — `queued` is a lifecycle state, not a second table — so status never drifts.

See [docs/production.md](docs/production.md) for the full lifecycle, replay contract, worker-death recovery model, and deploy discipline (versioned migrations via `pnpm migrate`, `TIDEBASE_AUTO_MIGRATE=0` for expand/contract deploys).

## Testing

```bash
pnpm test
```

The suite (84 TypeScript tests + 9 Python integration tests, run in CI on every push) uses the same Postgres in an isolated `tidebase_test` database. It is invariant-driven rather than coverage-driven: every test asserts a durability or safety guarantee through the public API or SDK, against real Postgres, including concurrency probes for the guarantees that only matter under contention.

What it proves:

- completed steps replay from storage and never re-execute, including across crash + recovery-webhook resume
- step and run leases are mutually exclusive and fenced — zombie workers cannot write back stale results
- input-hash drift on replay is rejected before it can corrupt a run
- failure classification honors the resume contract: unkeyed external writes park in `manual_review`, idempotency-keyed and read-only steps are `safe_replay`
- per-run event logs are gap-free and strictly ordered under concurrent writers
- gates resolve exactly once, require the resolve token, and replay their decision on resume
- child runs are idempotent by edge name, so resumed fanouts reuse children
- recovery webhooks and channel deliveries are HMAC-signed; the SDK rejects unsigned, tampered, or forged payloads
- a slow or hung channel endpoint never blocks other writers to the run

See [docs/testing.md](docs/testing.md) for the full invariant map and conventions.

## API Shape

```typescript
import { Tidebase } from '@tidebase/sdk'

const tide = new Tidebase()

await tide.run('generate-report', { runId }, async (run, input) => {
  const plan = await run.step('plan', () => makePlan(input))

  await run.state.set({
    status: 'writing',
    progress: 0.7
  })

  return run.step('write-report', () => writeReport(plan))
})
```

## Session Runs

`tide.run()` fits work shaped like a function. For open-ended execution — a protocol gateway in front of an agent, a REPL, a run that spans many requests — attach to a run as a session instead:

```typescript
const session = await tide.runs.attach('mcp-session', { input: { agent: 'hermes' } })

// session is a RunContext: step/gate/state/usage/snapshots all work unchanged
await session.step('tool-call', { input: args }, () => callTool(args))

await session.complete({ calls: 12 }) // or session.fail(err)
```

The session holds the run lease with a background heartbeat (`heartbeatMs`, default 20s). If the process dies, the heartbeat stops, the lease expires, and the reconciler takes over — requeue or recovery webhook, exactly as if a workflow worker had crashed. A session that loses its lease (`onLeaseLost`) is a zombie: the server fences its writes. Pass `runId` to resume an existing session's run; completed steps replay from storage.

For a complete worked example — an MCP gateway that wraps any agent's MCP server in checkpointed tool calls and durable approval gates with one config-line change — see [`examples/mcp-gateway/`](examples/mcp-gateway/).

## Resume Contracts

Each step can declare the operational contract Tidebase should record for replay:

```typescript
await run.step(
  'send-email',
  {
    input: { userId },
    sideEffects: ['email.send'],
    idempotencyKey: `welcome:${userId}`,
    replay: 'auto',
    checkpointInvariant: 'provider accepted the message id',
    verifiedBy: 'email provider response'
  },
  () => sendWelcomeEmail(userId)
)
```

Tidebase records that contract with the step and shows it in Studio. Final step failures are classified as:

- `failed_retryable` when SDK retries remain.
- `manual_review` when replay is manual, or when side effects exist without an idempotency key.
- `failed` for hard failures.

This does not make external systems exactly-once. It makes the resume decision explicit instead of hiding it in logs and custom retry flags.

## Versioned State And Snapshots

`run.state.set()` and `run.state.patch()` still update the current live run state. In v0.2 they also append a version to Tidebase's state history.

```typescript
await run.state.patch({
  status: 'writing',
  progress: 0.7
})
```

You can label the current state when it becomes a meaningful review or restore point:

```typescript
await run.state.save('before-approval', {
  reason: 'the user is about to approve sending'
})
```

Snapshots are a convenience API over labeled state versions for external targets such as reports, artifacts, workspaces, documents, or app state:

```typescript
await run.snapshots.create('draft-v1', {
  ta
ai-agentscheckpointclaude-plugindurable-executionhuman-in-the-loopmcpmcp-serverpostgresself-hostedworkflow

What people ask about tidebase

What is BlueprintLabIO/tidebase?

+

BlueprintLabIO/tidebase is mcp servers for the Claude AI ecosystem. The open-source checkpoint layer for AI agents — checkpoints, replay, durable queues, cron, cancellation, gates, and live state, in your own Postgres. It has 1 GitHub stars and was last updated today.

How do I install tidebase?

+

You can install tidebase by cloning the repository (https://github.com/BlueprintLabIO/tidebase) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is BlueprintLabIO/tidebase safe to use?

+

BlueprintLabIO/tidebase has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.

Who maintains BlueprintLabIO/tidebase?

+

BlueprintLabIO/tidebase is maintained by BlueprintLabIO. The last recorded GitHub activity is from today, with 1 open issues.

Are there alternatives to tidebase?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy tidebase to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: BlueprintLabIO/tidebase
[![Featured on ClaudeWave](https://claudewave.com/api/badge/blueprintlabio-tidebase)](https://claudewave.com/repo/blueprintlabio-tidebase)
<a href="https://claudewave.com/repo/blueprintlabio-tidebase"><img src="https://claudewave.com/api/badge/blueprintlabio-tidebase" alt="Featured on ClaudeWave: BlueprintLabIO/tidebase" width="320" height="64" /></a>

More MCP Servers

tidebase alternatives