Skip to content

These pages describe PrivacyFence 7.0.2. Download it · What changed

Connect Claude Code

Claude Code works with both deployments:

  • Local mode (desktop mode, deprecated): PrivacyFence installed on the same computer. Claude Code connects to the daemon's /mcp endpoint on localhost with your own bearer token.
  • Single-user Docker: PrivacyFence's Docker image on the same computer. Claude Code connects to http://localhost:8765/mcp and you sign in with your passkey.
  • Organization mode: PrivacyFence run centrally by your organization. Claude Code registers itself with PrivacyFence's OAuth server and you sign in with your organization account.

Which one you have is explained in Local mode and organization mode.

Local mode

Run this from your own account (not elevated, not as the service account), after logging out and back in once following the install.

Without a terminal command for the token: open Settings → AI clients. It shows the /mcp URL and the exact claude mcp add command; Copy token there, or Copy AI Client Token in the companion's menu (the macOS menu bar, the Windows tray, or on Linux the Copy AI client token action of the PrivacyFence Applications-menu entry), puts your token on the clipboard. Paste it in place of <token>. Treat it like a password.

The commands below get both from the command line instead, and need two things, both specific to your platform:

Platform /mcp URL file Token command
macOS /Library/Application Support/PrivacyFence/handoff/mcp_url /Applications/PrivacyFenceApp.app/Contents/MacOS/PrivacyFenceApp --print-mcp-token
Windows %ProgramData%\PrivacyFence\handoff\mcp_url & "$env:ProgramFiles\PrivacyFence\privacyfence-app.exe" --print-mcp-token, captured into a variable (the program has no console window, so run bare it prints nothing visible)
Linux (.deb) /var/lib/privacyfence/handoff/mcp_url privacyfence-app --print-mcp-token

On macOS:

PF_HANDOFF="/Library/Application Support/PrivacyFence/handoff"
claude mcp add --transport http --scope user privacyfence "$(cat "$PF_HANDOFF/mcp_url")" \
  --header "Authorization: Bearer $(/Applications/PrivacyFenceApp.app/Contents/MacOS/PrivacyFenceApp --print-mcp-token)"

On Windows, from PowerShell:

$url = Get-Content "$env:ProgramData\PrivacyFence\handoff\mcp_url"
$token = & "$env:ProgramFiles\PrivacyFence\privacyfence-app.exe" --print-mcp-token
claude mcp add --transport http --scope user privacyfence $url --header "Authorization: Bearer $token"

On Linux:

PF_HANDOFF=/var/lib/privacyfence/handoff
claude mcp add --transport http --scope user privacyfence "$(cat "$PF_HANDOFF/mcp_url")" \
  --header "Authorization: Bearer $(privacyfence-app --print-mcp-token)"
  • mcp_url holds http://localhost:8765/mcp unless you changed web.port (Configuration reference).
  • --print-mcp-token mints your account's token the first time and prints the same one afterwards, the same token Copy AI Client Token copies. Rotate token in Settings → AI clients replaces it; every client using the old one must then be given the new one. Each OS account gets its own token, and its own connectors, rules and approvals (ADR 0008).
  • --scope user makes PrivacyFence available in every project. Leave it out to add it to the current project only.
  • Run /mcp inside Claude Code to check that privacyfence is connected.

Any other MCP client that speaks Streamable HTTP takes the same URL and header.

Scoped tokens

A scheduled job or a single script needs less than your own token. In Settings → Scoped tokens create one: give it a name, a lifetime (90 days by default, at most 365), the rules it holds (new ones for this token, or copies of your Auto-accept rules) and the tools it may call. The companion copies the token to your clipboard once; it cannot be shown again. Use it as the bearer token in place of your own, for example PRIVACYFENCE_TOKEN for privacyfence-sync.

A client holding it sees only the tools you chose, and a call goes through only if one of its rules auto-accepts it. Anything else is denied at once; a scoped token never raises an approval card. Settings flags a token with 14 days or fewer left, and privacyfence_status tells the client its expiry. Revoke stops one token at once; Revoke all stops every one. Your own token and your other clients are not affected. A token's rules, tools and expiry cannot be edited. Deleting or changing an Auto-accept rule does not change a token. Rename changes only its name, and clients using it keep working. For any other change, Duplicate fills the New token form from an existing token, with a numbered name, so you can create a replacement and revoke the old one, with a copy of its rules. The form lists only the tools the selected rules cover, plus the tools that need no rule. On the New token form, a second checkbox, Let reads return personal data, lets covered Gmail message and thread reads, Slack reads and Drive file content reads return personal data (the scan still runs and is audited). The rules are the token's own: add them on the form (a scope, a value and verbs, as on the Auto-accept page) or copy one of your Auto-accept rules, and they never auto-accept anything for your other AI clients (ADR 0236). A Gmail query rule such as in:inbox does not match a message you sent, so a thread holding your own reply is not covered by it. See Scoped tokens.

