关于 tubekit
tubekit 是用于通过 AI 助手管理 YouTube 频道的 MCP 服务,涵盖发布、分析和创作者工具。它在操作中加入合规检查、配额核算、幂等处理和可审计记录。
主要功能
- 01合规检查并提供修正建议
- 02上传视频和管理元数据
- 03频道与视频分析报告
- 04评论审核与播放列表管理
- 05配额跟踪与幂等上传
- 06加密 OAuth 令牌并记录审计日志
适用场景
- 01发布前检查视频元数据
- 02重试上传时避免重复发布
- 03查看频道表现和视频趋势
- 04整理评论并管理播放列表
MCP 相关
MCP 客户端可调用 tubekit 工具,检查、发布和管理 YouTube 频道内容、分析数据及评论。更改状态的调用会经过合规、配额和审计控制。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx tubekit-mcpTUBEKIT_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+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
tubekit-mcp
面向 YouTube 发布、分析和创作者洞察的合规感知 Model Context Protocol 服务——每项操作在触及频道前都会经过把关、计量和审计。
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。
用法
前置条件
要让助手能够操作频道,你需要为每个频道一次性准备:
- 一个已启用 YouTube Data API v3(如果使用
get_analytics,还需启用 YouTube Analytics API)的 Google Cloud 项目。 - 一个类型为 桌面应用 的 OAuth 客户端,下载为
client_secret.json。 - 频道,其 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.upload | 1600 |
set_thumbnail(channel, video_id, thumbnail_path) | 为现有视频设置缩略图。 | youtube | 50 |
update_metadata(channel, video_id, patch) | 部分更新标题、说明、标签和隐私设置。更新后的元数据须通过合规检查。 | youtube | 50 |
get_video_status(channel, video_id) | 读取视频的处理和隐私状态。 | youtube.readonly | 1 |
get_analytics(channel, metrics, start_date, end_date, dimensions=None) | 获取指定时间段内的频道级指标。使用单独的 Analytics 配额池。 | yt-analytics.readonly | 1(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.readonly | 1 |
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-ssl | 1 |
get_comment_thread(channel, comment_id) | 完整获取一个评论串:不截断的正文和所有回复。 | youtube.force-ssl | 2 |
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.readonly | 1 |
list_playlist_items(channel, playlist_id, page_size=50, page_token=None) | 按顺序列出一个播放列表中的视频。返回每个 playlist_item_id,这是移除或重新排序所需的标识符。 | youtube.readonly | 1 |
create_playlist(channel, title, description="", privacy_status="private") | 创建播放列表。默认设为私密;改为公开需要明确操作。不具备幂等性。 | youtube | 50 |
update_playlist(channel, playlist_id, title=None, description=None, privacy_status=None) | 更新标题、说明或隐私设置。未提供的字段会读取并合并,绝不会清空。 | youtube | 50 |
add_to_playlist(channel, playlist_id, video_id, position=None) | 添加视频(追加到末尾,或插入到 position 指定的位置)。不具备幂等性——YouTube 允许重复添加。 | youtube | 50 |
reorder_playlist_item(channel, playlist_id, playlist_item_id, video_id, position) | 将条目移至 position 位置(0 表示首位)。 | youtube | 50 |
remove_from_playlist(channel, playlist_item_id) | 移除一个条目。不会影响视频本身。 | youtube | 50 |
播放列表写入操作需要提供
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_PATH | state.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_BACKEND | sqlite_fernet | 令牌存储后端(sqlite_fernet | in_memory) |
TUBEKIT_AUDIT_RETENTION_DAYS | 365 | 审计保留期限 |
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_SECONDS | 3600 | 一次性代理上传令牌的有效期 |
TUBEKIT_INGEST_MAX_BYTES | 21474836480 | 单次代理上传的最大大小(20 GiB) |
TUBEKIT_INGEST_MAX_PENDING | 32 | 并发待处理上传令牌数量上限(防止磁盘耗尽) |
TUBEKIT_INGEST_PURGE_AFTER_UPLOAD | true | 确认上传/缩略图后,从导入目录中删除源文件 |
TUBEKIT_HTTP_KEEPALIVE_TIMEOUT | 5 | uvicorn keep-alive 超时时间(秒);长时间 SSE 会话时可调高,并与代理空闲超时时间保持一致 |
TUBEKIT_HTTP_LIMIT_CONCURRENCY | 未设置 | uvicorn 最大并发连接数 |
TUBEKIT_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT | 未设置 | uvicorn 优雅关闭超时时间(秒) |
TUBEKIT_HTTP_MAX_JSONRPC_BODY | 4194304 | 认证前,认证关卡为单个 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_RESUMABLE | false | 启用 MCP 可流式传输 HTTP 的断点续传(内存事件存储),使中断的 SSE 会话可通过 Last-Event-ID 恢复 |
TUBEKIT_HTTP_SSE_RETRY_INTERVAL_MS | 2000 | 向客户端公布的 SSE 重连提示(毫秒);仅在启用断点续传时使用 |
TUBEKIT_SQLITE_BUSY_TIMEOUT_MS | 5000 | SQLite 写入锁在返回 SQLITE_BUSY 前的等待时间 |
TUBEKIT_LOG_LEVEL / TUBEKIT_LOG_FORMAT | INFO / 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
贡献与安全
- 欢迎贡献——工作流程和质量标准请参阅
CONTRIBUTING.md。 - 请按照
SECURITY.md的说明私下报告安全漏洞。 - 发布历史见
CHANGELOG.md;路线图见docs/ROADMAP.md。
许可证
FSL-1.1-MIT © 2026 sriera
用通俗的话来说,Functional Source License 允许你阅读、运行、修改并为自己的频道自托管——无论是否用于商业目的。它唯一禁止的是将 tubekit 本身作为竞争产品或服务提供给他人。每个版本发布两年后,还会自动且不可撤销地转为纯 MIT 许可证。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。