npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thenavidm/facebook-mcp-cli

v0.3.0

Published

Facebook MCP server and CLI for Claude Code, Codex and AI agents. 15 tools for posting, scheduling, drafts, Page and post insights, and comment moderation through Meta's official Graph API.

Readme

Facebook MCP Server & CLI

npm License YouTube X LinkedIn

Facebook MCP server and CLI for Claude Code, Codex and AI agents. 15 tools for posting, scheduling, drafts, Page and post insights, and comment moderation through Meta's official Graph API.

One install gives you both surfaces, the same 15 tools under the same names, built from one definition of each by Slipway, so they cannot drift apart.

Setup needs a Meta developer app. There is no way around that: Facebook only issues Page tokens through an app you own. You create one once, generate a user token, and login exchanges it for Page tokens that never expire.

Pages only. Facebook removed personal profile posting from the API in 2018 and never replaced it, so no tool can do it, including this one.

Scheduling is real. Facebook holds the post and publishes it itself, so nothing has to be running on your machine at the time.

15 tools, across as many Pages as you administer.

Two ways to use it

Command line

facebook-cli runs every tool as a command. Agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job:

facebook-cli                                          # every command, one line each
facebook-cli list-pages                               # the Pages login stored
facebook-cli get-page --json
facebook-cli list-posts --agent
facebook-cli which post a photo                        # find the command for a task
facebook-cli <command> --help                         # what any command takes

--confirm is the shell spelling of the confirmation deleting needs. --json gives JSON, --compact puts it on one line, --select keeps only the fields you name, and --agent turns on all of it for a script. Exit codes are 0 ok, 1 unexpected, 2 usage or a refused write, 3 not found, 4 a token Meta refuses, 5 API, 7 rate limited and 10 no Page connected, so a script branches on the number.

facebook-cli schema <command> prints the exact JSON Schema an MCP client receives for that tool.

MCP server, for AI agents

facebook-mcp is what Claude Code, Claude Desktop, Cursor and the rest launch. You never run it by hand:

claude mcp add facebook -- npx -y @thenavidm/facebook-mcp-cli

In Claude Desktop, the .mcpb extension installs on a double click. Section 5 has every other client.

What each costs

Both surfaces are the same program with the same 15 tools. The difference is when the model pays for them. Measured in Claude Code:

| | MCP server | CLI | |---|---|---| | Every message, with every tool loaded | 1,200 tokens, or 2,700 with writes on | nothing | | Every message, Claude Code's default | 290 tokens, or 370 with writes on | nothing | | When Facebook comes up | nothing more, or the tools it picks | 1,500 tokens for SKILL.md, once | | 20 messages with Facebook in 1, every tool loaded | 24,000 tokens | 1,500 tokens |

Claude Code's tool search is on by default: it sends only the tool names and the server instructions, and loads a tool's full definition when the model reaches for it. An app that loads every tool up front pays the first line on every message, whether Facebook comes up or not. With the skill added, Claude Code also lists its one-line description, about 80 tokens.

To spend less, turn the server off when you are not using it, which in Claude Code is the /mcp panel. Or install the CLI and add the server on the days it earns its place.

