mcpField
T
tubekit

tubekit

本地服务
gatecast.sriera.dev社交媒体011 周前更新

关于 tubekit

tubekit 是用于通过 AI 助手管理 YouTube 频道的 MCP 服务,涵盖发布、分析和创作者工具。它在操作中加入合规检查、配额核算、幂等处理和可审计记录。

主要功能

  1. 01合规检查并提供修正建议
  2. 02上传视频和管理元数据
  3. 03频道与视频分析报告
  4. 04评论审核与播放列表管理
  5. 05配额跟踪与幂等上传
  6. 06加密 OAuth 令牌并记录审计日志

适用场景

  1. 01发布前检查视频元数据
  2. 02重试上传时避免重复发布
  3. 03查看频道表现和视频趋势
  4. 04整理评论并管理播放列表

MCP 相关

MCP 客户端可调用 tubekit 工具,检查、发布和管理 YouTube 频道内容、分析数据及评论。更改状态的调用会经过合规、配额和审计控制。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"santiriera626-tubekit": {
"command": "uvx",
"args": [
"tubekit-mcp"
],
"env": {
"TUBEKIT_MASTER_KEY_PATH": "<TUBEKIT_MASTER_KEY_PATH>",
"TUBEKIT_OAUTH_CLIENT_SECRETS_PATH": "<TUBEKIT_OAUTH_CLIENT_SECRETS_PATH>",
"TUBEKIT_STATE_DB_PATH": "<TUBEKIT_STATE_DB_PATH>"
}
}
}
}
启动命令uvx tubekit-mcp
需要配置的环境变量
TUBEKIT_MASTER_KEY_PATH密钥Path to the Fernet key that encrypts stored OAuth tokens at rest. The server refuses to start without one.
TUBEKIT_OAUTH_CLIENT_SECRETS_PATH密钥Path to your own Google Cloud OAuth client JSON. Required to refresh access tokens.
TUBEKIT_STATE_DB_PATHSQLite file holding the audit log, quota ledger and channel state.

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

安装包
pypitubekit-mcp0.3.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

tubekit-mcp

面向 YouTube 发布、分析和创作者洞察的合规感知 Model Context Protocol 服务——每项操作在触及频道前都会经过把关、计量和审计。

CI License: FSL-1.1-MIT Python 3.11+ Type-checked: mypy strict Lint: ruff

tubekit-mcp 是一个 MCP 服务:将它连接到 MCP 客户端(Claude Desktop、 Claude Code,……),助手便可以代表你在 YouTube 频道上发布和管理视频,并且每次会更改状态的调用都会经过合规检查、配额核算、幂等上传和防篡改审计日志。 本项目采用 FSL-1.1-MIT 许可——你可以自由运行并自托管,无论是否用于商业用途;每个版本在发布两年后都会转为纯 MIT 许可。

架构

单次工具调用(例如 upload_video)会经过合规把关、配额 / 幂等性账本、OAuth 刷新、YouTube API,并生成一条防篡改审计记录——同时让纯核心不受协议相关问题影响。CI 通过 AST 适配度测试强制执行这一边界 (tests/unit/services/test_no_fastmcp_imports.py)。

flowchart LR
    client["MCP client<br/>(Claude Desktop / Code)"]
    subgraph edge["Protocol edge"]
      transport["Transport<br/>stdio · HTTP + Bearer"]
      tool["Tool wrapper"]
    end
    subgraph core["Pure core — no protocol imports (CI-enforced)"]
      compliance{"Compliance<br/>gate"}
      ledger["Quota +<br/>idempotency<br/>ledger"]
      oauth["OAuth refresh<br/>(Fernet at rest)"]
    end
    upstream["YouTube<br/>Data / Analytics API"]
    audit[("Tamper-evident<br/>hash-chained<br/>audit log")]

    client --> transport --> tool --> compliance
    compliance -->|pass| ledger --> oauth --> upstream
    compliance -->|fail| suggestion["Suggestion →<br/>agent retries"]
    tool -. audited .-> audit
    ledger -. audited .-> audit
    oauth -. audited .-> audit

