MCP YouTube Transcript
An MCP server retrieving transcripts of YouTube videos
作者提供的说明(英文原文)
Check a social post against a platform's real character limit: X, Bluesky, LinkedIn, Threads.
这三项永远不会合并成一个分数:意见、测量和人气是不同的东西。
我们还没有为它写通俗的介绍。下面是我们从注册中心读取到的事实。
选择你使用的 AI 应用,然后复制设置。
你需要
你用的是哪个应用?
在上方选择你的应用。我们会记住它,下次按钮会显示“安装到 …”。
打开 Claude Desktop → Settings → Developer → Edit Config,把下面的内容粘贴到 claude_desktop_config.json
{
"mcpServers": {
"postlint": {
"command": "npx",
"args": [
"-y",
"@conorbronsdon/postlint-mcp"
]
}
}
}在终端中运行这条命令
claude mcp add postlint -- npx -y @conorbronsdon/postlint-mcp粘贴到项目中的 .cursor/mcp.json,或 ~/.cursor/mcp.json
{
"mcpServers": {
"postlint": {
"command": "npx",
"args": [
"-y",
"@conorbronsdon/postlint-mcp"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
粘贴到项目中的 .vscode/mcp.json
{
"servers": {
"postlint": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@conorbronsdon/postlint-mcp"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
这个服务器在你的电脑上运行,而 ChatGPT 只能连接互联网上的服务器。请选择其他应用。
你的选择通过 Cookie 保存在这台设备上,无需账户。
这些设置是根据作者在注册中心的条目生成的。如果 README 的写法不同,请以 README 为准。
它在你的电脑上运行;安装后,工具列表会显示在你的 AI 应用中。
我们检查的是任何人都能看到的信息;我们没有阅读代码。不适用的检查项不计入总数。 · 检查于 2026年11月7日
注册名称已通过 GitHub 账户 conorbronsdon 验证,该账户拥有此仓库
我们还没有从 GitHub 读取这个仓库
我们还没有从 GitHub 读取这个仓库
它在你的电脑上运行,没有互联网端点
在你的电脑上运行,改用本地设置
它在你的电脑上运行;我们只能读取互联网端点的工具列表
与注册中心里这个分类中所有活跃的服务器比较。只有当发布者拥有该仓库时,星标数才计入。
它在 1 项适用的基础检查中通过了 1 项。我们没有阅读代码。在添加密钥或令牌之前,请先看看这个服务器要求哪些权限,并使用只具备所需权限的密钥。
注册中心没有列出必需的密钥,不过有些服务器会在首次使用时要求你登录。
它在你的电脑上运行。你的 AI 应用会在需要时启动它,数据不会经过作者的服务器(除非它自己调用在线服务)。
GitHub 仓库最后更新于–,最新版本(1.1.0)于3个月前进入注册中心。
支持 MCP 的应用,例如 Claude Desktop、Claude Code、Cursor 和 VS Code。你的电脑上还需要有 Node.js。
同一分类中有:MCP YouTube Transcript, Google Analytics MCP, BibiGPT YouTube Video Summarizer
同一分类中其他作者的服务器,按星标数排序。
如何看卡片:★ GitHub 星标i三大支柱:评价 · 检查 · 使用情况i更新 = 最新版本发布到注册中心的时间i
An MCP server retrieving transcripts of YouTube videos
GA4 MCP server for AI agents: schema discovery, server-side aggregation, analysis-ready defaults.
AI video summarizer: summarize and transcribe YouTube, Bilibili, TikTok and podcast videos.
按原文从作者的仓库复制。PopNx MCP 没有审查或背书其内容。HTML、图片和脚本已被移除。链接会离开本站。
Maintenance mode. This project is stable and receives security fixes. New features aren't planned, but issues and pull requests are still welcome.
Check a social post against a platform's real character limit before it ships. X, Bluesky, LinkedIn, Threads, Mastodon, Discord. Pure compute — no API, no auth, no network.
Recorded from docs/demo.tape with vhs . The posts and counts come from scripts/fixtures.mjs , which the regression tests import too.
An MCP server that answers one question: does this post fit?
A language model cannot count characters by inspection, and on these platforms neither can you. The limits are not what they look like. X bills every URL at 23 characters through t.co whether the link is 12 characters or 200. Bluesky counts extended grapheme clusters, so a four-person family emoji is 1 and not 11. Mastodon charges nothing for the domain on a remote mention. Getting any of that wrong shows up as a rejected post, or a truncated one, at publish time.
Counting is what a tool call is for. The model cannot do it by inspection, and a deterministic function can do it exactly.
Why this exists. Two posts went out of a podcast promo workflow over the limit. A Bluesky post shipped at 302 against 300, with the line "Under 300 graphemes. Audit clean." sitting directly beneath it. An X post was drafted at 308 against 280 and would have been rejected on launch morning. Both were invisible to eyeballing, because in both cases the count was a claim and not a measurement. Both are regression tests in this repo.
| Tool | What it returns |
|---|---|
check_post | Verdict for one platform: counted length, the limit, headroom, and what drove the count |
check_post_all | One row per platform, with the breakdown attached only to the rows that fail |
platform_limits | Each platform's limit, its counting unit, why that unit is not a character count, and the source |
Responses are small on purpose. check_post_all omits the arithmetic on passing rows because agents pay tokens per response.
| Platform | Limit | Unit | The part that surprises people | Source |
|---|---|---|---|---|
x | 280 | weighted characters | Every URL costs exactly 23. CJK, Hangul, and emoji cost 2 each; Latin, Greek, Cyrillic, Hebrew, and Arabic cost 1. An emoji sequence is one unit of 2, not 2 per code point. | twitter-text v3 config |
x_premium | 25,000 | weighted characters | Same weighting, higher ceiling. | X help center |
bluesky | 300 | graphemes | Flags, ZWJ emoji, skin-tone modifiers, and combining accents each count as 1. URLs count in full. A second cap of 3,000 UTF-8 bytes can bind first on ZWJ-heavy text. | atproto lexicon |
linkedin | 3,000 | characters | The 3,000 is generous; the fold is the real constraint. The feed collapses the post behind "see more" after a few lines. | LinkedIn help |
threads | 500 | characters | The September 2025 change added a 10,000-character *attachment*. The post body is still 500. | Meta newsroom |
mastodon | 500 | graphemes | URLs cost 23, as on X. On @user@example.social only @user counts. The limit is per-instance and plenty of servers run higher. | Mastodon API docs |
discord | 2,000 | characters | 4,000 with Nitro. Embeds have a separate 6,000 total. | Discord support |
Every number above traces to a published source. Widely repeated figures that no primary source states — the Facebook post limit, the YouTube community post limit, Reddit's title cap, Instagram's organic caption cap — are deliberately absent. A limit that cannot be defended makes a passing check worth nothing.
Published on npm. The config blocks below use npx, which fetches it on first run; no clone required.
git clone https://github.com/conorbronsdon/postlint-mcp.git
cd postlint-mcp npm install npm run build
Add to your .mcp.json:
{
"mcpServers": { "postlint": { "command": "npx", "args": ["-y", "@conorbronsdon/postlint-mcp"] } } }
Same block, in claude_desktop_config.json.
Add to ~/.codex/config.toml:
[mcp_servers.postlint]
command = "npx" args = ["-y", "@conorbronsdon/postlint-mcp"]
No token, no environment variables, no network access. To run a local build instead, set command to node and args to the absolute path of dist/index.js in your clone.
Ask your assistant: "Check this post for X and Bluesky," and paste something with a couple of links in it.
The X post that started this, run through check_post with platform: "x":
{
"platform": "x", "limit": 280, "unit": "weighted characters", "length": 308, "over": true, "remaining": -28, "drivers": [ "3 URLs counted as 23 each = 69", "239 other characters counted as 1 each" ], "warnings": [] }
The drivers line is the useful part. 69 of the budget went to links before a word was written, which tells you to move two of them into a reply rather than trimming prose.
The same post through check_post_all:
{
"fits": ["x_premium", "linkedin", "threads", "mastodon", "discord"], "over": ["x", "bluesky"], "rows": [ { "platform": "x", "length": 308, "limit": 280, "over": true, "drivers": ["3 URLs counted as 23 each = 69", "239 other characters counted as 1 each"] }, { "platform": "bluesky", "length": 330, "limit": 300, "over": true, "drivers": ["3 URLs counted in full = 91 (Bluesky does not shorten links)", "239 other graphemes"] }, { "platform": "mastodon", "length": 308, "limit": 500, "over": false, "remaining": 192 } ] }
One post, three different lengths — 308, 330, and 308 again — from the same 330 characters of text. That gap is the whole reason this exists.
Drafts carry link placeholders, and [URL] is five characters while a real link is not. A post measured with the placeholder in place and posted with the link filled in is a post measured wrong; one draft came in at 264 that way and posted at 282.
So [URL], [LINK], [YOUTUBE URL], [SUBSTACK URL], and similar are priced as a real link (a 28-character YouTube short link, the shortest thing normally posted) and the response carries a warning saying the count is a floor.
fetch, XMLHttpRequest, and WebSocket with throws and drives every tool, so a call added later fails CI instead of quietly making this sentence false.configuration.statuses.max_characters from the target server yourself.truncate_to helper was considered and left out. Cutting a post at a character offset splits URLs, breaks grapheme clusters, and lands mid-sentence, and cutting it at a "safe" boundary silently drops whichever clause happened to be last. Either way the tool would be deciding what the post says. It reports the number and leaves the edit to you.www.-prefixed hosts always match. A bare domain matches only on a common TLD (src/count.ts holds the list), where the real twitter-text implementation carries the full IANA registry. Write https:// in front of a link and the count is exact.npm install
npm run build npm test
Tests make no network calls, because the server makes none. The two historical over-limit posts are regression fixtures in src/__tests__/lint.test.ts, alongside grapheme cases for ZWJ family emoji, regional-indicator flags, skin-tone modifiers, combining accents, and CJK.
Issues and pull requests are welcome. A new platform needs three things: the limit, the unit it is measured in, and a published source. A new counting rule needs a test that fails without it. Numbers repeated by third parties are not sources.
Built and maintained by Conor Bronsdon. I host the Chain of Thought podcast, which covers AI infrastructure, developer tools, and how practitioners actually use this stuff. I built this after shipping two over-limit posts in a workflow that was supposed to catch them.
Companion tools:
More at chainofthought.show and on X.
*This is an independent personal project, not affiliated with, sponsored by, or endorsed by any company. All views expressed are my own.*
Apache-2.0