A default install lists only the seven reads, which is why it costs less than one with writes on. Measured on 2026-10-05 against 0.2.0, with Claude Code 2.1.286 on Claude Opus 5.5 (one short prompt with and without the server connected, once with ENABLE_TOOL_SEARCH=false and once with the default, the difference read from the API's own usage figures; SKILL.md the same way) and Codex 0.159.3 on gpt-6.1-sol:

| Cost | 0.2.0 | 0.3.0 | | --- | --- | --- | | Claude Code, every tool loaded, every message | 3,120 | 1,176 | | The same, with writes and deletes on | 3,108 | 2,679 | | Claude Code's default, tool search, every message | 388 | 292 | | The same, with writes and deletes on | 374 | 374 | | SKILL.md, read once | 1,460 | 1,451 | | Codex over the CLI, one task, median of five | 90,223 | 71,276 | | Codex over MCP, the same task, median of five | 37,254 | 35,254 |

The task was "find the command that reports how one post performed, and the flags it requires". 0.2.0 listed every tool and refused writes when called, so with nothing set it cost what it did with writes on. Claude Code's default with writes on is the mean of six runs a side, which ranged from 370 to 377 tokens; its other figures are means of two. Other apps and models count tokens a little differently, and tool-list characters divided by four are not API usage.

Contents

| | Section | | |---|---|---| | 1 | What you can ask it | Real prompts, not features | | 2 | Quick install | One command | | 3 | Create your Meta app | The setup step there is no way around | | 4 | Get your token | And make it permanent | | 5 | Connect your client | Every client, copy and paste | | 6 | Check it worked | One command that says what is broken | | 7 | Tools | All fifteen | | 8 | Posting safely | Three levels, three switches | | 9 | Several Pages | Picking which one acts | | 10 | Limits worth knowing | What Facebook will not let you do | | 11 | Troubleshooting | When something breaks | | 12 | FAQ | Common questions |

1. What you can ask it 💬

  • Schedule this for Tuesday at 9am, and draft two alternatives I can pick from.
  • Which post this month got the most reach, and what was different about it?
  • Compare last week to the week before. Did the change in posting time help?
  • Read the comments on the last five posts and tell me what people keep asking.
  • Draft a reply to each comment that deserves one, in my voice. Do not post them.
  • Hide the spam on that post, but leave the criticism.
  • How many followers did I gain this month, and which day did most of it happen?

What this adds over Meta Business Suite, which already schedules posts:

Business Suite shows you numbers. It cannot answer a question about them. "Why did Thursday do four times better" needs someone to look at the posts, compare them, and form a view. That is the part a conversation does and a dashboard does not.

The second thing is that reading and acting happen in one place. You ask what worked, decide what to do about it, and schedule the follow-up without opening another tab or copying anything between windows.

What to do first, in order:

  1. Install it, one command, section 2
  2. Create a Meta app and connect your Page, sections 3 and 4. This is the part that takes ten minutes, and only once
  3. Point your client at it, section 5
  4. Ask it something read-only, like "how did my last five posts do"
  5. Turn on writing only once you trust what it is telling you

Reading works as soon as a Page is connected. Posting stays off until you set one environment variable, deliberately.

2. Quick install ⚡

npx -y @thenavidm/facebook-mcp-cli --version

Node 20 or newer. Nothing else to install.

That gets you the server. Connecting a Page is the next three sections, and it is the part that takes real time.

For the CLI as a command you or your agent can run anywhere, install it once:

npm install -g @thenavidm/facebook-mcp-cli
facebook-cli

3. Create your Meta app 🔑

Facebook has no app passwords and no personal tokens. Every credential comes through an app you own, so you make one once.

You do not need App Review, and you do not need Business Verification. Those are only for managing Pages belonging to other people, which Meta calls Advanced Access. For your own Pages, Standard Access is enough and it is granted the moment you ask.

[!TIP] One app covers Facebook, Instagram and Threads.

Use cases are ticked in a list, and you can tick several. If you plan to use more than one of these, do it now rather than making three apps and managing three sets of credentials.

| Use case | For | Server | |---|---|---| | Manage everything on your Page | Facebook Pages | this one | | Manage messaging and content on Instagram | Instagram | instagram-mcp | | Access Threads API | Threads | threads-mcp |

Incompatible combinations grey out. If an option will not tick, it conflicts with something already selected.

Step 1: the creation wizard

developers.facebook.com/apps/creation. Five screens, in this order.

App details. A name, up to 30 characters, and a contact email. The name is only shown on your own My Apps page and can be changed later.

Use cases. This is where people get stuck. The screen opens on Featured (6), and the Pages use case is not one of the six. Change the filter on the left to All (20) or Content management (5) to find it.

The featured six are Marketing API, app ads, Threads, Instant Games, Facebook Login and WhatsApp. None of those is what you want.

Business. Which business portfolio the app belongs to. An unverified one is fine, and "I don't want to connect a business portfolio yet" is a valid answer you can revisit. Verification is only needed to reach other people's data.

Requirements. For a Pages app on your own Pages this reads "No requirements identified". That is the screen confirming you do not need App Review.

Overview. Review and Create app.

Step 2: add the permissions by hand

Creating the app does not give you the permissions. This is the step every guide skips, and without it login will fail.

Open your app, click the use case in the left sidebar, then Permissions and features. You get a table of every permission that use case can grant, and almost all of them start unadded, showing a dash in the Status column.

Click + Add on each of these:

| Permission | What it is for | |---|---| | pages_show_list | Seeing which Pages you administer. Without it, login finds nothing | | pages_read_engagement | Reading posts, comments, followers and Page metadata | | pages_manage_posts | Creating, editing and deleting posts | | pages_manage_engagement | Replying to, hiding and deleting comments | | read_insights | Impressions, reach and engagement numbers |

Added permissions move to Ready for testing, which is the state you want. That is Standard Access, it is immediate, and nothing is reviewed.

Those five are what this server needs. The Pages API exposes far more, covering messaging, leads, monetization and ads, grouped by Meta into tasks like CREATE_CONTENT, MODERATE, ANALYZE and MESSAGING. Add more only if you have a reason, since each one widens what an agent holding the token can do.

There is also Add more to this use case in the sidebar, which widens what the use case can grant if something you need is not in the list.

[!TIP] The one people miss is pages_read_engagement. It reads like a write permission and is not. Leave it out and reading breaks while posting still works, which is a confusing way to fail.

Step 3: make sure you have an app role

Standard Access only works for people who hold a role on the app. As its creator you are automatically an admin, so this is usually already true and worth knowing rather than doing.

It matters when it is not you. Anyone else who wants to use your app, a colleague or a second account of your own, has to be added under App roles, then Roles, as an Administrator, Developer or Tester. Without a role they cannot grant the permissions at all, and Meta's error does not say why.

Test users live in the same place. They are throwaway accounts Meta generates for you, useful for trying a destructive tool without pointing it at a real Page. They cannot administer a real Page, so they are for testing the plumbing, not the content.

Business Verification is a separate thing again, and you do not need it here. It is required for Advanced Access, which is what you would need to manage Pages belonging to people who have no role on your app. For your own Pages, Standard Access is enough.

Step 4: check the Page is in the same portfolio

Your Page must belong to the business portfolio you attached to the app, or the app cannot see it and login reports no Pages.

Business settings, then Accounts, then Pages. If it is not listed, add it there first.

Rather have an agent do it

The steps above are written to be handed over. Paste this into Claude, or any agent with a browser:

Walk me through creating a Meta developer app for the Facebook Pages API. I need the "Manage everything on your Page" use case, Standard Access for pages_show_list, pages_read_engagement, pages_manage_posts, pages_manage_engagement and read_insights, and my Page linked to the same business portfolio. Tell me what to click, one step at a time, and wait for me to confirm each one.

4. Get your token 🔑

Generate one

  1. Graph API Explorer
  2. Pick your app, top right
  3. Under Permissions, add the five above
  4. Generate Access Token, and approve

That token dies in about an hour. It does not matter, it is used once.

Exchange it for Page tokens

npx @thenavidm/facebook-mcp-cli login <that token>

Writes ~/.facebook-mcp/pages.json, mode 600, one token per Page you administer.

Make them permanent

Left alone, those Page tokens expire with the user token they came from. That is the single most common reason this stops working the next day.

export FACEBOOK_APP_ID=...
export FACEBOOK_APP_SECRET=...
npx @thenavidm/facebook-mcp-cli login <that token>

Both are under Settings, then Basic in your app. With them, login extends the user token first, and the Page tokens it derives never expire.

One app also covers Instagram and Threads

The same Meta app can carry the Instagram and Threads permissions. If you plan to use those too, add their products now rather than making three apps.

5. Connect your client 🔌

Claude Code

claude mcp add --transport stdio facebook -- npx -y @thenavidm/facebook-mcp-cli

With posting allowed:

claude mcp add --transport stdio --env FACEBOOK_ALLOW_WRITE=true facebook -- npx -y @thenavidm/facebook-mcp-cli

Claude Desktop

The short way: download the .mcpb extension from the latest release and double-click it. It carries its own dependencies, so there is no config file to edit and nothing to install first. Run login from section 4 first, and the extension uses the Pages it stored.

The long way, if you would rather edit the config yourself:

| Platform | Path | |---|---| | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json |

{
  "mcpServers": {
    "facebook": {
      "command": "npx",
      "args": ["-y", "@thenavidm/facebook-mcp-cli"],
      "env": { "FACEBOOK_ALLOW_WRITE": "true" }
    }
  }
}

Quit Claude Desktop completely and reopen it.

Cursor

~/.cursor/mcp.json for every project, or .cursor/mcp.json inside one. Same shape as Claude Desktop.

VS Code with GitHub Copilot

.vscode/mcp.json. Note it uses servers, not mcpServers.

{
  "servers": {
    "facebook": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@thenavidm/facebook-mcp-cli"]
    }
  }
}

