关于 facebook-mcp
facebook-mcp 是面向 Facebook Pages 的本地优先 TypeScript MCP 服务,由主页管理员使用自己的 Meta 开发者应用操作。它实现了发布、分析、审核、消息和可选广告控制,但尚未通过真实 Graph API 验证。
主要功能
- 01读取主页、帖子、Reels 和分析数据
- 02发布并安排主页内容
- 03审核评论并回复消息
- 04启用后查看和管理广告
- 05最小权限令牌与分级写入保护
适用场景
- 01安排 Facebook 主页帖子
- 02查看主页和帖子的表现
- 03处理评论和主页消息
- 04使用可选组件管理广告预算
MCP 相关
通过 stdio 向 MCP 客户端提供精选的 Facebook Pages 工具及可选广告工具。已实现的 Graph API 功能尚未在真实 Meta 账户上验证。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @ivanbaev/facebook-mcpFB_SYSTEM_TOKEN密钥System-user access token (Business Manager). Takes precedence over FB_ACCESS_TOKEN and FB_PAGE_TOKEN when several are set.FB_ACCESS_TOKEN密钥Primary user access token. At least one of FB_SYSTEM_TOKEN, FB_ACCESS_TOKEN or FB_PAGE_TOKEN must be set.FB_PAGE_TOKEN密钥Long-lived Page access token used as a fallback credential when no user or system-user token is configured. It belongs to exactly one Page, so set FB_PAGE_ID to that Page ID alongside it (the doctor / facebook_whoami reports it as the acting Page); a Page token without its Page ID is bound to nothing.FB_APP_IDMeta app ID; combined with FB_APP_SECRET it forms the app access token used to authorize /debug_token inspection.FB_APP_SECRET密钥Meta app secret. When set, appsecret_proof is attached to every call so a stolen bare token cannot be used on its own.FB_PAGE_IDDefault Facebook Page ID, used when a tool call omits an explicit profile argument. Required when FB_PAGE_TOKEN is the only credential: it names the Page that token belongs to.FB_API_VERSIONGraph API version to target. Defaults to the tested pinned version; other values are accepted verbatim as an escape hatch but are not tested.FB_ADS_API_VERSIONMarketing API version the ads tools target (ad accounts, campaigns, ad sets, ads, insights, async reports). The Marketing API retires versions on its own, shorter schedule, so it is pinned separately from FB_API_VERSION. Other values are accepted verbatim as an escape hatch but are not tested.FB_REQUEST_TIMEOUT_MSPer-request timeout in milliseconds; integer in [1, 600000].FB_HOST_CONCURRENCYMaximum number of in-flight requests per Graph host; integer in [1, 64].FB_MAX_RESULT_CHARSCharacter budget applied by the result shaper before a tool result is truncated; integer in [500, 10000000].FB_WRITE_MODEWrite gating mode: plan (validating dry-run preview, the default) or apply. It never covers the irreversible and spend tiers, which always need a per-call apply plus a plan_id.FB_CONFIRM_TOKEN密钥Operator confirmation token for out-of-band approval of irreversible or spend actions. The server prompts through MCP elicitation where the client supports it; otherwise the caller passes this value as the confirm_token tool argument. At least 16 characters — a shorter value fails startup; mint one with openssl rand -hex 32.FB_MEDIA_DIRDirectory permitted for local media uploads. Unset means URL-only uploads and no local file access at all.FB_JOURNAL_PATHPath to the append-only write journal. Defaults to the XDG/%APPDATA% state path; the file is created owner-only (0600) and rotates by size.FB_ACTIVITY_STATE_PATHPath to the small JSON file where facebook_get_activity_since keeps, per Page, the horizon of the last complete read. Defaults to the XDG/%APPDATA% state path next to the journal; the file holds Page ids and timestamps only and is written atomically, owner-only (0600).FB_EXPORT_DIRDirectory where the insights tools write a CSV or JSON file when called with `output`. Defaults to `exports/` under the XDG/%APPDATA% state path. Files are written atomically and owner-only (0600) and are never overwritten; a name collision gets a numeric suffix.FB_TOOL_PACKAGESComma-separated tool packages or profiles to expose (e.g. core,posts,reader, or the profiles core|all|reader|publisher|moderator|ads). Omit for the default profile, which excludes ads.FB_PACKAGES_DENYComma-separated packages OR profiles to exclude even when FB_TOOL_PACKAGES enables them; deny wins over allow. Profile names expand here exactly as they do in FB_TOOL_PACKAGES, and a profile beats a same-spelled package, so FB_PACKAGES_DENY=core denies the whole six-package core profile rather than the single core package. The core package is then forced back on regardless, because its identity and diagnostic tools are what you need to debug the surface you just narrowed. An unrecognized name is a startup error, not a silently ignored token.FB_PACKAGES_READONLYComma-separated packages OR profiles whose write tools are not registered at all; the read tools of those packages stay available. Profile names expand as they do in FB_TOOL_PACKAGES, so FB_PACKAGES_READONLY=core makes every default package read-only in one token. An unrecognized name is a startup error.FB_TRANSPORTTransport protocol: stdio (default) or http. The http transport binds 127.0.0.1 only and fails closed without FB_HTTP_TOKEN.FB_HTTP_TOKEN密钥Bearer token guarding the HTTP transport; required when FB_TRANSPORT=http (the server refuses to start without it). At least 16 characters — a shorter value is refused (under stdio it is dropped with a warning); mint one with openssl rand -hex 32.FB_HTTP_PORTPort for the HTTP transport (loopback only); used when FB_TRANSPORT=http. Integer in [1, 65535].FB_AD_ACCOUNT_IDDefault ad account ID (act_… or the bare numeric id) for the opt-in ads package.FB_ADS_BUDGET_CEILINGHard ceiling for any ads budget write, in minor units of the ad account's own currency (e.g. cents for USD). Non-negative integer; a write above it is refused. No currency conversion: size it for the account's currency (1000 is $10 but only 1000 JPY).FB_ADS_CAMPAIGN_SPEND_CAP_MAXLargest campaign spend_cap (the lifetime total a campaign may spend) that an ads write may set, in minor units of the ad account's own currency. Non-negative integer; a cap above it is refused, never clamped. Unset: every write that sets a campaign spend cap is refused. No currency conversion, same as FB_ADS_BUDGET_CEILING.FB_LOG_LEVELStderr log verbosity: debug, info, warn or error. Logs never go to stdout — that is the stdio protocol channel.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
facebook-mcp — Facebook Pages MCP 服务
📖 文档网站 →
一个本地优先的 TypeScript 模型上下文协议 (MCP)服务,用于 Meta Graph API,专注于 Facebook Pages—— 发布、读取与洞察,以及评论/消息审核——通过 MCP 客户端(Claude、VS Code、Inspector 等)驱动, 并由 Page 管理员使用自己的 Meta 开发者应用在本地运行。采用最小权限令牌、先规划后应用的写入安全机制,且不进行遥测。
🚧 状态:pre-1.0,正在积极开发。 已发布到 npm,包名为
@ivanbaev/facebook-mcp——版本号本身就是警告。七个工具包均已实现——具体功能请参阅工具表。目前尚未针对真实的 Graph API 验证任何功能。 本仓库中的所有测试都通过伪造对象和已记录的测试固件运行,并受到网络隔离机制保护;只要发出真实的
fetch请求,机制就会抛出错误。因此,“测试通过”意味着“代码的行为符合测试固件所述”,而非“Meta 已接受”。我们提供了真实环境冒烟测试工具(scripts/smoke/),但尚未在任何已发布版本的开发过程中针对真实 Page 运行过。请将以下所有功能视为已实现但未经验证,并预期在 1.0 之前会有不兼容变更;依赖任何功能之前,请先阅读已知限制。
目录: 功能 · 要求 · 设置 · 客户端兼容性 · 配置凭据 · 所需权限 · 工具 · 对比 · 已知限制 · 不在范围内 · 你的责任 · 路线图 · 安全说明 · 文档 · 支持 · 商标 · 许可证
功能
仅说明实现状态——有关“已实现”的含义及其不代表的内容,请参阅上方的状态说明。
| 区域 | 功能 | 状态 |
|---|---|---|
| 核心与诊断 | 身份信息、主页列表、速率限制用量、doctor 上线前检查 | ✅ 已实现,未经实时验证 |
| 读取 | 主页和帖子读取、Reels、互动、游标分页 | ✅ 已实现,未经实时验证 |
| 发布 | 文本 / 链接 / 照片 / 视频 / Reels 帖子、排期、编辑和删除 | ✅ 已实现,未经实时验证 |
| 洞察 | 主页和帖子洞察、扁平行 + 按指标汇总、支持弃用感知 | ✅ 已实现,未经实时验证 |
| 审核 | 评论读取、回复、隐藏 / 删除、私密回复、屏蔽 / 解除屏蔽 | ✅ 已实现,未经实时验证 |
| 消息 | 读取对话并在 24 小时窗口内回复 | ✅ 已实现,未经实时验证 |
| 广告 | 读取广告系列 / 广告组 / 广告、洞察、状态和预算控制 — 默认关闭 | ✅ 已实现,未经实时验证 |
| 实时验证 | 使用真实主页和真实广告账户测试每个工具 | ❌ 尚未完成 — 请参阅状态说明 |
| npm / MCPB 发布 | npx @ivanbaev/facebook-mcp、认证包、注册表条目 | ✅ 已发布 — 0.7.0 |
默认配置文件提供经过精心筛选且刻意精简的工具集——每个工具都封装一项实际功能,而非映射每个 Graph API 端点。
- 本地优先,无遥测。 只会访问三个 Meta 主机
(
graph、graph-video、rupload);不会向外发送任何数据。 - 遵循最小权限原则的凭据。 支持永不过期的系统用户令牌 (Business Manager)或长期有效的主页令牌——管理员管理自己的资产无需经过应用审核。
- 安全写入。 采用分层的计划和应用门控;不可逆操作和支出操作 需要通过带外方式确认,且绝不会通过环境变量标志绕过。
- 密钥管理。 在单一关键节点按值脱敏,覆盖日志、 错误、工具结果和写入日志。
- 分层架构。 由 Lint 强制执行
core ← api ← mcp ← tools分层, 工具以数据形式组织,并通过中央包注册表管理。
要求
- Node.js ≥ 22(由
engines和启动器中的运行时检查强制执行; 项目使用.nvmrc中指定的版本)。 - Meta(Facebook)开发者应用——Business 类型应用达到标准访问权限 即可;管理自己的资产无需经过应用审核。
- 由你管理的 Facebook 主页(如需使用选择启用的
ads包,还需 广告账户)。
设置
首次运行分为以下 5 个步骤,请按顺序执行。预留约 20 分钟;大部分时间会花在 Meta 的应用界面上。docs/runbooks/onboarding.md 提供了详细说明和故障排查方法。
-
Meta 应用 — 在 https://developers.facebook.com/apps 创建一个 Business 类型的应用,并记下 App ID 和 App Secret(Settings → Basic)。
setup-token需要这两项信息。 -
短期令牌 — 在 Graph API Explorer 中选择你的应用、选择 User Token,勾选所需的权限范围(至少包括
pages_show_list和pages_read_engagement),然后点击 Generate Access Token。令牌有效期为 1–2 小时,因此请立即执行第 3 步。 -
交换令牌并写入环境文件 —
setup-token会将令牌换成有效期约为 60 天的令牌,解析你的 Page 并写入环境文件:FB_APP_ID='<app id>' FB_APP_SECRET='<app secret>' \ FB_SETUP_TOKEN='<explorer token>' \ npx -y @ivanbaev/facebook-mcp setup-token如果 Run 区块中显示
status: completed,且 Env file 区块中显示status: written,则表示成功。文件会写入~/.config/facebook-mcp/.env(如果已设置$XDG_CONFIG_HOME,则写入该目录)或 Windows 上的%APPDATA%\facebook-mcp\.env,文件权限为0600。服务每次启动时都会读取该文件,因此下面的客户端配置无需添加env区块。有多个 Page?重新运行并添加--page=<id> --force。 -
预检 — 计划使用的每个 package 都应显示为
usable:npx -y @ivanbaev/facebook-mcp doctor -
在客户端注册服务并发起首次调用 — 请参阅接下来的两个小节,然后让客户端 "run facebook_whoami"。回复中指出令牌类型和 Page,即表示首次工具调用成功。
doctor 和 setup-token 报告中列出的命令会采用你启动服务时使用的形式(npx -y @ivanbaev/facebook-mcp …、全局安装后使用的 facebook-mcp …,或从源码检出目录运行的 node build/index.js …)。--help 输出的命令形式为 facebook-mcp …;请替换为你实际使用的启动形式。每个子命令都支持 --help,且不会访问网络。
(a) 使用 npx
Claude Code — 运行一条命令,然后在会话中检查 /mcp:
claude mcp add facebook -- npx -y @ivanbaev/facebook-mcp
默认情况下,它会为当前项目目录注册;添加 --scope user 即可在所有位置使用。或者将其安装为插件,插件会配置相同的命令:
/plugin marketplace add IvanBBaev/facebook-mcp
/plugin install facebook-mcp
Claude Desktop — Settings → Developer → Edit Config 会打开 claude_desktop_config.json(macOS:
~/Library/Application Support/Claude/,Windows:%APPDATA%\Claude\)。添加服务并保存,然后退出并重启 Claude Desktop:
{
"mcpServers": {
"facebook": {
"command": "npx",
"args": ["-y", "@ivanbaev/facebook-mcp"]
}
}
}
Claude Desktop 不会加载你的 shell 配置文件。如果 Node 来自版本管理器(nvm、fnm、asdf),且服务无法启动,请将 npx 的绝对路径(which npx)填入 command。
其他任何 stdio 客户端都使用相同的 command / args 配置 — 请参阅客户端兼容性。
Claude Desktop 安装包(替代方式) — 双击最新版本中附带的 .mcpb 即可安装。其设置表单会将所有凭据列为可选项:留空即可使用第 3 步生成的环境文件(空白字段不会覆盖该文件)。该安装包附带构建来源证明,你可以在安装前验证它确实由此代码库的工作流生成:
gh attestation verify facebook-mcp-0.7.0.mcpb --repo IvanBBaev/facebook-mcp
(b) 从源码运行
用于开发,或运行尚未发布的提交版本:
git clone https://github.com/IvanBBaev/facebook-mcp.git
cd facebook-mcp
npm install
npm run build
node build/index.js setup-token # with the same FB_* variables as step 3
node build/index.js doctor # pre-flight: token, scopes, package matrix
node build/index.js # or: ./bin/facebook-mcp.mjs
使用绝对路径,将 MCP 客户端指向该命令。env 区块为可选项 — 不添加时,服务会读取环境文件;如果此处的值非空,则会覆盖文件中的值:
{
"mcpServers": {
"facebook": {
"command": "node",
"args": ["/absolute/path/to/facebook-mcp/build/index.js"],
"env": { "FB_SYSTEM_TOKEN": "…", "FB_PAGE_ID": "…" }
}
}
}
客户端兼容性
这是一个标准的 stdio MCP 服务,不包含针对特定客户端的代码,因此只要客户端支持该协议,理论上就能使用。**“理论上”是关键:**下表记录了各客户端所需的配置,以及该配置路径是否经过实际测试——这并非承诺。
| 客户端 | 注册方式 | 已验证? |
|---|---|---|
| Claude Desktop | claude_desktop_config.json → mcpServers,或使用 .mcpb bundle | ❌ 尚未验证 — bundle 从未完成端到端安装 |
| Claude Code | claude mcp add,或使用本仓库中的插件市场 | ❌ 尚未验证 |
| VS Code (Copilot Chat / agent) | .vscode/mcp.json → servers | ❌ 尚未验证 |
| Cursor | ~/.cursor/mcp.json → mcpServers | ❌ 尚未验证 |
| Windsurf, Zed, Cline, … | 任何支持 stdio JSON-RPC 的客户端 | ❌ 尚未验证 |
| MCP Inspector | 将其指向 node build/index.js | ❌ 尚未验证 |
以下内容已经通过自动化测试验证:
- stdio 帧处理 — 测试会将构建好的服务作为真实子进程启动,通过管道完成完整的
initialize→tools/list→tools/call握手,并断言 stdout 仅包含协议帧(所有日志都输出到 stderr)。 - 工具契约 — 每个工具的输入/输出架构、注释、写入级别和错误映射,均使用模拟对象和记录的测试固定数据进行了单元测试。
- HTTP 传输 — 回环绑定、Bearer 令牌拒绝和会话处理,同样针对真实的本地服务进行了测试。
这些测试均未涉及 MCP 客户端或 Meta API。如果你成功在某个客户端中使用了它,请在 issue 中告知我们——这样我们就能将表格中的状态更新为 ✅。
平台说明
CI 会在 Linux(Node 22/24/26)和 Windows(Node 22)上运行完整检查。macOS 是主要开发平台,但不在 CI 中。环境文件、写入日志和 FB_MEDIA_DIR 的路径在 POSIX 上遵循 XDG,在 Windows 上遵循 %APPDATA%。
配置凭据
facebook-mcp 使用你已掌控的令牌进行身份验证——无需 App Review、OAuth 回调服务或托管组件。请提供以下令牌变量中的至少一个;优先使用范围最具体的变量(FB_SYSTEM_TOKEN → FB_ACCESS_TOKEN → FB_PAGE_TOKEN):
FB_SYSTEM_TOKEN— 永不过期的系统用户令牌(Business Manager)。推荐使用:它不会过期,且仅限于分配给它的资产。FB_ACCESS_TOKEN— Meta 用户访问令牌(建议使用长期有效的令牌)。FB_PAGE_TOKEN— 长期有效的主页令牌,适用于没有 Business Manager 的情况。它只属于一个主页,因此需同时将FB_PAGE_ID设为该主页的 ID(doctor/facebook_whoami会将其报告为当前操作的主页)。
只授予你启用的软件包实际需要的权限(完整列表见下文),并设置 FB_APP_SECRET,确保每次调用都会附带 appsecret_proof——这样,即使裸令牌被盗,也无法单独使用。设置会从 XDG/%APPDATA% 配置路径中的环境文件读取,也可以从实际环境变量读取(环境变量优先)。
如果您不想手动组装 env 文件,可以运行
npx -y @ivanbaev/facebook-mcp setup-token(从源码运行 node build/index.js setup-token)——引导流程会交换并分类令牌,然后为您写入 env 文件(使用 --page=<id>、--env-file=<path>,使用 --force 覆盖,使用 --no-write/--dry-run 预演;通过 FB_SETUP_TOKEN 传入令牌,不要在命令行中传入;交换还需要 FB_APP_ID 和 FB_APP_SECRET)。完整操作流程请参阅
docs/runbooks/onboarding.md。
然后先运行 doctor(npx -y @ivanbaev/facebook-mcp doctor),再进行其他操作:它会检查令牌、报告类型、过期时间和已授予的权限范围,并输出逐个软件包的可用 / 部分可用 / 受阻矩阵,让您在调用工具前就能发现缺少的权限。最后,它会用一行给出对所有检查结果的判定。
doctor 只会生成报告,因此无论发现什么都会以状态码 0 退出——将它的文本输出传给其他命令的包装器仍可正常工作。添加 --strict 可让它充当门禁:
| 判定 | 使用 --strict 时 | 含义 |
|---|---|---|
OK | 状态码 0 | 无需处理。 |
WARN | 状态码 1 | 服务仍会运行,但有些方面已降级(权限范围不完整、令牌即将过期、env 文件可被所有人读取,或 Graph 不再接受的指标名称)。 |
UNKNOWN | 状态码 1 | 无法完成某项检查——通常是无法连接 debug_token,因此凭据尚未验证,而非无效。 |
FAIL | 状态码 2 | 此配置无法处理请求:没有令牌、令牌被 Graph 拒绝、资产访问权限已撤销,或没有可用的软件包。 |
UNKNOWN 会有意优先于 WARN:“尚未确定任何结果”不应被“已降级”掩盖。不支持 POSIX 权限位的平台不会对凭据文件报告问题——那里无法建议使用 chmod,而无法消除的警告会导致 Windows 上的 --strict 永远显示失败。
node build/index.js --version(或 -v)会在一行中打印服务、Node 和 MCP SDK 的版本,然后退出——它不需要凭据,因此即使安装无法启动,仍会给出响应:
facebook-mcp 0.7.0 (node v22.23.0, darwin arm64, sdk 1.30.0)
裸服务版本始终是第二个字段,因此 --version | awk '{print $2}' 仍可正常工作。facebook_whoami 也会在其 server 对象(name、version、apiVersion、sdkVersion)中报告相同的三个版本以及固定的 Graph API 版本。--help(或 -h)会向标准输出打印命令摘要和首次运行指南,然后以状态码 0 退出,同样不会读取任何凭据;setup-token --help 和 doctor --help 也会这样做,而不会执行命令。doctor、setup-token、--version 和 --help 是唯一会自行退出的参数;其他任何参数都会启动 stdio 服务,并等待 JSON-RPC。doctor 无法识别的参数(例如 --stric)不会启用门禁,但报告会列出该参数——只列选项名称,不列值——这样在 CI 中输入错误的 --strict 就能被发现。
环境变量
至少提供一个令牌;其他所有变量都用于可选调优。标记为 机密 的变量绝不会被记录日志或由工具返回。
| 变量 | 必需 | 默认值 | 说明 |
|---|---|---|---|
FB_SYSTEM_TOKEN | 三选一¹ | — | 机密。 系统用户令牌(Business Manager)。推荐使用;优先于另外两个令牌。 |
FB_ACCESS_TOKEN | 三选一¹ | — | 机密。 Meta 用户访问令牌(建议使用长期令牌)。 |
FB_PAGE_TOKEN | 三选一¹ | — | 机密。 长期 Page 令牌——无 Business Manager 时的备用方案。该令牌仅属于一个 Page:请同时将 FB_PAGE_ID 设为该 Page,否则任何限定 Page 的工具都无法使用它。 |
FB_APP_ID | 否 | — | Meta 应用 ID。与 FB_APP_SECRET 配合使用可组成用于检查令牌的应用令牌。 |
FB_APP_SECRET | 否 | — | 机密。 设置后会附加 appsecret_proof,使被盗取的裸令牌无法使用。 |
FB_PAGE_ID | 否 | — | 调用未提供 profile 时,供限定 Page 的工具使用的默认 Page ID。若 FB_PAGE_TOKEN 是唯一凭据,则必须设置此项(用于指定令牌所属的 Page)。 |
FB_API_VERSION | 否 | v26.0 | 固定使用的 Graph API 版本。接受非默认值,但仅测试默认值。 |
FB_ADS_API_VERSION | 否 | v26.0 | 广告工具使用的 Marketing API 版本(生命周期独立于 FB_API_VERSION)。接受非默认值,但仅测试默认值。 |
FB_REQUEST_TIMEOUT_MS | 否 | 60000 | 每个请求的超时时间,单位为毫秒(1–600000)。 |
FB_HOST_CONCURRENCY | 否 | 4 | 每个 Graph 主机的最大并行请求数(1–64)。 |
FB_MAX_RESULT_CHARS | 否 | 25000 | 工具结果截断前的字符数上限(500–10000000)。 |
FB_WRITE_MODE | 否 | plan | plan(默认)会预览写入操作但不进行修改;apply 会执行操作。始终不适用于不可逆操作/支出层级。 |
FB_CONFIRM_TOKEN | 否 | — | 机密。 用于授权受限写入/支出操作的带外确认令牌,适用于无法提示用户的客户端。至少 16 个字符。 |
FB_MEDIA_DIR | 否 | — | 允许用作本地媒体上传来源的目录。未设置 ⇒ 仅允许 URL,禁用本地文件访问。 |
FB_JOURNAL_PATH | 否 | XDG / %APPDATA% 状态路径 | 仅追加、循环轮转的写入日志路径(0600)。 |
FB_TOOL_PACKAGES | 否 | 核心配置(除 ads 外的所有包) | 以逗号分隔的要启用的包或配置。始终强制启用 core;ads 为可选启用。 |
FB_PACKAGES_DENY | 否 | — | 即使 FB_TOOL_PACKAGES 已启用,也要排除的包或配置;core 包始终保留。 |
FB_PACKAGES_READONLY | 否 | — | 不注册其写入工具的包或配置;其读取工具仍可用。 |
FB_TRANSPORT | 否 | stdio | stdio(默认)或 http(供本地 Agent 客户端使用、仅限环回地址的 Streamable HTTP)。 |
FB_HTTP_TOKEN | http 时必需 | — | 机密。 http 传输所需的 Bearer 令牌;未设置时将拒绝所有请求。至少 16 个字符。 |
FB_HTTP_PORT | 否 | 3000 | http 传输的 TCP 端口(绑定主机固定为环回地址 127.0.0.1)。 |
FB_AD_ACCOUNT_ID | 否 | — | 可选启用的 ads 包所用的广告账户 ID。 |
FB_ADS_BUDGET_CEILING | 否 | — | 广告写入的硬性预算上限,单位为广告账户货币的最小单位(非负整数,不进行货币换算)。 |
FB_LOG_LEVEL | 否 | info | Stderr 日志详细级别:debug、info、warn、error。 |
FB_SETUP_TOKEN | 否 | — | 机密。 由 setup-token 一次性使用的短期用户令牌;比将其作为 CLI 参数传递更安全。 |
FB_PROFILE_<NAME>_PAGE_ID | 否 | — | 命名配置的 Page ID,例如 FB_PROFILE_BRAND_A_PAGE_ID。 |
FB_PROFILE_<NAME>_TOKEN | 否 | — | 机密。 可选的配置专用令牌覆盖值,与对应的 FB_PROFILE__PAGE_ID 匹配。 |
¹ 至少提供 FB_SYSTEM_TOKEN、FB_ACCESS_TOKEN 或 FB_PAGE_TOKEN 中的一项。 | |||
完整的注释模板位于 .env.example。 |
需要授予的权限
仅授予你实际启用的包所需的权限。以下范围是此服务请求的权限;node build/index.js doctor 会将它们与你的令牌实际拥有的权限进行比对,并输出各包可用/部分可用/受限的矩阵。business_management 不在此列表中——它仅用于设置,不应随运行时令牌一起使用。
| 包 | 所需的 Graph 权限 |
|---|---|
core | pages_show_listpages_read_engagement |
reader | pages_read_engagementpages_read_user_content |
posts | pages_manage_postspages_read_engagement |
insights | read_insights |
moderation | pages_read_engagementpages_read_user_contentpages_manage_engagementpages_messaging |
messages | pages_messagingpages_manage_metadata |
ads | ads_readads_management |
各工具的权限范围(标记为 继承 的工具没有更细粒度的映射,将使用其所属包的权限范围)
| 工具 | 所需的 Graph 权限 | | ------------------------------- | --------------------------------------------------------------------- | | `facebook_whoami` | _(无——令牌本身即可)_ | | `facebook_list_pages` | `pages_show_list` | | `facebook_get_page` | `pages_read_engagement` | | `facebook_usage` | _(无——令牌本身即可)_ | | `facebook_list_posts` | `pages_read_engagement` | | `facebook_get_post` | `pages_read_engagement` | | `facebook_list_reels` | `pages_read_engagement` | | `facebook_get_reactions` | `pages_read_engagement` | | `facebook_create_post` | `pages_manage_posts` | | `facebook_create_photo_post` | `pages_manage_posts` | | `facebook_create_video_post` | `pages_manage_posts` | | `facebook_create_reel` | `pages_manage_posts` | | `facebook_update_post` | `pages_manage_posts` | | `facebook_delete_post` | `pages_manage_posts` | | `facebook_list_scheduled_posts` | `pages_read_engagement` | | `facebook_get_video_status` | `pages_read_engagement` | | `facebook_page_insights` | `read_insights` | | `facebook_post_insights` | `read_insights` | | `facebook_reel_insights` | `read_insights` | | `facebook_list_comments` | `pages_read_engagement`、`pages_read_user_content` | | `facebook_get_comment` | `pages_read_engagement`、`pages_read_user_content` | | `facebook_reply_to_comment` | `pages_manage_engagement` | | `facebook_hide_comment` | `pages_manage_engagement` | | `facebook_delete_comment` | `pages_manage_engagement`、`pages_read_user_content` | | `facebook_private_reply` | `pages_messaging`、`pages_read_engagement`、`pages_read_user_content` | | `facebook_block_user` | `pages_manage_engagement` | | `facebook_unblock_user` | `pages_manage_engagement` | | `facebook_list_conversations` | `pages_messaging`、`pages_manage_metadata` | | `facebook_get_conversation` | `pages_messaging`、`pages_manage_metadata` | | `facebook_send_message` | `pages_messaging` | | `facebook_list_campaigns` | `ads_read` | | `facebook_list_adsets` | `ads_read` | | `facebook_list_ads` | `ads_read` | | `facebook_get_ad_object` | `ads_read` | | `facebook_ads_insights` | `ads_read` | | `facebook_ads_report_status` | `ads_read` | | `facebook_update_ad_object` | `ads_management` |工具
软件包是暴露功能的基本单位:你可以通过
FB_TOOL_PACKAGES 启用和禁用整个软件包,而 FB_PACKAGES_READONLY 会移除软件包的写入工具,
同时保留其读取工具。
这三个软件包变量共用一个命名空间,其中包含软件包和配置组
(core、all、reader、publisher、moderator、ads),而配置组名称的优先级高于同名软件包。这个规则在 FB_PACKAGES_DENY 中尤为重要:
FB_PACKAGES_DENY=core 禁用的是包含六个软件包的core 配置组,而不是单个
core 软件包——并且随后会强制重新启用 core 软件包,因为它的身份和速率限制工具能够帮助你诊断刚刚收窄的功能范围。
如果名称无法识别,启动时会报错,而不会忽略该名称。
| 软件包 | 默认启用 | 工具 | 默认写入模式 | 覆盖范围 |
|---|---|---|---|---|
core | 是 | 4 个读取工具 | — | 始终启用的身份、主页发现和速率限制诊断(只读)。 |
reader | 是 | 4 个读取工具 | — | 只读访问主页自身内容:帖子(四种边缘)、单篇帖子、Reels 和表情回应总数。 |
posts | 是 | 2 个读取工具 + 6 个写入工具 | plan | 发布、安排发布时间、编辑和删除主页帖子、照片、视频和 Reels(先规划:每次写入都会在执行前预览)。 |
insights | 是 | 3 个读取工具 | — | 主页、帖子和 Reel 成效数据:精简重塑的指标序列、汇总总数,以及 2025 年后的指标重命名指南(只读)。 |
moderation | 是 | 2 个读取工具 + 6 个写入工具 | apply | 读取和审核主页内容上的评论(列出、回复、隐藏、删除、私密回复),并维护被屏蔽用户列表。 |
messages | 是 | 2 个读取工具 + 1 个写入工具 | plan | 主页的 Messenger 对话:轮询收件箱、读取对话串(将不可信内容包装起来,附件以占位符表示),并在 24 小时窗口内发送一条私密回复。默认先规划。 |
ads | 否(需主动启用) | 6 个读取工具 + 1 个写入工具 | plan | Marketing API 访问:带投放状态信息的广告系列/广告组/广告列表、单个对象读取、通过异步报告任务获取成效数据,以及受计划控制的状态和预算管理。默认关闭。 |
7 个软件包共 37 个工具。 默认启用 6 个软件包;其余软件包需通过 FB_TOOL_PACKAGES 主动启用。read 等级绝不会修改数据。reversible 写入受 FB_WRITE_MODE 控制;irreversible 和 spend 还需要在每次调用时指定 apply,并提供刚刚运行预览时返回的 plan_id,仅靠环境变量绝不会解锁这些操作。
| Package | Tool | Tier | Purpose |
|---|---|---|---|
core | facebook_whoami | read | 报告已配置令牌对应的身份(类型、有效性、已授予的权限、到期时间),以及服务器、MCP SDK 和固定的 Graph API 版本。 |
core | facebook_list_pages | read | 列出运营者管理的 Facebook 公共主页(通过 /me/accounts):ID、名称、类别、已授予的任务,以及是否有可用的公共主页令牌。 |
core | facebook_get_page | read | 获取一个公共主页的元数据——名称、类别、关注者/粉丝数、发布状态和新版公共主页体验标记。 |
core | facebook_usage | read | 报告最新的 Graph 速率限制信号(X-App-Usage、X-Business-Use-Case-Usage、x-fb-ads-insights-throttle),以使用百分比表示,方便你在……之前降低请求频率。 |
reader | facebook_list_posts | read | 列出公共主页帖子,每次获取一页游标结果。 |
reader | facebook_get_post | read | 通过复合 ID(facebook_list_posts 返回的 "{page-id}_{post-id}")获取一条帖子。 |
reader | facebook_list_reels | read | 通过 /video_reels 边列出公共主页的 Reels——这是唯一可读取 Reels 的位置。 |
reader | facebook_get_reactions | read | 读取一条帖子上的回应:按回应类型(LIKE / LOVE / CARE / HAHA / WOW / SAD / ANGRY)汇总的 totals 映射、总体 total,以及回应用户列表。 |
posts | facebook_create_post | reversible | 创建公共主页帖子:纯文本、链接、多链接卡片轮播或多照片轮播。 |
posts | facebook_create_photo_post | reversible | 向公共主页发布一张照片,可选择添加说明、保存为草稿或设置定时发布。 |
posts | facebook_create_video_post | reversible | 向公共主页上传视频。 |
posts | facebook_create_reel | reversible | 通过三阶段上传(开始 → 传输 → 完成)发布 Facebook Reel,并显式指定 video_state:PUBLISHED、DRAFT 或 SCHEDULED。 |
posts | facebook_update_post | reversible | 编辑应用自身创建的公共主页帖子,或推进帖子经过定时发布生命周期。 |
posts | facebook_delete_post | irreversible | 永久删除应用自身创建的公共主页帖子——包括定时发布的帖子;这是取消定时帖子的唯一方式。 |
posts | facebook_list_scheduled_posts | read | 列出排队等待发布的公共主页帖子,每条均同时显示 UTC 时间和公共主页所在地时间的发布时间。 |
posts | facebook_get_video_status | read | 查询 Meta 流程中某个视频的状态:上传中、处理中、就绪或出错。 |
insights | facebook_page_insights | read | 以紧凑的扁平格式读取一个公共主页的 Graph 洞察数据:每个数据点的每项指标占一行({metric, date, value},按操作类型划分的指标另含 breakdown),以及一个…… |
insights | facebook_post_insights | read | 以与……相同的紧凑扁平格式读取一条已发布帖子的 Graph 洞察数据(post_media_view、post_clicks、post_reactions_by_type_total、视频指标等)。 |
insights | facebook_reel_insights | read | 从 /{video-id}/video_insights 读取一个 Reel 的 Graph 洞察数据——Reel 指标实际所在的边,facebook_post_insights 无法访问此处。 |
moderation | facebook_list_comments | read | 列出帖子、照片、视频或其他评论下的评论,默认按时间从新到旧排序。 |
moderation | facebook_get_comment | read | 通过 ID 读取一条评论,可选择包含其回复,并报告是否仍可发送私信回复(7 天窗口)。 |
moderation | facebook_reply_to_comment | reversible | 在评论下发布公开回复——所有能看到该讨论串的人都可见。 |
moderation | facebook_hide_comment | reversible | 一次调用隐藏或取消隐藏最多 50 条评论(hidden:true 表示隐藏,hidden:false 表示恢复显示)。 |
moderation | facebook_delete_comment | irreversible | 永久删除最多 50 条评论。 |
moderation | facebook_private_reply | irreversible | 向评论作者发送私信。 |
moderation | facebook_block_user | reversible | 将最多 50 个 PSID 加入公共主页的屏蔽列表:他们将无法再评论或向该公共主页发送消息。 |
moderation | facebook_unblock_user | reversible | 从公共主页的屏蔽列表中移除最多 50 个 PSID,恢复其评论和发送消息的能力。 |
messages | facebook_list_conversations | read | 列出公共主页的 Messenger 对话(仅限 platform=messenger,绝不包括 Instagram 讨论串):ID、updated_time、unread_count、message_count 和最新消息摘要。 |
messages | facebook_get_conversation | read | 按消息从新到旧的顺序读取一个 Messenger 讨论串:发送者、时间戳、方向和正文,以及用于图片、贴纸、文件和共享链接的类型化占位符(附件……) |
messages | facebook_send_message | reversible | 以公共主页身份,在标准的 24 小时消息窗口内(messaging_type=RESPONSE)发送一条纯文本 Messenger 私信作为回复。 |
ads | facebook_list_campaigns | read | 列出一个广告账户下的广告系列,每次获取一页游标结果。 |
ads | facebook_list_adsets | read | 列出一个广告账户下的广告组,每次获取一页游标结果。 |
ads | facebook_list_ads | read | 列出一个广告账户下的单条广告,每次获取一页游标结果。 |
ads | facebook_get_ad_object | read | 通过 ID 读取一个广告系列、广告组或广告。 |
ads | facebook_ads_insights | read | 读取广告账户、广告系列、广告组或广告的效果数据(展示次数、点击次数、花费、覆盖人数、cpc、ctr)。 |
ads | facebook_ads_report_status | read | 查询一项异步洞察报告的运行状态,并在报告完成后通过 fetch_results:true 读取其数据行。 |
ads | facebook_update_ad_object | spend | 暂停或恢复广告对象,或更改其预算。 |
对比情况
截至 2026-07-21 的阶段性调查;完整分析见
docs/analysis/02-market-and-positioning.md。
| 项目 | 重点 | 语言 | 许可证 | 分发方式 | 备注 |
|---|---|---|---|---|---|
| facebook-mcp(本项目) | Pages/自然流量 + 广告 | TypeScript | MIT | npm + MCPB 包 | 多 Page、计划后应用写入、脱敏、MCP 注解和 outputSchema |
| Meta 官方托管 Ads MCP | 仅广告 | 托管 | Meta ToS | mcp.facebook.com/ads | Business OAuth,无需开发者应用,约 29 个工具。免费。 |
| pipeboard-co/meta-ads-mcp | 广告 | Python | BUSL-1.1 | 托管远程 | 市场领先者(约 1.1k ★),42 个工具。非 OSI 开源。 |
| HagaiHen/facebook-mcp-server | Pages | Python | MIT | 仅源代码 | 唯一另一个值得关注的 Pages 服务:27 个工具,单个 Page,没有测试。 |
如果你只需要广告,请使用 Meta 官方服务。 它免费、无需你自行创建开发者应用,由供应商维护,支持的广告功能也比本项目未来能提供的更多。这里的 ads 包存在的唯一原因,是让你能够在单个令牌和配置下,将广告与 Pages、内容审核和消息功能组合使用,并采用相同的支出限制。这就是它默认关闭的原因——广告不是安装本项目的理由。
安装本项目的理由在于 Pages 功能:支持多个 Page、上传视频和 Reels、管理定时帖子的完整生命周期、洞察数据会告知你某项指标何时更名或停用,以及评论和消息审核——这一切都由一个有类型定义、经过测试、采用 MIT 许可证,且完全在本地运行的服务提供。
已知限制
当前、客观,且刻意不加粉饰:
- 未对 Graph API 进行实时验证。 本文中的内容都未经 Meta 服务器验证。测试夹具记录的是 API 文档所述行为;实际情况仍有自己的说法。
- 已发布,但刚刚推出。 0.7.0 已发布到 npm,并带有来源证明;
.mcpb捆绑包已附加到此版本,MCP Registry 条目也已启用——但除了 CI 之外,还没有人从头到尾走过任何安装流程。各客户端的具体情况请参阅客户端兼容性。 - 无法提示用户的客户端需要操作员令牌。
irreversible和spend写入操作每次调用都需要apply和plan_id,还需要模型无法自行提供的带外确认。如果客户端声明了 MCPelicitation能力,服务会通过它向人工操作员请求确认;如果没有,调用方必须将FB_CONFIRM_TOKEN的值作为工具的confirm_token参数传入。两种方式都不可用时,这些工具会返回confirmation_denied。 - 上传进度取决于客户端是否请求。 分块视频和 Reels 上传会在每个分块完成后发出
notifications/progress,但前提是调用方按照 MCP 规范在请求中提供progressToken。不发送该值的客户端不会收到任何进度帧,长时间上传看起来就只是很慢。 - Insights 指标会发生变化。 Meta 分三轮(2024-09、2025-11 和 2026-06-15)停用了并重命名了大量 Page/帖子指标。Insights 工具会对请求的指标进行分类,并在指标被重命名或移除时告知你,而不是静默返回空结果——但底层数据丢失是 Meta 造成的,任何封装层都无法挽回。
- 消息受 Meta 24 小时窗口限制。 对于超过 24 小时没有互动的对话,必须带上消息标签才能回复,本服务不会对此进行规避。
- 单人维护,尚未达到 1.0。 在 1.0 之前,接口可能会在不设弃用期的情况下发生变化。
不在范围内
人们合理期待一个“Facebook MCP 服务”支持、但本服务不支持的功能。列出这些内容,是为了让你能在 30 秒内排除本服务,而不是安装之后才发现:
- 个人主页和 Groups。 没有可用于向个人时间线发布内容的 API,Groups API 已于 2024 年 4 月停用。本服务只处理 Pages,除此之外一概不支持。
- Instagram、Threads、WhatsApp。 产品和权限集都不同。未来可能会有配套服务,但不是本服务。
- Webhooks / 实时数据接入。 本地 stdio 服务没有可接收回调的公共 URL。读取采用轮询方式,这是有意设计。
- 推广自然帖子(
/{page-id}/promotions)。自然内容到广告的衔接是最受期待的跨功能需求,但有意留到 1.0 之后再处理——这需要广告包和经过周密设计的支出门控,而不是临时拼凑。 - Page Stories。 发布端点确实存在,但未经验证;1.0 不承诺支持 Stories,在实时运行验证通过之前都不会纳入。
- 活动、直播视频、相册/照片库读取、Page 资料编辑、自然帖子定向。 这些端点确实存在,但不属于本服务承诺支持的帖子 / 视频 / Reels / 排程 / 内容审核范围。
- 多租户或托管式运营、为其他企业提供广告账户服务。 本服务面向单个操作员,采用 Standard Access,使用自有资产和自有设备。其他任何模式都需要 App Review 和 Business Verification,属于另一种产品。
完整的设计依据见
docs/analysis/01-goals-and-scope.md。
作为运营者的责任
此服务会自动执行 Meta 归于你的操作,并使用你的应用和令牌。 自动执行这些操作并不意味着你可以不遵守相关规则:
- Meta 的平台条款和 开发者政策仍然适用—— 包括反垃圾信息和自动化行为规则。批量或重复发布内容、评论或发送消息, 可能导致主页受到限制或应用被停用;模型选择了操作时间,并不能成为辩护理由。
- 必须披露 Messenger 自动化。 Meta 希望用户知道自己正在与自动化系统对话。 如果你将消息工具接入并用来回复用户,请告知他们。
- 内容和同意由你负责。 工具会发布你指定的任何内容;确认你拥有相关权利—— 对于私密回复和私信,还要确认对方预期会收到联系——不是包装层能做到的事。
- 这不是法律建议。 这是诚恳的提醒:功能强大的自动化工具伴随着责任, 而本项目宁愿提前说明这一点。
安全方面的对应说明见
SECURITY.md。
路线图
工作进展在公开的 facebook-mcp 路线图看板 上跟踪,并按发布里程碑分组:
| 里程碑 | 范围 |
|---|---|
| v0.1.0 — 核心 | 基础功能 + core 工具、实时冒烟测试框架 |
| v0.2.0 — 读取与发布 | 帖子/Reels 读取、发布、定时发布、照片/视频/Reels 媒体 |
| v0.3.0 — 数据分析与审核 | 主页/帖子数据分析、评论审核、屏蔽 |
| v0.4.0 — 消息 | 对话和消息发送 |
| v1.0.0 — 稳定版 | 实时验证、元数据 SSOT、发布流程、npm 发布 |
| v1.1.0 — 广告 | 广告读取与控制、需主动启用且默认关闭 |
v1.0.0 不包含广告包——这是有意为之。主页功能是产品本身;广告功能需主动启用、
默认关闭,并将在 1.1.0 中推出。相关代码已经在工作树中,正因如此,该里程碑关注的是
验证,而非实现:只有当某项功能已通过 Meta 服务的实时验证并完成发布后,
里程碑才会关闭,而不是代码合入时。
具有约束力的版本映射见
docs/analysis/10-v1-release-definition.md。
每项工作的设计都会提前记录在
docs/analysis/ 中——路线图是这些文档的产物,
而非它们的替代品。
安全说明
- 三域名围栏。 只会联系
graph.facebook.com、graph-video.facebook.com和rupload.facebook.com——允许列表在代码中固定,无法由用户配置,因此重定向或输错的域名无法在不被察觉的情况下接收令牌。 - 通过计划与执行门控写入。 写入操作默认采用
plan(不会修改数据的预览);apply则会执行。例外是moderation,其默认采用apply,因为隐藏评论属于高频且可撤销的操作——FB_WRITE_MODE会直接覆盖任何软件包默认值,无论切换到哪个方向,因此模式由操作者决定,而非由单个工具承诺。模式无法绕过的限制:不可逆操作和付费操作始终需要通过带外方式确认;任何会触达真实受众的操作(发布帖子或 Reel、提前发布定时帖子、发送 DM)还必须提供与该次调用的预览绑定的plan_id。任何环境标志都无法绕过这些要求。 - 单点脱敏。 在任何内容进入日志、错误、工具结果或写入日志前,密钥值都会在同一处被剥除;Page 访问令牌会转换为布尔值,其值绝不会进入载荷。
- 无遥测,本地优先。 服务仅将日志写入
stderr,不收集任何信息,也不会向外部发送数据。http传输仅绑定到环回地址(127.0.0.1),且若未设置FB_HTTP_TOKEN,则会安全失败。
完整的安全模型和漏洞报告方式请参阅 SECURITY.md。
文档
- 设计资料集——完整的实现前分析位于
docs/analysis/:目标与范围、市场定位、 Graph API 概况、身份验证与安全模型、架构、工具目录、风险、 路线图、边缘情况、v1.0 发布定义,以及推动开发的并行任务拆分。 - 操作手册——操作流程见
docs/runbooks/。 - 错误目录——服务分类的所有 Graph 错误、是否会重试以及应如何处理:
docs/error-catalog.md。 - 文档网站——ivanbbaev.github.io/facebook-mcp。
上文中的环境变量表、软件包/工具表和权限表,以及错误目录,均由 npm run metadata 根据代码生成;如果内容不一致,CI 会报错。
支持
支持由单人维护者尽力通过 GitHub 提供——如何提交错误、功能请求和安全报告,请参阅 SUPPORT.md。
本项目由我利用个人时间构建和维护。如果它对你有帮助,打赏可以支持项目持续运行:
- GitHub Sponsors——可一次性或定期捐赠,无平台手续费。
- Ko-fi——便捷的一次性支持(也接受 PayPal);没有 GitHub 账户的用户可使用此方式。
- Donatree——在一个页面上提供所有捐赠方式,包括本地支付选项。
捐赠不会带来优先支持,也不提供 SLA——详情请参阅 SUPPORT.md。如果不方便捐款,给仓库点星或提交优质的错误报告,同样能提供帮助。
商标
这是一个独立的社区项目,与 Meta Platforms, Inc. 无关,也未获其认可或赞助。Facebook、Meta 及相关标志均为 Meta Platforms, Inc. 的商标,此处仅以指称方式使用,用于说明兼容性。
许可证
MIT © 2026 Ivan Baev
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。