Let Claude propose a token

Instead of building the token by hand, ask Claude to propose one for the routine. Claude calls privacyfence_propose_scoped_token, built from what you approved in the session or from rules it names, and hands you a review link. A local install always allows it, for the computer's owner.

  • Open the link: Settings → Scoped tokens shows the proposal. You can only narrow it: untick a rule, a verb or a tool, or shorten the lifetime. To add more, use New token.
  • If Claude asked for personal data to be allowed, those boxes start unticked; only you can tick them.
  • Continue, then type the token's name to confirm that you are delegating access.
  • The companion copies the token to your clipboard once. Claude never receives the token, and is not told whether you created it. A proposal lasts one hour and can be used once; Decline discards it. See ADR 0250.

Single-user Docker

Start the Docker image on your computer and set up your passkey (Run it on this computer). Then:

claude mcp add --transport http --scope user privacyfence http://localhost:8765/mcp

Run /mcp inside Claude Code and choose privacyfence to sign in. PrivacyFence opens its sign-in page for your passkey, then a consent page; after that Claude Code holds its own tokens, as with an organization server. Use localhost, not 127.0.0.1: the passkey belongs to localhost.

Organization mode

Your administrator gives you the deployment's URL, for example https://pf.example.com. Then:

claude mcp add --transport http --scope user privacyfence https://pf.example.com/mcp

Run /mcp inside Claude Code and choose privacyfence to sign in. Claude Code discovers PrivacyFence's authorization server, registers itself, and opens your organization's sign-in page in the browser. After you sign in it holds its own tokens; there is nothing to copy or paste. Access tokens last one hour and are refreshed silently; after 30 days you sign in again.

Scoped tokens

If your administrator has turned scoped tokens on, Settings → Scoped tokens lets you create a named, expiring bearer token with its own rules and a chosen list of tools, for a scheduled job that cannot sign in. The token is shown once, in a dialog with a Copy button; it is not stored and cannot be shown again. Pass it as the bearer token (Authorization: Bearer pfst_…) to /mcp. Its lifetime is 90 days by default and at most the administrator's limit. Revoke it in the same page. It is deny-only. A token's rules, tools and expiry cannot be edited. Deleting or changing an Auto-accept rule does not change a token. Rename changes only its name, and clients using it keep working. For any other change, Duplicate fills the New token form from an existing token, with a numbered name, so you can create a replacement and revoke the old one, with a copy of its rules. The form lists only the tools the selected rules cover, plus the tools that need no rule. On the New token form, a second checkbox, Let reads return personal data, lets covered Gmail message and thread reads, Slack reads and Drive file content reads return personal data (the scan still runs and is audited). The rules are the token's own: add them on the form (a scope, a value and verbs, as on the Auto-accept page) or copy one of your Auto-accept rules, and they never auto-accept anything for your other AI clients (ADR 0236). A Gmail query rule such as in:inbox does not match a message you sent, so a thread holding your own reply is not covered by it.

Connect your services at https://pf.example.com/connect. Setting up the deployment itself is Organization deployment.

Let Claude propose a token

Instead of building the token by hand, ask Claude to propose one for the routine. Claude calls privacyfence_propose_scoped_token, built from what you approved in the session or from rules it names, and hands you a review link. Your administrator must have turned token proposals on.

  • Open the link: Settings → Scoped tokens shows the proposal. You can only narrow it: untick a rule, a verb or a tool, or shorten the lifetime. To add more, use New token.
  • If Claude asked for personal data to be allowed, those boxes start unticked; only you can tick them.
  • Continue, then type the token's name to confirm that you are delegating access (and use your passkey, if your installation asks for one).
  • The token is shown once, in a dialog, for you to copy. Claude never receives the token, and is not told whether you created it. A proposal lasts one hour and can be used once; Decline discards it. See ADR 0250.

A cloud routine with a scoped token