Windsurf, Zed, Cline, Codex CLI, Gemini CLI

All take the same stdio shape. Codex uses TOML:

[mcp_servers.facebook]
command = "npx"
args = ["-y", "@thenavidm/facebook-mcp-cli"]

Docker

docker build -t facebook-mcp .
docker run -i --rm -v facebook-mcp:/home/node/.facebook-mcp facebook-mcp

The volume matters. Page tokens live in the home directory, and without it every login is written into a container that is about to disappear.

6. Check it worked 🩺

npx @thenavidm/facebook-mcp-cli doctor

It names every Page it can reach, with follower counts. If something is wrong it says which link in the chain broke, because Meta's own error rarely does.

7. Tools 🧰

Fifteen. Each declares whether it reads or writes, so your client can show you before anything runs.

Scheduling is native: Facebook holds a scheduled post and publishes it itself, so nothing has to run on your machine at the time. Drafts are real drafts too.

Your Pages

| Tool | | | |---|---|---| | list_pages | read | Every Page this server can act as | | get_page | read | Name, category, followers, about, website |

Posting

| Tool | | | |---|---|---| | create_post | write | Text post, optionally with a link | | create_photo_post | write | Photo from a URL, with a caption | | publish_draft | write | Push a draft or scheduled post out now | | update_post | write | Edit the text of a published post | | delete_post | delete | Cannot be undone | | list_posts | read | Published posts with reaction, comment and share counts | | list_scheduled_posts | read | Scheduled and draft posts not yet out |

