Fbc Guard
Overview
Description from the maker (original English)
Static checks for Meta _fbc, _fbp and fbclid code that cause modified click ID warnings.
What you can do with it
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
- Connection: Runs on your computer
- Transport: stdio
- Category: Developer tools
Install
Pick the AI app you use, then copy the settings.
Passed 2/2 checks · Runs on your computer
First: which AI do you use?
Pick your app and the steps appear below.
Works with Claude, with some setup first
Install Node.js on your computer first (one time) · Only the Claude desktop app (Windows or Mac), not the web or phone
Install Node.js
One time only; it works for every server that needs Node.js
Open the Claude desktop app’s settings file
SettingsDeveloperEdit Config
Paste these settings and save the file
{ "mcpServers": { "fbc-guard": { "command": "npx", "args": [ "-y", "mcp-server-fbc-guard" ] } } }Quit Claude and open it again
Try it
Use Fbc Guard and tell me what you can do for me, then show me one thing✓ If Claude says it is using Fbc Guard or shows a Fbc Guard tool in the answer, you are connected
Menu names checked against Anthropic’s help page on Nov 11, 2026 · your screen may differ slightly by app version
ChatGPT cannot connect Fbc Guard yet
Fbc Guard runs on your computer, but ChatGPT can only connect servers that run on the web
What you can do instead
A · Use an app that can connect Fbc Guard
- Install Node.js on your computer first (one time) · Only the Claude desktop app (Windows or Mac), not the web or phone
- Install Node.js on your computer first (one time)
- Install Node.js on your computer first (one time)
- Install Node.js on your computer first (one time)
B · Others in Developer tools that work with ChatGPT
Picked from the most used in the same category, only ones that connect by address with no key
- Sentry✓ ChatGPT
- Front-End Checklist✓ ChatGPT
- Compiler Explorer✓ ChatGPT
Works with Claude Code, with some setup first
Install Node.js on your computer first (one time)
Install Node.js
One time only; it works for every server that needs Node.js
Open Terminal
Mac: press Command+Space and type Terminal · Windows: open PowerShell
Paste this command and press Enter
claude mcp add fbc-guard -- npx -y mcp-server-fbc-guardType /mcp in Claude Code
You should see Fbc Guard listed as connected
Try it
Use Fbc Guard and tell me what you can do for me, then show me one thing✓ If Claude Code says it is using Fbc Guard or shows a Fbc Guard tool in the answer, you are connected
Menu names checked against Anthropic’s help page on Nov 11, 2026 · your screen may differ slightly by app version
Works with Cursor, with some setup first
Install Node.js on your computer first (one time)
Install Node.js
One time only; it works for every server that needs Node.js
Open the AI chat in Cursor in Agent mode
Try it
Use Fbc Guard and tell me what you can do for me, then show me one thing✓ If Cursor says it is using Fbc Guard or shows a Fbc Guard tool in the answer, you are connected
Menu names checked against Cursor’s help page on Nov 11, 2026 · your screen may differ slightly by app version
Works with VS Code, with some setup first
Install Node.js on your computer first (one time)
Install Node.js
One time only; it works for every server that needs Node.js
Open the AI chat in VS Code in Agent mode
Try it
Use Fbc Guard and tell me what you can do for me, then show me one thing✓ If VS Code says it is using Fbc Guard or shows a Fbc Guard tool in the answer, you are connected
Menu names checked against VS Code’s help page on Nov 11, 2026 · your screen may differ slightly by app version
For developers: Terminal commands and JSON settings
Installed on your computer
Claude Code
claude mcp add fbc-guard -- npx -y mcp-server-fbc-guardClaude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"fbc-guard": {
"command": "npx",
"args": [
"-y",
"mcp-server-fbc-guard"
]
}
}
}Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"fbc-guard": {
"command": "npx",
"args": [
"-y",
"mcp-server-fbc-guard"
]
}
}
}VS Code (mcp.json)
{
"servers": {
"fbc-guard": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mcp-server-fbc-guard"
]
}
}
}These settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
At a glance
- Downloads per weeki
- 50/wk
- Connection
- Runs on your computer
- Transport
- stdio
- Latest versioni
- 0.1.0
- Categoryi
- Developer tools
- Published to registryi
- Oct 23, 2026
- Code last changedi
- Oct 23, 2026
- Maker
- adsandcode
- Packages
npm: mcp-server-fbc-guard- Website
- adsandcode.com
- Registry status
- Active
Which apps can use it
Based on how this server connects and on each app’s own docs, checked Nov 10, 2026.
Run on your computer in
ClaudeGooseLM StudioMsty StudioCherry StudioCursorVS Code + GitHub CopilotVisual StudioWindsurf (Devin Desktop)ZedKiroClineContinueJetBrains AI AssistantClaude CodeCodex CLIGemini CLIOpenCodenodecodeWarpLibreChatRaycast
Related guides
What it can do
Runs on your computer; the tool list appears in your AI app after you install it.
Basic checksi
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 11, 2026
- ✓ Pass
Maker matches the repo
The registry name was verified with the GitHub account adsandcode, which owns the repo
- ✓ Pass
Still maintained
Code last changed 19 days ago
- … Not checked yet
Has a licence
We have not read this repo from GitHub yet
- – Not applicable
Endpoint responds
This one runs on your computer; there is no internet endpoint
- – Not applicable
Sign-in with OAuth
Runs on your computer and uses local settings instead
- … Not checked yet
No hidden instructions in tool descriptions
Runs on your computer; we can only read tool lists from internet endpoints
Discussion
Ask, share a tip or report that it does not work. Sorted by what people marked helpful.
No posts yet. Be the first to ask or share.
Posts here are written by users, not the PopNx team.
User reviews
No reviews yet
Compared with others in Developer toolsi
- More stars than 0% of the other 5750 servers in this category
- Published to the registry more recently than 59% of the other 5750 servers in this category
- Basic checks equal to or better than 100% of the other 5750 servers in this category
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
Common questions
Is Fbc Guard safe?
It passed 2 of 2 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
What keys or codes does it need?
The registry does not list a required key, though some servers ask you to sign in on first use.
Does it run on my computer or in the cloud?
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
Is it still maintained?
The GitHub repo last changed 19 days ago, and the latest version (0.1.0) reached the registry 19 days ago.
Which apps can use it?
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Node.js on your computer.
What can I use instead?
In the same category: REA, Netdata, Front-End Checklist
Alternatives
Servers in the same category from other makers, sorted by stars.
Reading a card:↓ Downloads per weeki★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
Netdata
Real-time infrastructure monitoring with metrics, logs, alerts, and ML-based anomaly detection.
Front-End Checklist
Review frontend code and live pages against 386 quality-gated web development rules.
README from the maker
Open the README
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
fbc-guard
Static checks for the landing-page code that stores Meta's click ID.
Documentation and background: adsandcode.com/en/open-source/fbc-guard
fbc-guard reads the HTML and JavaScript that turn the fbclid URL parameter into the _fbc cookie (and, if you write it yourself, the _fbp cookie), and flags the known ways that code changes or loses the click ID.
It runs as an MCP server, so an AI assistant can check tracking code while it writes or reviews a page, and as a command-line tool for CI.
The problem it addresses
When someone clicks a Meta ad, the landing page URL carries an fbclid parameter. Your page, or the Meta Pixel, stores it in a first-party _fbc cookie in the form fb. . . , and later events send that value to Meta in the fbc parameter.
Hand-written versions of this code tend to go wrong in a few specific ways:
- They keep an older click ID when a returning visitor arrives from a different ad, so the conversion is attributed to the earlier ad.
- They change the click ID on the way through: decode it again, change its case, or cut it short.
- They write
creationTimein seconds instead of milliseconds, or hard-codesubdomainIndex.
Advertisers report seeing an Events Manager diagnostic about a modified fbclid in the fbc parameter. Meta's documentation does not list what causes it. The first two mistakes above alter or replace the click ID between the URL and the event, so they are worth ruling out when you see it.
fbc-guard finds these patterns in source code before it ships. It does not run the code and it sends nothing to Meta.
Install
MCP server
Add this to your MCP client configuration (Claude Desktop, Cursor, and other clients that read an mcpServers block):
{
"mcpServers": { "fbc-guard": { "command": "npx", "args": ["-y", "mcp-server-fbc-guard"] } } }
Claude Code:
claude mcp add fbc-guard -- npx -y mcp-server-fbc-guard
Requires Node.js 18 or later.
Command line
npx -y -p mcp-server-fbc-guard fbc-guard https://your-landing-page.example/
or install it
npm install -g mcp-server-fbc-guard fbc-guard ./dist/index.html ./dist/js/tracking.js
As a library
import { checkCode } from "mcp-server-fbc-guard";
const result = checkCode(htmlOrJs); // { status, failed, unknown, warnings, rules }
The package entry point is the rules module only. Importing it does not start the MCP server, read files or touch the network.
MCP tools
| Tool | Input | What it does |
|---|---|---|
check_fbc_code | code: HTML or JavaScript; optional kind: auto (default), html or js | Runs every rule on the source you pass. No network access. |
check_fbc_url | url: http or https URL | Fetches the page and every same-origin it loads, then runs every rule on all of it. Public hosts only, unless the server runs with FBC_GUARD_ALLOW_PRIVATE=1 (see Network safety). Also returns final_url, scanned_scripts and skipped_scripts. |
Both return JSON:
{
"status": "fail", "failed": ["FBC-01"], "unknown": [], "warnings": ["FBC-06"], "rules": [ { "id": "FBC-01", "title": "A new fbclid must overwrite an older _fbc cookie", "status": "fail", "evidence": "indexOf('_fbc=')<0", "protects": "If the cookie is only written when it is missing, ...", "basis": "official", "severity": "error", "reference": "https://developers.facebook.com/documentation/ads-commerce/conversions-api/parameters/fbp-and-fbc" } ] }
Each rule's status is pass, fail, unknown or warn. warn comes only from warning-level rules (FBC-06); it is listed under warnings and never changes the overall status or the exit code.
The overall status is pass, fail, unknown, or not_applicable.
unknownmeans no rule failed, but at least one rule could not decide. Today only FBC-01 can return it, when it cannot tell which variable holds thefbclidfrom the URL. The rule'sevidencesays what could not be resolved.not_applicablemeans the string_fbcdoes not appear anywhere in what was scanned, so no rule was evaluated. The code may live somewhere the scan cannot see.
Neither is a pass.
In check_fbc_code, kind: "auto" reads the input as HTML when it starts with < and analyses its inline bodies, and reads anything else as JavaScript.
The server runs its own negative tests at startup and refuses to start if any rule no longer fails on the code it is supposed to catch.
Command line
fbc-guard <url|file> [<url|file> ...] check pages (http/https) or local files
fbc-guard --json [...] print JSON instead of text fbc-guard --allow-private [...] also allow localhost and private-network URLs fbc-guard --selftest run only the negative tests fbc-guard --help | --version
Each target is judged separately. URLs are fetched together with their same-origin scripts. Local files are scanned as they are, without following , so list your JavaScript files as well. A local file is read as JavaScript when its extension is .js, .mjs, .cjs, .jsx, .ts, .mts, .cts or .tsx, as HTML when it is .html, .htm, .xhtml, .shtml or .php, and otherwise by its first character, as in check_fbc_code.
Before judging any target the CLI runs the same negative tests as the server. If they fail, it prints which test failed and exits with code 2 without giving a verdict.
| Exit code | Meaning |
|---|---|
| 0 | No error-level rule failed on any target. This includes targets with warnings only (FBC-06), unknown (a rule could not decide) or not_applicable (no _fbc code); the output marks all three |
| 1 | At least one rule failed on at least one target |
| 2 | The negative tests failed, the arguments were invalid (including --selftest with anything else), or a target could not be read or fetched |
In CI:
npx -y -p mcp-server-fbc-guard fbc-guard ./public/index.html ./public/js/tracking.js
Rules
Each rule cites Meta's reference page, ClickID and the fbp and fbc Parameters (the older URL under /docs/marketing-api/conversions-api/parameters/fbp-and-fbc/ redirects there). The Basis column says how directly that page supports the rule:
- Official: the page states the requirement.
- Derived: the page states a general requirement; applying it to this specific code pattern is our reading.
- Observed in practice: not stated by Meta; a mistake seen in real implementations.
| ID | Flags | Severity | Basis |
|---|---|---|---|
| FBC-01 | The _fbc cookie is written only when it does not exist, or the click ID from the URL is never compared with anything but a literal | error | Official |
| FBC-02 | decodeURIComponent(fbclid) | error | Derived |
| FBC-03 | fbclid.toLowerCase() / fbclid.toUpperCase() | error | Official |
| FBC-04 | fbclid.slice(, .substring(, .substr( | error | Derived |
| FBC-05 | A seconds timestamp in the statement that builds an _fbc=fb. value | error | Official |
| FBC-06 | A literal digit as subdomainIndex in an _fbc cookie value | warning | Observed in practice |
| FBP-01 | The same as FBC-05, for _fbp=fb. | error | Official |
An error-level rule that fires fails the check (exit code 1). A warning-level rule that fires is reported with status warn and does not change the result or the exit code.
The rules read the source through a small scanner, not a JavaScript parser. Nothing inside a JavaScript comment counts, and neither does markup inside an HTML comment.
- FBC-02, FBC-03 and FBC-04 read only the JavaScript (inline
bodies and fetched script files) and also ignore string contents, so a message such as'do not call decodeURIComponent(fbclid)'does not trigger them. - FBC-06 and the write-only-if-missing check of FBC-01 look for text that lives inside string literals, so they read the whole document with comments removed and string contents kept.
- FBC-01, FBC-05 and FBP-01 also use the scanner to find where a statement starts and ends.
FBC-01: a new fbclid must overwrite an older _fbc cookie
Code written as "set the cookie if there is none" keeps the first click ID forever. A visitor who returns through a different ad still carries the old one, and the conversion is credited to the earlier ad. Meta's page lists, as a case where the cookie should be set, a URL fbclid that "isn't equal to the corresponding value in the _fbc cookie value".
How the rule decides:
- It finds the variables that hold the click ID from the URL: assigned from
.get('fbclid'),['fbclid']or.fbclid, from amatch,split,execor similar call on text containingfbclid=, or copied from one of those (var f = fbclid || ''). A variable or parameter literally namedfbclidalso counts. - It looks for a
!==,!=,===or==comparison between one of those variables and something that is not a literal.id !== fandif (stored === clickId) return;count;f !== ''andf != nulldo not. - A comparison passes the rule. That includes "set the cookie if it is missing or different", written as
indexOf('_fbc=') < 0 || id !== f. - Without a comparison, the rule fails if it finds the write-only-if-missing pattern
indexOf('_fbc=') < 0, or if it found a click ID variable. - If it found neither a click ID variable nor that pattern, the status is
unknown, with an explanation. Exit code 0.
FBC-02: do not URL-decode fbclid a second time
URLSearchParams.get() already returns a decoded value. Decoding it again either leaves it unchanged or changes it, and decodeURIComponent throws on a lone %, which stops the rest of the script. Meta's page says to "do not apply any modifications before using" the click ID. It does not mention decoding specifically; treating a second decode as a modification is our reading.
FBC-03: do not change the case of fbclid
Meta's page states "ClickID value is case sensitive" and names lower- and upper-casing as modifications to avoid.
FBC-04: do not truncate fbclid
A shortened click ID is a modified click ID. Meta's page says to "do not apply any modifications before using" it; truncation is not named specifically.
FBC-05: _fbc creationTime must be in milliseconds
Meta's page defines it: "creationTime is the UNIX time since epoch in milliseconds". Date.now() already returns milliseconds; dividing by 1000 writes seconds.
The rule looks at each statement that contains an _fbc=fb. string or template literal and fails if that statement divides a millisecond clock by 1000:
- clocks:
Date.now(),new Date(),(new Date),new Date().getTime(),(new Date).getTime(),new Date().valueOf(),+new Date, andd.getTime()/d.valueOf()on a variable (anew Date(...)built from arguments is a fixed moment, not the clock, and is not matched); - divisors:
/1000or/1e3, with or without spaces, whatever wraps it (Math.floor,Math.round,Math.trunc,parseInt,|0,~~); - written directly in the concatenation or template literal, or stored in a variable first and concatenated in. For a variable, the last assignment before the statement is the one that counts.
It does not fire on Date.now() alone, on /1000 in other statements (a countdown timer elsewhere in the file), on a commented-out line, or on a time difference such as (end - Date.now()) / 1000, which is a duration like max-age, not a timestamp.
FBC-06 (warning): check a hard-coded subdomainIndex in the _fbc cookie
Meta's page says "subdomainIndex is which domain the cookie is defined on"