为何构建此项目。 Agent 正开始运营真实的 YouTube 频道——而频道是一项可能失去的资产。一次错误调用就可能发布违反政策的视频、耗尽当天的 API 配额(一次上传会消耗默认每日 10,000 单位中的 1600 单位),或在重试时重复发布。通用 YouTube 封装会把原始 API 交给 Agent;tubekit 则为每次调用加上无人值守运营所需的防护措施:任何内容上线前先进行合规把关,花费配额前先完成核算,支持幂等重试,将 OAuth 令牌静态加密(日志中仅记录指纹),并对 Agent 的所有操作建立防篡改审计链。完整的设计理由见 ADR 0001。

用法

前置条件

要让助手能够操作频道,你需要为每个频道一次性准备:

  1. 一个已启用 YouTube Data API v3(如果使用 get_analytics,还需启用 YouTube Analytics API)的 Google Cloud 项目。
  2. 一个类型为 桌面应用 的 OAuth 客户端,下载为 client_secret.json。
  3. 频道,其 Google 账号将授予授权。

OAuth 授权流程需要交互操作,且只在此处进行——tubekit 会将由此生成的刷新令牌以 Fernet 加密方式存储,绝不会打印出来。没用过 Google Cloud Console?docs/runbooks/gcp-setup.md 会从零开始讲解整个流程(项目、API、授权同意屏幕、客户端类型,以及两项容易让人措手不及的 Google 政策——测试期间的令牌过期,以及未经审核的项目只能上传为私人锁定状态)。授权流程本身见 docs/runbooks/oauth-bootstrap.md。

安装

从 PyPI 安装:

uv tool install tubekit-mcp   # installs the tubekit / tubekit-mcp-* commands

实际安装请使用 uv tool install,不要使用 uvx:下面的一次性步骤完成后仍需要使用 tubekit CLI。uvx tubekit-mcp 会在临时环境中运行 stdio 服务;设置完成后,MCP 客户端的配置会指向该服务。

服务现在还无法启动,这是有意为之——它拒绝在没有主密钥的情况下运行,而不会擅自生成一个,因为主密钥负责加密静态存储的 OAuth 令牌。下方的一次性设置只需执行两条命令即可解决。

或者从源代码安装,用于开发:

git clone https://github.com/santiriera626/tubekit-mcp.git tubekit-mcp && cd tubekit-mcp
uv sync --all-extras        # installs the tubekit / tubekit-mcp-* entry points
make db-upgrade             # builds the state schema (wraps `tubekit db upgrade`;
                            #   `tubekit db current` prints the applied revision)

