mcpField
T
tidebase

tidebase

本地服务
tidebase.devAI 与智能体118 周前更新

关于 tidebase

Tidebase 为 AI Agent 提供身份、凭据代理,以及运行检查点、队列、计划和审批门,并将持久数据存储在自有 Postgres 中。它不运行应用代码,而是让现有运行时管理恢复、审计和敏感凭据。

主要功能

  1. 01为 Agent 隔离身份并代理凭据
  2. 02持久化运行检查点与状态
  3. 03支持队列、计划和失败恢复
  4. 04设置可持久化的审批门
  5. 05在自有 Postgres 中存储数据

适用场景

  1. 01不向模型暴露密钥地调用外部 API
  2. 02从失败步骤恢复 Agent 运行
  3. 03在高风险操作前请求人工审批
  4. 04通过 Studio 检查运行与审批状态

MCP 相关

可通过 @tidebase/mcp 向 AI 助手提供运行、审批门与恢复操作。示例 MCP 网关还能将其他 MCP 服务的工具调用包装为带检查点的操作。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"blueprintlabio-tidebase": {
"command": "npx",
"args": [
"-y",
"@tidebase/mcp"
],
"env": {
"TIDEBASE_URL": "<TIDEBASE_URL>"
}
}
}
}
启动命令npx -y @tidebase/mcp
需要配置的环境变量
TIDEBASE_URLBase URL of your self-hosted Tidebase server

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@tidebase/mcp0.1.1

工具

7

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

Tidebase

Tidebase

为 AI Agent 提供身份验证和凭证代理,并支持检查点、队列、计划任务和审批关卡。数据存储在你自己的 Postgres 中。

许可证:Apache-2.0 最新版本 CI TypeScript 和 Python SDK Postgres 存储

快速开始 · API · 存储规范 · 范围

Tidebase Studio

Tidebase 为你的 AI Agent 提供身份和保险库。当 Agent 调用 API 时,请求会经过 Tidebase,由它注入凭证,因此 Agent 和模型都看不到密钥。你可以限定其范围、审计使用情况并撤销凭证。

Tidebase 还会保存持久化数据:检查点、实时状态、队列、计划任务和审批关卡,全部存储在你自己的 Postgres 中。代码仍在你的应用、工作进程或作业进程中运行;Tidebase 不会运行代码。因此,“这次运行在第 7 步失败了,重新运行安全吗?”这个问题有了答案,而“Agent 以明文形式持有我的 GitHub 令牌”也不再成立。

文档:https://tidebase.dev · 社区:Discord · 面向 AI 助手:/llms.txt

为什么选择 Tidebase

Agent 产品通常会逐渐需要相同的运维基础设施:

  • 为每个 Agent 分配独立身份,而不是共用一个 API 密钥
  • 用于存放第三方密钥和 OAuth 令牌的保险库
  • 在不把密钥交给模型的情况下调用 API
  • 用于记录运行和步骤状态的表
  • 用于保存部分进度的检查点数据
  • 重试标记和人工审核状态
  • 向界面实时推送进度
  • 针对高风险操作的审批关卡
  • 令牌和成本台账
  • 用于恢复和外部审核界面的 Webhook 连接逻辑

Tidebase 将这一层封装起来,围绕你现有的代码提供服务,并通过凭证代理,让 Agent 在不持有密钥的情况下操作实际服务。它不会运行你的代码(运行环境仍由你掌控),也不是大模型代理或托管式工作进程运行环境。

快速开始

最快的方式(无需 Node),使用预构建的服务端镜像:

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

然后让任意 SDK 连接到 http://localhost:7373(npm i @tidebase/sdk 或 pip install tidebase)。

开发环境设置(从源代码运行服务端和 Studio):

启动 Postgres:

docker compose up -d postgres

安装依赖:

pnpm install

运行服务端和 Studio:

pnpm dev

运行示例工作流:

pnpm example

在完成两个检查点后强制失败:

FAIL_WRITE=1 pnpm example

从 Studio 或 API 复制运行 ID,然后恢复运行:

TIDEBASE_RUN_ID=run_xxx pnpm example

plan 和 fetch-sources 步骤会从检查点恢复。只有 write-report 会重新执行。

在运行过程中终止进程,使用相同的运行 ID 重新调用,工作流会从上一个检查点恢复

## Agent 身份验证与凭据代理

为 Agent 提供独立身份,将第三方密钥存入保险库,让 Agent 无需持有密钥即可调用 API。Tidebase 会注入密钥并发起出站调用,你可以限定范围、审计并撤销授权。

import { Tidebase } from '@tidebase/sdk'