Comments

| Tool | | | |---|---|---| | list_comments | read | With author and time | | reply_to_comment | write | Public reply, as the Page | | hide_comment | write | Hide or unhide. Reversible | | delete_comment | delete | Cannot be undone |

Numbers

| Tool | | | |---|---|---| | get_page_insights | read | Impressions, reach, engagement, follower change | | get_post_insights | read | How one post did |

Scheduling and drafts

create_post covers three cases with one tool:

| Intent | Arguments | |---|---| | Post now | message | | Save a draft | message, draft: true | | Schedule | message, publish_at as an ISO timestamp |

Facebook requires 10 minutes to 6 months ahead. Its own error for breaking that says nothing useful, so this checks first and tells you which rule you hit.

8. Posting safely 🔒

A Page post is public the moment it lands. Deleting one cannot be undone. Two different risks, so two different switches.

Reading needs nothing.

Writing needs FACEBOOK_ALLOW_WRITE=true. Until it is set, posting, editing, replying and hiding are left off the tool list and refused if called anyway, so a default install cannot publish anything and an agent is not offered tools it cannot use. FACEBOOK_READ_ONLY=0 does the same, and FACEBOOK_READ_ONLY=1 turns writes off again whatever else is set.

Deleting needs FACEBOOK_ALLOW_DELETE=true as well, or FACEBOOK_ALLOW_DESTRUCTIVE=1, and then each delete asks first. Over MCP a person approves it: Claude Code (2.1.246 and later) shows its own prompt, and an app that can show forms asks with an approval form whose one box starts unticked. Where an app can do neither, the model's confirm: true still counts, and FACEBOOK_CONFIRM=model makes it enough everywhere. In a terminal it is --confirm, which --agent never adds.

