This is the Python Software Foundation's fork of Plausible Analytics, running at analytics.python.org. It tracks traffic across PSF infrastructure sites with privacy-friendly, cookie-free analytics.
The fork adds:
- A custom landing page at
/with links to public dashboards - Unix domain socket support for Cabotage deployments
- PSF-specific Procfile and Dockerfile configuration
- ClickHouse migration and replication settings for the PSF database topology
- Google API and GA4 import adjustments
The deployment branch for this baseline is v3.2.1-psf, incorporating upstream
v3.2.1.
The name identifies the latest incorporated CE release, not an unmodified release
tree: this fork also retains the previously imported upstream master snapshot
dc51b4cc9c7107d9bed63fbe594c7c81fe702238 and subsequent PSF changes.
These are open to everyone, no login required:
To add a new PSF property to analytics.python.org, open an issue on this repo or reach out to the Infrastructure team. Include:
- The domain (e.g.
us.pycon.org) - Whether the dashboard should be public or private
- Who needs admin access
The infra team will create the site, provide the tracking snippet, and configure visibility.
By default, dashboards are private (team-only).
To make one publicly visible, ask the infra team to toggle the "Public" setting for that site.
Once public, anyone can view the dashboard at analytics.python.org/<domain> without logging in.
Query analytics.python.org from Claude, Codex, omp, or any MCP
client with getsentry/plausible-mcp (read-only tools:
get_timeseries, get_breakdown, get_conversions, compare_periods).
You need an account and a personal API key. A key reads only the sites its owner belongs to; public dashboards do not open the API. Ask the infra team for an invite.
-
Create a key at Settings → API Keys. Copy it from the form before you click Create API key; it is not shown again.
-
Build the server (Node.js 20+). Do not use the hosted
plausible-mcp.sentry.dev(it only talks to plausible.io) or the unrelated npm packageplausible-mcp.git clone https://github.com/getsentry/plausible-mcp.git cd plausible-mcp && pnpm install && pnpm build
-
Register it with your client. Set
PLAUSIBLE_BASE_URL, because the default is plausible.io. Replace/path/to/plausible-mcpwith your clone.
Claude Code
claude mcp add -s user plausible-psf \
-e PLAUSIBLE_API_KEY=your-key -e PLAUSIBLE_BASE_URL=https://analytics.python.org \
-- node /path/to/plausible-mcp/dist/index.jsCodex
codex mcp add plausible-psf \
--env PLAUSIBLE_API_KEY=your-key --env PLAUSIBLE_BASE_URL=https://analytics.python.org \
-- node /path/to/plausible-mcp/dist/index.jsomp
Add to ~/.omp/agent/mcp.json. ${PLAUSIBLE_API_KEY} expands from your shell environment.
{
"mcpServers": {
"plausible-psf": {
"type": "stdio",
"command": "node",
"args": ["/path/to/plausible-mcp/dist/index.js"],
"env": {
"PLAUSIBLE_API_KEY": "${PLAUSIBLE_API_KEY}",
"PLAUSIBLE_BASE_URL": "https://analytics.python.org"
}
}
}
}Claude Desktop / Cursor / other JSON clients
{
"mcpServers": {
"plausible-psf": {
"command": "node",
"args": ["/path/to/plausible-mcp/dist/index.js"],
"env": {
"PLAUSIBLE_API_KEY": "your-key",
"PLAUSIBLE_BASE_URL": "https://analytics.python.org"
}
}
}
}Keep the key out of config files (macOS Keychain)
Store the key once, then point any client at this launcher instead of node …/index.js:
security add-generic-password -U -s plausible-psf-mcp -a "$USER" -w # paste key#!/bin/sh
export PLAUSIBLE_API_KEY="$(security find-generic-password -s plausible-psf-mcp -w)"
export PLAUSIBLE_BASE_URL=https://analytics.python.org
exec node /path/to/plausible-mcp/dist/index.jsTest your key
curl -sS -X POST https://analytics.python.org/api/v2/query \
-H "Authorization: Bearer $PLAUSIBLE_API_KEY" -H 'Content-Type: application/json' \
-d '{"site_id":"python.org","metrics":["visitors"],"date_range":"7d"}'A 401 Invalid API key or site ID means a bad key or a site you are not a member of.
Then ask things like "Compare docs.python.org visitors this week vs last week." To revoke a key, delete it on the API Keys page.
The landing page at / is a static HTML file at landing/index.html.
It gets baked into the Docker image and served by the Phoenix app through PageController.
Logged-in users get redirected to /sites as usual.
To edit the landing page, change landing/index.html and open a PR against the
deployment branch. Merge only after CI passes; Cabotage builds from its configured
branch.
Docker. It uses:
- Elixir 1.19+, Erlang/OTP 27+
- PostgreSQL 16+
- ClickHouse 24.3+
- Node.js 23+
mix deps.get
mix ecto.create
mix ecto.migrate
mix download_country_database
npm install --prefix assets
npm install --prefix tracker
npm run deploy --prefix trackermake serverThe app starts at http://localhost:8000.
If you only need to iterate on the landing page HTML without running the full Elixir stack:
cd landing && python3 -m http.server 3000Open http://localhost:3000. The links won't resolve (no Plausible backend), but you can check layout and styling.
make help Show available targets
make server Start the dev server (mix phx.server)
make install Full setup (deps, DB, assets)
make clickhouse Start ClickHouse in Docker
make postgres Start PostgreSQL in Docker
This runs on Cabotage, the PSF's PaaS. The Procfile defines two processes:
web— the Plausible Phoenix app, binds to a unix socket viaHTTPS_UDSrelease— runs database migrations on deploy
Cabotage builds from its configured deployment branch. The transition from
v3.0.1-psf to v3.2.1-psf requires an explicit operator cutover; merging code or
editing this README does not change Cabotage's branch setting.
After the reconciliation PR passes CI and is merged with a merge commit:
- Pause automatic deployment while changing branch references.
- Rename the deployment branch from
v3.0.1-psftov3.2.1-psf, keeping its reviewed history. Update GitHub's default branch and applicable branch rules. - Change Cabotage's tracked branch to
v3.2.1-psf, then resume automatic deployment. - Build and deploy through Cabotage. Verify the deployed source commit and image digest, migration completion, and application health.
Before this cutover, production continues to track the existing branch.
This fork backports the upstream removal of Storybook for GHSA-mhcv-h7gf-57cf. Deploy a newly built image containing the fix; the branch name alone does not identify patched code.
Until the patched image is deployed, block /storybook and its subpaths at every ingress, including direct-origin access. Preserve access logs and incident evidence. After deployment, verify the running commit and image digest and confirm that Storybook is unavailable.
If credentials were disclosed or compromise is suspected, rotate or revoke all secrets accessible to the container after containment and assess downstream access with PSRT. Use the supported rotation procedure for encryption keys. Deploying this patch does not invalidate stolen credentials.
Track published upstream CE release tags, not the moving master branch.
For each release, create a review branch from the current PSF deployment branch
and merge the selected upstream tag into it. Keep the PSF and previously imported
upstream changes unless a reviewed migration deliberately replaces them.
The reconciliation to v3.2.1 restores the ancestry lost when PR #2 was
squash-merged: original merge ec3f81de488b7aa9a6dcffc03cb9b33bcb53cda1
has the same tree as squash commit 2d3391215fd26fe3a4a2e54c083e4ffb5ebe7b60.
The ancestry repair preserves the current PSF tree, then incorporates the
upstream v3.2.1 tag.
Use merge commits for upstream synchronization PRs, including this ancestry repair. Do not squash or rebase them. A repository administrator must enable merge commits before merging if the repository only permits squash merges.
Review the landing page and controller, Unix socket configuration, Dockerfile and Procfile, ClickHouse migrations and replication paths, Google API/GA4 import adjustments, Storybook removal, and MinIO test setup during every synchronization. Preserve applied migration history; do not reset the fork to a stock release tree.
Require CI and a production-image build before merging. If migrations change,
validate them against a restored database copy before production deployment.
After review, rename the deployment branch to v<upstream-version>-psf and update
GitHub, Cabotage, and these instructions together. Record the upstream tag, PSF
commit, and deployed image digest for each deployment.
Plausible CE is open source under the GNU Affero General Public License Version 3. The JavaScript tracker is MIT licensed.
Copyright (c) 2018-present Plausible Insights OÜ.