const tide = new Tidebase({ baseUrl: 'http://localhost:7373', apiKey: process.env.TIDEBASE_API_KEY })

// 1. Vault a secret behind a pinned upstream. The returned resource never carries the secret.
await tide.resources.connect('github', {
  provider: 'static',
  baseUrl: 'https://api.github.com',
  secret: process.env.GITHUB_TOKEN,
  scopesAllowed: ['repo.read'],
})

// 2. Inside a run, request a grant for what the agent needs to do.
const auth = tide.auth(runId)
const grant = await auth.request({
  resource: 'github:repo:acme/app',
  action: 'repo.read',
  scopes: ['repo.read'],
})

// 3. Make the call through Tidebase. The token is injected upstream; the agent and the LLM never see it.
const res = await auth.use(grant.grantId, { method: 'GET', path: '/user' })

密钥在静态存储时使用信封加密(AES-256-GCM,并由 KMS 包装 DEK)。baseUrl 将上游地址固定,scopesAllowed 限制任何授权的范围,因此即使授权泄露,也无法访问任意主机。代理会屏蔽私有 IP 和元数据主机(防御 SSRF),而 GET /audit 返回的授权凭据中不含任何密钥材料。对于 OAuth 提供商,你可以将凭据托管委托给 nango 或 openbao,Tidebase 只保留不透明的连接引用。

在 AI 编码 Agent 中使用 Tidebase

让项目中的每个 AI 会话都正确使用 Tidebase:

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

通过 MCP 让助手直接访问运行、关卡和恢复功能:

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

或者安装 Claude Code 插件(包含技能和 MCP 服务):

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

面向 Agent 的文档位于 tidebase.dev/llms.txt;每个文档页面也都提供对应的原始 .md 文件。

队列、计划任务与取消(v0.5)

Tidebase 现在可以决定代码何时运行,同时仍绝不执行代码:

// 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' })

现在也支持推送模式分发:为队列配置 invokeUrl 后,Tidebase 会向你的应用发送签名的 run.invoke Webhook,而不是等待领取。排队的任务就是一次运行,queued 是生命周期状态,而不是第二张表,因此状态永远不会不一致。

完整生命周期、重放约定、工作进程退出后的恢复模型以及部署规范(通过 pnpm migrate 执行版本化迁移,扩展/收缩部署时设置 TIDEBASE_AUTO_MIGRATE=0),请参阅 docs/production.md。

测试

pnpm test

测试套件(84 个 TypeScript 测试 + 9 个 Python 集成测试,在 CI 中每次推送时运行)使用同一个 Postgres,并在隔离的 tidebase_test 数据库中执行。它以不变量为驱动,而非以覆盖率为驱动:每项测试都会通过公共 API 或 SDK,针对真实 Postgres,验证持久性或安全保证;还包括并发探测,以验证仅在争用时才会显现的保证。

测试验证的内容:

  • 已完成的步骤会从存储中重放,绝不会重新执行,包括崩溃后通过恢复 Webhook 恢复的情况
  • 步骤租约与运行租约互斥且带有围栏机制,僵尸工作进程无法写入过时结果
  • 重放时会在输入哈希漂移导致运行数据损坏前拒绝请求
  • 故障分类遵循恢复约定:未设置幂等键的外部写入会进入 manual_review,设置了幂等键的步骤和只读步骤则属于 safe_replay
  • 并发写入时,每次运行的事件日志都无间隙且严格有序
  • 每个关卡只会解析一次,且必须提供解析令牌;恢复时会重放其决策
  • 子运行以边名称作为幂等依据,因此恢复后的扇出会复用现有子运行
  • 恢复 Webhook 和渠道投递都带有 HMAC 签名;SDK 会拒绝未签名、被篡改或伪造的载荷
  • 渠道端点响应缓慢或挂起,绝不会阻塞对该运行的其他写入

完整的不变量映射和约定请参阅 docs/testing.md。

API 结构

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))
})

会话运行

tide.run() 适用于函数式的工作。对于开放式执行、位于 Agent 前面的协议网关、REPL 或跨多个请求的运行,可以改为将运行附加到会话:

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)

会话通过后台心跳(heartbeatMs,默认 20s)持有运行租约。如果进程退出,心跳会停止,租约到期,协调器便会接管,执行重新入队或恢复 Webhook,就像工作流工作进程崩溃时一样。丢失租约(onLeaseLost)的会话会变成僵尸:服务端会隔离其写入。传入 runId 可恢复现有会话的运行;已完成的步骤会从存储中重放。

如需完整的示例,了解如何通过更改一行配置,将任意 Agent 的 MCP 服务封装到 MCP 网关中,实现带检查点的工具调用和持久化审批关卡,请参阅 examples/mcp-gateway/。