A scheduled Claude Code routine that runs in the cloud (claude.ai/code) uses the claude.ai connector by default. That connector signs in as you, so the routine runs under your Auto-accept rules. It cannot use a scoped token's rules, its tool list or its personal-data checkboxes. To run the routine under a scoped token instead, give it a cloud environment of its own that sends the token to PrivacyFence:

  1. Create the token for the routine in Settings → Scoped tokens, with only the rules and tools the job needs. If the routine reads mail or pages that may hold personal data, tick Let reads return personal data. Use one token per routine (ADR 0220).
  2. Create a personal cloud environment used only by this routine and save the token in it. This is done in the browser, with no command: in claude.ai/code, open the cloud environment menu (in a session's title bar), add a new environment or choose Edit on an existing one, and under Network secrets add the token for the deployment's host, for example pf.example.com, as a bearer token. The environment's network proxy then adds Authorization: Bearer pfst_… to every request this environment's sessions send to that host.
  3. Add PrivacyFence as an MCP server in that environment, because the network secret only adds the header and gives the routine no tools. Put it in the routine repository's .mcp.json, or add it from the environment's setup script:
claude mcp add --transport http privacyfence https://pf.example.com/mcp --header "Authorization: Bearer placeholder"

The placeholder makes Claude Code send a header for the proxy to replace, instead of starting an OAuth sign-in. Never put the real token in the repository, the setup script or an environment variable: those are stored in plain text. 4. Turn off the claude.ai PrivacyFence connector for the routine, so its calls do not also go out under your own sign-in. 5. Point the routine at the new environment.

Calls from the routine are then decided by the token alone. They are deny-only, never raise an approval card, and are recorded in the audit log under the token's name. Things to keep in mind:

  • Keep the environment for this routine only. The secret goes to every session in the environment. On your Default environment, or an environment shared with your organization, other sessions would run under the routine's token too.
  • Replace the token before it expires. At expiry the routine's calls are denied. Settings flags a token close to expiry; Duplicate it, save the new token in the environment's network secrets, then revoke the old one.

Files

Claude Code does not run PrivacyFence's Claude Desktop extension, so PrivacyFence never opens a path on your computer for it. Files travel through one-time links instead (ADR 0028):

  • Upload (for example drive_upload_file, or an email attachment): Claude Code calls privacyfence_create_upload_slot, sends the file to the returned URL with an HTTP PUT, and passes the returned upload_id to the tool.
  • Download (for example drive_download_file): the tool returns a one-time link, or in organization mode the file itself when it is small enough.

Sizes, lifetimes and the organization settings are in Files. A source checkout or pip install that runs as you reads and writes paths directly.

Confirmations

Two things can ask you before a tool runs:

  1. Claude Code's own permission prompt. Whether Claude Code asks before it calls a tool from an MCP server depends on its permission mode and rules, not on the tool's annotations. To stop it asking for PrivacyFence's tools, allow mcp__privacyfence under /permissions, or add it to permissions.allow in Claude Code's settings.
  2. PrivacyFence's approval card. A gated call waits for you in Approvals, whatever Claude Code was told or allowed. This is the confirmation that decides; see Approvals and policy.

PrivacyFence always tells the client what each tool does: reads are read-only, writes are writes, and the tools that delete something (calendar_delete_event, drive_sheets_delete_dimensions and peek_delete_page) are destructive (What the AI system is told). There is no switch that advertises writes as read-only. If you would rather confirm only once, on PrivacyFence's card, always-allow PrivacyFence's tools in Claude Code: choose the option not to ask again the first time it asks about a PrivacyFence tool, or allow mcp__privacyfence as above for all of them at once. Every call still goes through PrivacyFence's gate.

What we observed (Claude Code 2.1.283, PrivacyFence 5.0.0a2, 2026-09-28, local mode, evidence): with no permission rules configured, Claude Code did not ask before calendar_create_event or any other PrivacyFence tool in the run; PrivacyFence's approval card was the only confirmation. If your permission mode or rules make it ask, always-allow as above.

How the client is identified

In local mode every approval card and Audit Log row shows the requester as Undetected: every AI system on your computer uses the same credential, so PrivacyFence cannot tell them apart. The audit log still records the name Claude Code sent.

In organization mode, Claude Code sends its own name when it registers and in the MCP handshake. It registers as Claude Code (<name>), where <name> is the server name you gave claude mcp add, and PrivacyFence recognises that as Claude Code whatever the name is. That name is a claim: the card says the caller says it is Claude Code and marks it Not verified, because any program can send the same name, and its redirect URI is a loopback address that any local program can register. There is nothing an administrator can do about it. See Which AI system is asking and AI systems.

Troubleshooting

What you see What to do
--print-mcp-token cannot reach the daemon Log out and back in once after installing, then check that the daemon is running (your platform's install page, "Troubleshooting").
On Windows the token variable is empty Run the command as yourself, not elevated, and capture it into a variable as above.
/mcp shows privacyfence as failed in local mode The daemon is stopped, or web.port changed after you added it. Start the daemon, then run the claude mcp add command again (remove the old entry first with claude mcp remove privacyfence).
/mcp shows privacyfence as needing authentication in organization mode Choose it in /mcp and sign in again.
Tools are listed but none of your services' tools No service is connected yet. Ask Claude Code to call privacyfence_status; connect services in Settings (local mode) or at /connect (organization mode). See Connecting a service.
A call waits and nothing happens It is waiting for your approval. Open Approvals from the companion, or /approvals in organization mode.

Platform-specific problems are on macOS, Windows and Linux.