(uv 本身可通过 curl -LsSf https://astral.sh/uv/install.sh | sh 安装。)

60 秒上手 — 无需 Google 账号

合规引擎完全在本地运行,因此你可以先看看关卡及其自动纠正的 Suggestion 如何工作,再接触 Google Cloud:

cat > video.json <<'EOF'
{
  "title": "Test Upload — Compliance Gate Demo",
  "description": "Demo description for the compliance gate.",
  "tags": ["demo", "test"],
  "ai_disclosure": false,
  "made_for_kids": null,
  "category_id": "10"
}
EOF
uv run tubekit compliance test video.json
Compliance: PASSED  (8 rules evaluated)
  WARNING AI_DISCLOSURE_MISSING: AI disclosure flag is false; confirm this is the
      channel owner's intended policy for AI-generated content.
      suggestion: action=set field=metadata.ai_disclosure value=True
  WARNING KIDS_FLAG_NOT_SET: made_for_kids is unset; set it explicitly to true or
      false (this rule does not classify by content).
      suggestion: action=set field=metadata.made_for_kids value=False

违反错误级别规则——例如标题有 126 个字符——会导致关卡失败并返回退出码 1,以及可由机器应用的修复建议(suggestion: action=truncate field=metadata.title value=100)。这与 Agent 从被拒绝的 upload_video 请求中收到并在重试前应用的 Suggestion 相同(ADR D8)。tubekit compliance list 会打印规则目录;tubekit compliance manifest 会导出规则目录,供外部审计人员使用。

使用 AI Agent 安装

不想自己输入上面的命令?将下面的代码块粘贴到 Claude Code(或任何可访问 shell 的编码 Agent)中,它就会为你克隆、安装并注册服务。它会停在上述边界:不会涉及 Google 账号、client_secret.json 或 OAuth 授权同意。

Install tubekit-mcp and register it as an MCP server. Stop and report if any step fails.

1. Clone the repo and enter it (install uv first if missing:
   curl -LsSf https://astral.sh/uv/install.sh | sh):
   git clone https://github.com/santiriera626/tubekit-mcp.git tubekit-mcp && cd tubekit-mcp

2. Install dependencies, apply the database migrations and create the Fernet
   master key (the server refuses to start without one):
   uv sync --all-extras
   make db-upgrade
   uv run tubekit auth init-master-key
   (Idempotent: an existing key is reported and left untouched.)

3. Run the zero-credential compliance smoke check to confirm the install works:
   cat > video.json <<'EOF'
   {
     "title": "Test Upload — Compliance Gate Demo",
     "description": "Demo description for the compliance gate.",
     "tags": ["demo", "test"],
     "ai_disclosure": false,
     "made_for_kids": null,
     "category_id": "10"
   }
   EOF
   uv run tubekit compliance test video.json
   Expect "Compliance: PASSED (8 rules evaluated)" and exit code 0.

4. Register the server with Claude Code over stdio, using absolute paths:
   claude mcp add tubekit \
     -e TUBEKIT_STATE_DB_PATH="$(pwd)/state.db" \
     -e TUBEKIT_MASTER_KEY_PATH="$HOME/.config/tubekit/master.key" \
     -- "$(pwd)/.venv/bin/tubekit-mcp-stdio"

Do not run `tubekit auth setup-channel` or open any Google consent screen —
OAuth channel bootstrap is a separate, human-in-the-loop step documented in
docs/runbooks/oauth-bootstrap.md. Stop after step 4 and tell me to run that
myself.

注册后重启 MCP 客户端;现在它可以调用 tubekit.health() 并列出完整的工具目录。所有接受 channel 参数的工具——包括 validate_compliance——都需要配置好的频道,也就是说,你需要自行完成一次性设置——包括在 docs/runbooks/oauth-bootstrap.md 中进行 OAuth 授权同意。 无需任何频道,也可以通过第 3 步的 tubekit compliance test 测试合规关卡本身。

一次性设置
# 1. Create the Fernet master key used to encrypt stored tokens (mode 0600).
#    Skip if the agent install above already created it.
tubekit auth init-master-key

# 2. Bootstrap a channel — opens a browser for the OAuth consent.
#    The alias is positional; --channel-id, --gcp-project, --client-secrets
#    and --scopes are all required (see docs/runbooks/oauth-bootstrap.md).
tubekit auth setup-channel mychannel \
  --channel-id UCxxxxxxxxxxxxxxxxxxxxxx \
  --gcp-project my-gcp-project \
  --client-secrets ./client_secret.json \
  --scopes youtube.upload,youtube.readonly

#    …or, on a headless box (no browser), append --device-code:
tubekit auth setup-channel mychannel \
  --channel-id UCxxxxxxxxxxxxxxxxxxxxxx \
  --gcp-project my-gcp-project \
  --client-secrets ./client_secret.json \
  --scopes youtube.upload,youtube.readonly \
  --device-code

# 3. Define the channel registry — setup-channel persists only the encrypted
#    token; the registry is a TOML you write yourself. The table name is the
#    alias. Full field reference: docs/runbooks/vps-deploy.md §5.
mkdir -p ~/.config/tubekit/channels
cat > ~/.config/tubekit/channels/mychannel.toml <<'EOF'
[mychannel]
channel_id     = "UCxxxxxxxxxxxxxxxxxxxxxx"
gcp_project_id = "my-gcp-project"
oauth_scopes   = [
  "https://www.googleapis.com/auth/youtube.upload",
  "https://www.googleapis.com/auth/youtube.readonly",
]
EOF

# 4. Verify — `show` prints one channel's status (token fingerprint only),
#    `list` prints every configured alias
tubekit channels show mychannel --channels-dir ~/.config/tubekit/channels
tubekit channels list --channels-dir ~/.config/tubekit/channels
连接到 MCP 客户端(stdio)

大多数客户端通过 stdio 启动服务。将以下内容添加到客户端的 MCP 配置中(对于 Claude Desktop:claude_desktop_config.json):

{
  "mcpServers": {
    "tubekit": {
      "command": "tubekit-mcp-stdio",
      "env": {
        "TUBEKIT_STATE_DB_PATH": "/absolute/path/to/state.db",
        "TUBEKIT_MASTER_KEY_PATH": "/absolute/path/to/master.key"
      }
    }
  }
}

重启客户端。助手现在可以看到以下工具以及 tubekit.health() 探测工具。比如,可以让它“将 ./intro.mp4 上传到我的 mychannel”,它就会调用 upload_video,该工具会进行合规检查、扣除配额、刷新 OAuth 并写入审计记录——所有这些操作都会透明地完成。

可用工具
工具功能说明OAuth scope配额
validate_compliance(channel, metadata, thumbnail_present=False)根据元数据运行规则注册表;返回 ComplianceReport。完全在本地运行,不会调用 YouTube。—0
upload_video(channel, video_path, metadata, idempotency_key, privacy_status="private", notify_subscribers=False)通过内部合规检查后上传视频。通过 idempotency_key 实现幂等。youtube.upload1600
set_thumbnail(channel, video_id, thumbnail_path)为现有视频设置缩略图。youtube50
update_metadata(channel, video_id, patch)部分更新标题、说明、标签和隐私设置。更新后的元数据须通过合规检查。youtube50
get_video_status(channel, video_id)读取视频的处理和隐私状态。youtube.readonly1
get_analytics(channel, metrics, start_date, end_date, dimensions=None)获取指定时间段内的频道级指标。使用单独的 Analytics 配额池。yt-analytics.readonly1(Analytics)
get_portfolio_report(channels=None, period="28d", start_date=None, end_date=None)每个频道一行:时段总计及与前一时段的差值(观看次数、收入),以及未获利频道的 YPP 进度。各频道的失败互不影响。yt-analytics.readonly + youtube.readonly(收入数据需额外授权 yt-analytics-monetary.readonly)每个频道 3(Analytics)
get_channel_report(channel, period="28d", start_date=None, end_date=None, granularity="auto")单频道健康报告:总计、趋势序列、热门视频、流量来源、Shorts/长视频占比、收入或 YPP 进度,以及全生命周期快照。yt-analytics.readonly + youtube.readonly(收入数据需额外授权 monetary)7(Analytics)
get_video_report(channel, video_id, period="lifetime", start_date=None, end_date=None, granularity="auto")单个视频的深度分析:留存率代理指标、流量来源,以及已获利视频的收入;默认从发布日期开始统计。yt-analytics.readonly + youtube.readonly(收入数据需额外授权 monetary)5(Analytics)
list_my_videos(channel, page_size=50, page_token=None)分页列出频道上传的视频。youtube.readonly1
get_comments_digest(channels=None, force_sync=False)汇总所有频道的评论数(未读、未回复、被保留、垃圾评论;按视频统计)。youtube.force-ssl每个频道 4
list_comments(channel, video_id=None, only="unread", search=None, order="time", page_size=20, page=1)从本地镜像中简洁列出评论。youtube.force-ssl1
get_comment_thread(channel, comment_id)完整获取一个评论串:不截断的正文和所有回复。youtube.force-ssl2
mark_comments_reviewed(channel, ids=None, video_id=None, all_unread=False, state="read")设置本地分流状态;绝不修改 YouTube 上的内容。—0
check_oauth(channel)零配额 OAuth 可用性预检:使用 Google 的令牌端点刷新已存储的授权,并报告 oauth_ok 和过期时间。在调用消耗配额的工具前运行。—0
request_ingest_upload(channel, filename, size_bytes, sha256)生成一次性代理上传 URL,使远程客户端可以通过 PUT 上传数 GB 的视频,再由服务端摄取——无需 ssh。请参阅媒体摄取。—0
list_playlists(channel, page_size=50, page_token=None)列出频道自己的播放列表:ID、标题、隐私设置和条目数量。youtube.readonly1
list_playlist_items(channel, playlist_id, page_size=50, page_token=None)按顺序列出一个播放列表中的视频。返回每个 playlist_item_id,这是移除或重新排序所需的标识符。youtube.readonly1
create_playlist(channel, title, description="", privacy_status="private")创建播放列表。默认设为私密;改为公开需要明确操作。不具备幂等性。youtube50
update_playlist(channel, playlist_id, title=None, description=None, privacy_status=None)更新标题、说明或隐私设置。未提供的字段会读取并合并,绝不会清空。youtube50
add_to_playlist(channel, playlist_id, video_id, position=None)添加视频(追加到末尾,或插入到 position 指定的位置)。不具备幂等性——YouTube 允许重复添加。youtube50
reorder_playlist_item(channel, playlist_id, playlist_item_id, video_id, position)将条目移至 position 位置(0 表示首位)。youtube50
remove_from_playlist(channel, playlist_item_id)移除一个条目。不会影响视频本身。youtube50

播放列表写入操作需要提供 playlist_item_id,而不是单独的视频 ID:同一视频可能在列表中出现多次,因此 YouTube 无法仅凭视频本身确定对应项。通过一次 list_playlist_items 调用(1 个单位)获取这些 ID,并重复使用——服务会刻意不为你解析它们,因为这会产生调用方从未要求的配额消耗。

播放列表不经过合规注册表检查:该注册表会评估视频元数据(缩略图、类别、标签、合成媒体声明),而播放列表没有这些内容;其中的 TITLE_TOO_LONG 还会把 视频 的长度上限(100)用于实际上限为 150 的资源。实际执行的是 Google 为播放列表资源记录的要求:标题不能为空,privacyStatus 必须有效,标题不超过 150 个字符、描述不超过 5000 个字符,且两者都不能包含 <、> 或 U+2028。这些限制记录在 YouTube 帮助页面中,而不在 Data API 参考文档中——后者没有记录任何此类限制,这也是一开始会漏掉它们的原因。

评论工具需要频道授权包含 youtube.force-ssl(按审核状态筛选仅限所有者)。使用 check_oauth 验证;如果缺少此授权,请重新授权一次: tubekit auth setup-channel --scopes …,https://www.googleapis.com/auth/youtube.force-ssl。

所有报告工具中的收入数据都只是广告收入 + YouTube Premium 收入估算值(频道级 API 不提供会员、Super Chat 和 Shopping 数据),有约 2 天的延迟(period.revenue_complete_until),并会在次月 10 日左右最终确定。目标 Analytics API 不提供缩略图展示次数/点击率。对于任意临时查询,get_analytics 仍是原始查询的备用入口。

每个工具都会返回一个 ToolResult 封装(ok + data,或一个结构化的 ToolError,其 code 是已记录的错误代码之一)。合规检查失败时,错误会附带一个 Suggestion,助手可以应用该建议并重试——这就是 ADR D8 中描述的自我纠正循环。

HTTP 传输(多用户)

对于远程/多租户使用,请改为运行 HTTP 传输。它要求每个客户端使用持有者 API 令牌,该令牌限定了可访问的特定频道和工具,并可选择设置每个令牌的速率限制:

# Issue a token (the plain value is printed exactly once — store it now)
tubekit auth issue --name claude-prod --channels mychannel --tools "*" \
  --rate-limit-per-min 30

# Serve over HTTP
tubekit-mcp-http --host 0.0.0.0 --port 8080

客户端发送 Authorization: Bearer <token>。未经身份验证、超出授权范围或触发速率限制的请求会收到 JSON-RPC 错误(-32001..-32006)。GET /healthz 会返回存活状态负载;只有提供有效的 Bearer 令牌时才会附加各频道的详细信息(别名、OAuth 过期时间),并且仅包含该令牌授权的频道。使用 tubekit auth list | show | revoke | rotate 管理令牌。

要在 VPS 上集中运行此服务(一个服务端,多个项目通过 HTTPS 连接),请按照 docs/runbooks/vps-deploy.md 操作——这是一份为基础设施团队编写的完整分步部署指南(systemd + Traefik + 每个项目各自的令牌)。

媒体导入(远程 upload_video)

upload_video(video_path) 会从服务器的文件系统读取文件——客户端本地路径在远程部署中永远无法解析。可以通过两种方式将媒体文件传到服务器。

经代理上传(推荐,无需 ssh)。 Agent 通过 MCP 使用 HTTP 协调整个传输过程。调用 request_ingest_upload,然后将字节 PUT 到它返回的一次性 URL(使用相同的 Bearer 令牌),最后使用返回的服务器端路径调用 upload_video:

# 1. request_ingest_upload(channel, filename="video.mp4", size_bytes, sha256)
#    → { upload_url, curl, video_path: "/ingest/video.mp4" }
# 2. transfer the bytes (the returned curl recipe):
curl -fSs -T video.mp4 -H "Authorization: Bearer $TUBEKIT_TOKEN" "<upload_url>"
# 3. upload_video(channel="...", video_path="/ingest/video.mp4", ...)

服务器会将请求正文流式写入暂存文件 .part,校验 size_bytes 和 sha256,并在 upload_video 读取文件前以原子方式发布。该 URL 是一个有时效(TTL)、与通道绑定且仅可使用一次的能力。传输中断后,可通过 HEAD 和 Content-Range 续传。设计原理:ADR 0002。需要设置 TUBEKIT_INGEST_UPLOAD_URL_BASE(否则该工具会返回 precondition_failed)。

rsync 约定(备用方案,需要 ssh)。 通过带外方式传输,然后使用服务器端路径调用工具:

rsync -av --chmod=F644 video.mp4 <server>:/opt/tubekit-ingest/
# upload_video(channel="...", video_path="/ingest/video.mp4", ...)

将 TUBEKIT_INGEST_DIR 设置为服务器内的导入路径(例如 /ingest):当 video_path 无法读取时,该工具会返回带有 suggestion 的 validation_error,指引调用该工具的 Agent 使用此约定。有关卷挂载和保留策略,请参阅 VPS 运维手册中的媒体导入部分。

环境变量

所有设置均使用 TUBEKIT_ 前缀(参见 .env.example):

变量默认值用途
TUBEKIT_STATE_DB_PATHstate.db用于存放审计表和状态表的 SQLite 文件
TUBEKIT_MASTER_KEY_PATH~/.config/tubekit/master.key用于加密已存储 OAuth 令牌的 Fernet 密钥
TUBEKIT_OAUTH_CLIENT_SECRETS_PATH未设置client_secret.json(Google Cloud 机密客户端)的路径。运行时必需——没有它,google-auth 无法刷新访问令牌,因此未设置时所有频道工具都会失败
TUBEKIT_TOKEN_BACKENDsqlite_fernet令牌存储后端(sqlite_fernet | in_memory)
TUBEKIT_AUDIT_RETENTION_DAYS365审计保留期限
TUBEKIT_OTLP_ENDPOINT未设置OTLP 收集器端点;未设置时 → 不执行遥测操作
TUBEKIT_INGEST_DIR未设置服务端媒体导入目录。会在 upload_video 路径错误中显示;并且仅对 HTTP 调用方而言,这是其 video_path/thumbnail_path 必须解析到的边界。未设置意味着没有此类边界:此时 HTTP 令牌相当于具有服务器文件系统的读取权限
TUBEKIT_INGEST_UPLOAD_URL_BASE未设置代理上传的公共源地址;未设置时会禁用 request_ingest_upload
TUBEKIT_INGEST_UPLOAD_TTL_SECONDS3600一次性代理上传令牌的有效期
TUBEKIT_INGEST_MAX_BYTES21474836480单次代理上传的最大大小(20 GiB)
TUBEKIT_INGEST_MAX_PENDING32并发待处理上传令牌数量上限(防止磁盘耗尽)
TUBEKIT_INGEST_PURGE_AFTER_UPLOADtrue确认上传/缩略图后,从导入目录中删除源文件
TUBEKIT_HTTP_KEEPALIVE_TIMEOUT5uvicorn keep-alive 超时时间(秒);长时间 SSE 会话时可调高,并与代理空闲超时时间保持一致
TUBEKIT_HTTP_LIMIT_CONCURRENCY未设置uvicorn 最大并发连接数
TUBEKIT_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT未设置uvicorn 优雅关闭超时时间(秒)
TUBEKIT_HTTP_MAX_JSONRPC_BODY4194304认证前,认证关卡为单个 JSON-RPC POST 缓冲的最大字节数(防止认证前 DoS);超出时 → 413
TUBEKIT_HTTP_FORWARDED_ALLOW_IPS未设置uvicorn 可信任其 X-Forwarded-* 标头的反向代理 IP/CIDR。未设置时 → uvicorn 仅信任 127.0.0.1,因此位于代理之后时,每条审计记录都会标记为代理的 IP,且请求协议仍为 http。请使用代理自身固定的地址,而不是桥接子网——共享网络上的每个容器都能解析到该 CIDR 内,并可能伪造标头。绝不要设为 *(加载时会拒绝):这会允许任何调用方选择审计记录中的 IP
TUBEKIT_HTTP_SSE_RESUMABLEfalse启用 MCP 可流式传输 HTTP 的断点续传(内存事件存储),使中断的 SSE 会话可通过 Last-Event-ID 恢复
TUBEKIT_HTTP_SSE_RETRY_INTERVAL_MS2000向客户端公布的 SSE 重连提示(毫秒);仅在启用断点续传时使用
TUBEKIT_SQLITE_BUSY_TIMEOUT_MS5000SQLite 写入锁在返回 SQLITE_BUSY 前的等待时间
TUBEKIT_LOG_LEVEL / TUBEKIT_LOG_FORMATINFO / json日志记录

如果 state.db / master.key 同时丢失,就意味着必须重新引导每个频道。 请将它们一并备份——参见 docs/runbooks/state-db-backup.md。

托管版本

Gatecast 是 tubekit 的托管版——使用相同的引擎,并由我们代为运行和保持在线。该服务尚处于发布前阶段;目前只有候补名单。使用此仓库自托管一直都受到全面支持。

开发

uv sync --all-extras
make lint    # ruff
make type    # mypy --strict
make test    # pytest unit suite
make cov     # coverage report

make demo-stack-up 会启动 Jaeger/Prometheus/Grafana 可观测性堆栈,并配置五个仪表板(docker-compose.demo.yml、docs/grafana/)。

仓库布局

docs/adr/        Architecture Decision Records (source of truth for design)
docs/grafana/    Provisioned Grafana dashboards + demo observability config
docs/runbooks/   Operational procedures (master key rotation, audit verify, …)
docs/ROADMAP.md  Shipped, planned and under-exploration work
src/tubekit/     Library code (Alembic migrations ship in src/tubekit/migrations/)
tests/           Unit + integration suites

贡献与安全

许可证

FSL-1.1-MIT © 2026 sriera

用通俗的话来说,Functional Source License 允许你阅读、运行、修改并为自己的频道自托管——无论是否用于商业目的。它唯一禁止的是将 tubekit 本身作为竞争产品或服务提供给他人。每个版本发布两年后,还会自动且不可撤销地转为纯 MIT 许可证。

评论

支持 Markdown

第一次接触 MCP?

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

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