恢复契约

每个步骤都可以声明 Tidebase 应记录以供重放的运行契约:

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 会将该契约与步骤一同记录,并在 Studio 中显示。最终步骤失败会分类为:

  • 如果仍有 SDK 重试次数,则为 failed_retryable。
  • 如果需要手动重放,或存在副作用但没有幂等键,则为 manual_review。
  • 硬性失败则为 failed。

这不会让外部系统实现恰好一次。它会明确恢复决策,而不是将其隐藏在日志和自定义重试标记中。

版本化状态与快照

run.state.set() 和 run.state.patch() 仍会更新当前运行状态。在 v0.2 中,它们还会将一个版本追加到 Tidebase 的状态历史中。

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

当当前状态成为有意义的审查点或还原点时,可以为其添加标签:

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

快照是基于带标签状态版本的便捷 API,适用于报告、工件、工作区、文档或应用状态等外部目标:

await run.snapshots.create('draft-v1', {
  target: { type: 'report', id: reportId },
  state: draft,
  reason: 'first complete draft'
})

该模型刻意保持精简:

current state = latest version in a stream
snapshot = labeled state version
time travel = read an older version
fork = create new app/run context from an older version
restore = append a new version based on an older version

Tidebase 会存储并公开这些版本。如何还原或分叉自己的状态目标,由你的应用决定。

将运行回退到较早的步骤,切换模型并分叉出新分支;已完成的步骤会从检查点重放

子运行与扇出

较长的 Agent 工作流通常会扇出到多个子 Agent,并汇总它们的结果。Tidebase v0.2 通过父子运行关系边和带检查点的汇总步骤来实现这一模式。

const results = await run.fanout('research-options', [
  {
    name: 'flights',
    workflow: researchFlights,
    input: { destination }
  },
  {
    name: 'hotels',
    workflow: researchHotels,
    input: { destination }
  },
  {
    name: 'food',
    workflow: researchFood,
    input: { destination }
  }
])

子运行的创建以父运行和边名称为依据,具有幂等性。如果父运行恢复,Tidebase 会返回现有子运行,而不是创建重复项。汇总结果会存储在名为 join:<fanout-name> 的常规带检查点步骤中。

并行子 Agent 作为子运行执行,各自独立设置检查点,并在完成时汇总

关卡与通道

通道会将 Tidebase 事件传递到外部界面。Alpha 版本支持 Webhook 通道:

await tide.run(
  'generate-report',
  {
    input: { topic: 'channels' },
    channels: [{
      type: 'webhook',
      url: 'https://your-app.example.com/api/tidebase-events',
      events: ['run.failed', 'step.failed', 'gate.created']
    }]
  },
  workflow
)

关卡会创建持久化审批决策,可由 Studio、产品 UI、Slack/Teams 适配器、内部工具或本地审查页面解决:

const decision = await run.gate('approve-send', {
  prompt: 'Send this report to the customer?',
  data: { reportId },
  channels: [{ type: 'webhook', url: process.env.REVIEW_WEBHOOK_URL! }],
  capability: {
    name: 'report.send',
    scopes: ['report:send'],
    reason: 'agent wants to send an external report'
  }
})

if (decision.decision !== 'approved') {
  throw new Error('Report was not approved')
}

Webhook 关卡载荷包含 resolveUrl 和 resolveToken,供审查者解决关卡。(凭据由 Broker 单独处理;请参阅 Agent 身份验证部分。)

当你无法等待人工审批时,例如在 HTTP 处理器、机器人或协议网关中,可以使用 run.gate() 所基于的非阻塞拆分模式:

const gate = await run.gates.begin('approve-send', { prompt: 'Send it?', data: { reportId } })
if (gate.status === 'pending') {
  // return now; check back with run.gates.get(gate.gateId) on a later request
}

在一次运行中,关卡开始操作按名称实现幂等:重新开始已解决的关卡会立即返回其决策,因此重试的调用方最终会得到同一个答案。

运行在持久化关卡处暂停,人工批准该权限后,工作流继续执行,全程均有审计记录

运行本地审批通道:

pnpm example:review

在另一个终端中:

REQUIRE_APPROVAL=1 \
TIDEBASE_CHANNEL_WEBHOOK=http://localhost:8788/tidebase-events \
pnpm example

打开 http://localhost:8788,批准该关卡,工作流便会继续。

恢复 Webhook

当一次运行失败且配置了恢复 Webhook 时,Tidebase 可以回调你的应用。SDK 可以处理该 Webhook 并恢复匹配的工作流。