Every write can be logged. Set FACEBOOK_AUDIT_LOG=/path/to/file and each attempt is appended as one JSON line, allowed or refused, with what it was about to do and who approved it, then whether it was done or failed. No tool can read or edit it, and a Page token never goes into it.

Comment text is labelled as data rather than instructions when handed to the model. Comments are written by strangers, and an agent that reads them and can also post is exposed to whatever they put there.

Settings

The program reads the environment directly. It does not load .env files.

| Variable | Default | Purpose | | --- | --- | --- | | FACEBOOK_ALLOW_WRITE | Off | true allows posting, editing, replying and hiding | | FACEBOOK_ALLOW_DELETE | Off | true allows deleting posts and comments, with writes on as well | | FACEBOOK_READ_ONLY | Read-only until writes are allowed | 0 allows writes, 1 turns them off whatever else is set | | FACEBOOK_ALLOW_DESTRUCTIVE | Off until deletes are allowed | 1 allows deleting, 0 refuses it whatever else is set | | FACEBOOK_CONFIRM | human | model lets confirm: true alone approve a delete over MCP, for an agent with no person to ask | | FACEBOOK_AUDIT_LOG | Empty | Append every attempted write to this file | | FACEBOOK_PAGES | Empty | Several Pages as a JSON array of {id, access_token, name}; login stores Pages instead | | FACEBOOK_PAGE_ID, FACEBOOK_PAGE_TOKEN | Empty | A single Page and its token | | FACEBOOK_PAGE_NAME | Empty | That Page's name, so it can be picked by name | | FACEBOOK_PREFERRED_PAGES | Empty | Comma-separated Page names, in the order that decides the default Page | | FACEBOOK_APP_ID, FACEBOOK_APP_SECRET | Empty | Your Meta app, so login stores Page tokens that do not expire | | FACEBOOK_TIMEOUT_MS | 30000 | How long to wait for the Graph API | | FACEBOOK_TOOLSETS, FACEBOOK_SURFACE | All, full | FACEBOOK_SURFACE=search lists three tools that find, describe and run the rest | | FACEBOOK_TOOL_TIMEOUT_MS | None | Give up on any tool after this long | | FACEBOOK_HTTP_PORT, FACEBOOK_HTTP_HOST, FACEBOOK_HTTP_TOKEN | 8787, 127.0.0.1, none | For --http. Any host but 127.0.0.1 needs the bearer token | | FACEBOOK_HTTP_ALLOWED_ORIGINS | None | Comma-separated browser origins allowed to call --http; a page from any other site is refused | | FACEBOOK_DEBUG | 0 | 1 prints debug lines on stderr |

9. Several Pages 📄

login stores every Page you administer. list_pages shows them, and every tool takes a page argument to name one.

Unnamed, it uses the first, which is rarely what you want. Set an order:

export FACEBOOK_PREFERRED_PAGES="Navid Media,Side Project"

Exact name matches beat prefix matches, so a Page called "Navid Media" will not swallow a request meant for "Navid".

10. Limits worth knowing ⚠️

Pages only. Facebook removed personal profile posting from the API in 2018 and never replaced it. No tool can do it.

Insights lag by a few hours, so this morning's post looks quieter than it is.