const run = await tide.runs.create('generate-report', {
  input: { topic: 'checkpoints' },
  recoveryWebhook: 'https://your-app.example.com/api/tidebase'
})

Tidebase 会记录每次恢复尝试的投递状态、HTTP 状态、响应正文和错误。如果服务器和 SDK 都设置了 TIDEBASE_WEBHOOK_SECRET,恢复负载会使用 x-tidebase-signature 签名。

示例包含一个本地 Webhook 服务器:

pnpm example:webhook

用量跟踪

Tidebase 可以记录一次运行的通用资源用量,而无需代理模型或提供商调用:

await run.usage.record({
  kind: 'llm',
  provider: 'openai',
  model: 'gpt-4.1-mini',
  label: 'draft-response',
  inputTokens: 1200,
  outputTokens: 420,
  costUsd: 0.012
})

用量记录会与运行一同存储,作为 usage.recorded 事件发出,并在 Studio 中汇总。同一台账也可以跟踪非 LLM 资源:

await run.usage.record({
  kind: 'tool',
  provider: 'internal-search',
  quantity: 8,
  unit: 'queries',
  costUsd: 0.004
})

Tidebase 存储的内容

  • 运行和尝试
  • 命名的检查点步骤
  • 防止重复使用过期检查点的输入哈希
  • 步骤恢复契约
  • 实时运行状态
  • 版本化状态流
  • 带标签的状态版本和快照
  • 父子运行关系
  • 仅追加的运行事件
  • 恢复尝试
  • Webhook 通道投递记录
  • 持久化门控和决策
  • 凭据/能力审计元数据
  • 用于跟踪令牌、单位和成本的通用用量记录

所有数据都由 Postgres 提供支持,并且从第一天起就为可自托管而设计。

当前范围

  • 由 Postgres 提供支持的运行存储
  • 权威运行生命周期,原生支持取消和截止时间
  • 持久化队列(去重、延迟、优先级、重试/退避、并发和速率上限)
  • Cron 调度(UTC、防止重复触发)
  • 拉取模式 Worker(tide.work)和推送模式签名调用 Webhook
  • 调谐器(租约过期后重新入队/恢复、截止时间取消、Cron、派发)
  • 版本化迁移运行器
  • TypeScript SDK
  • Python SDK,包含 asyncio(sdk-python/、tidebase.aio)
  • SvelteKit Studio
  • 实时状态设置/补丁
  • 状态历史记录和带标签的快照
  • 子运行和扇出汇合
  • SSE 事件流
  • 签名恢复 Webhook
  • Webhook 通道
  • 持久化门控
  • 用量/资源台账
  • Dogfood 工作流
  • Agent 身份验证 + 凭据代理:每个 Agent 使用密钥对标识、绑定运行的授权、用于存储机密并将其注入代理调用的保险库(客户端和 LLM 都无法看到这些机密)、策略引擎、SSRF 防御,以及 Nango/OpenBao 后端

Alpha 版本不包含的内容

截至 v0.7.0(2026 年 6 月)。更早的 Alpha 版本曾将队列、调度、取消、审批门控、API 身份验证和凭据代理列在此处。这些功能都已发布(v0.5 至 v0.7):支持重试/退避的持久化队列、Cron、权威取消、恰好一次门控、会话运行、可选的 Bearer 身份验证、可检测已死亡 Worker 并重新派发任务的调谐器,以及 v0.7 中的 Agent 身份验证控制平面和凭据代理。以下内容仍被刻意排除在范围之外:

  • Tidebase 托管的代码执行(你的运行时仍由你掌控;这是永久不支持的功能,并非待开发)
  • LLM 网关/代理
  • 托管的通道适配器
  • Agent 记忆(对话或嵌入存储)
  • 多租户身份验证(目前使用单个共享 API 密钥)
  • 托管云服务

Alpha 版本说明

此版本适合本地演示和早期反馈,不适用于生产环境。

重要限制:

  • 迁移已进行版本管理并使用咨询锁;开发环境会在启动时自动迁移,设置 TIDEBASE_AUTO_MIGRATE=0 并运行 pnpm migrate,即可遵循扩展/收缩部署规范。
  • API 身份验证默认关闭:在服务器和 SDK 中设置 TIDEBASE_API_KEY(Studio 中设置 VITE_TIDEBASE_API_KEY)即可启用。未设置时,API 处于开放状态,只能在可信的本地/自托管环境中使用。
  • 外部副作用仍需在用户代码中使用幂等键。
  • Tidebase 会记住发生过的事情,并可以调用恢复 Webhook,但不保证用户代码届时仍可用来恢复。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。