Rate limits are per app, not per Page. Heavy use across several Pages shares one budget. Reads back off and retry; writes never retry, because retrying a post risks publishing twice.

Edits are visible. Facebook shows viewers an edit history on any post you change.

11. Troubleshooting 🔧

"The Page token is invalid or expired." The token was short-lived. Set FACEBOOK_APP_ID and FACEBOOK_APP_SECRET and run login again.

"The token is missing a permission." Regenerate with all five permissions. Missing pages_read_engagement is the usual one, and it breaks reading rather than writing, which makes it confusing.

"That token can see no Pages." Missing pages_show_list, or you are not an admin of any Page.

Posting is missing, or refuses. That is the default: writes stay off the list until FACEBOOK_ALLOW_WRITE=true is set.

Anything else. Run doctor. It checks each Page and reports the first broken link.

Full setup walkthrough: INSTALL.md.

FAQ ❓

Model Context Protocol is a standard way to give an AI assistant access to a tool or a data source. An MCP server exposes a set of functions, and a client like Claude Code or Claude Desktop calls them during a conversation. This one exposes Facebook Pages.

You install it once, point your client at it, and then ask in plain language. You never call the tools yourself.

facebook-cli is the same program as the MCP server, run as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job. Every tool is a command with dashes, so create_post runs as facebook-cli create-post.

Use the MCP server in an app with no terminal, like Claude Desktop's chat. Use the CLI anywhere commands run: an agent like Claude Code, Codex or OpenCode, a script or a cron job. The MCP server's tools take up context on every message, and the CLI costs nothing until it runs.

Because Facebook has no other way to issue a token. There are no app passwords and no personal access tokens, so every credential is minted by an app someone owns. For a personal tool, that someone is you.

It is free, takes about ten minutes, and only happens once. Nothing is reviewed, nothing is published, and nobody else sees the app.

No. This is Meta's own API used the way Meta intends. Nothing is reverse engineered. The account risk that exists on Instagram's unofficial API, or on WhatsApp's companion protocol, does not apply here.

The real limit is rate limiting, which is per app rather than per Page. Heavy automated use across several Pages shares one budget.

One file, ~/.facebook-mcp/pages.json, written mode 600. It holds your Page ids and their tokens, nothing else.

No posts, no comments and no insights are stored. Everything is fetched live and passed straight to your client, so there is no local copy of your content.

If you set FACEBOOK_AUDIT_LOG, every attempted write is appended to that file as well.

No. The Graph API is free for this, the Meta app is free, and there is no paid tier involved. You pay for whatever AI client you use, and nothing else.

No, not for your own Pages. App Review and Business Verification are for managing Pages belonging to other people, which Meta calls Advanced Access. For Pages you administer, Standard Access is enough and is granted the moment you request it.

No, and neither can anything else. Facebook removed profile posting from the API in 2018 and never brought it back. Pages are the only writable surface.

Page tokens derived from a long-lived user token do not expire at all. Without your app id and secret, login can only produce short-lived ones that die in about an hour, which is the most common reason this stops working.

It cannot post at all unless you set FACEBOOK_ALLOW_WRITE=true. With that on it can, so set FACEBOOK_AUDIT_LOG and every attempt is written to a file no tool can edit.

Yes. The same app can carry all three sets of permissions, so add those products now if you plan to use them rather than creating three apps.

Questions

Run into a problem or have a question? Open an issue and I will help.

About the author

Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.

Links

If this is useful, star the repo and come say hi on X.

Dependencies

| Project | License | Used for | |---|---|---| | Slipway | Apache-2.0 | The MCP server and the CLI from one definition of each tool | | MCP TypeScript SDK | Apache-2.0 | The MCP protocol and its transports, through Slipway |

License

MIT. Free to use, modify, and share.

Not affiliated with, endorsed by, or connected to Meta Platforms, Inc.


© 2026 Navid Media. Made with ❤️ by Navid Moazzez.