{"id":"0ad78d59-ba9e-4e7e-96f2-1200efac5b9f","slug":"virling","kind":"mcp","name":"virling","summary":"Open-source revenue attribution: see which traffic channel brings paying customers. Stripe, Dodo Payments and Polar. One Rust binary.","owner":"virling","repoUrl":"https://github.com/virling/virling","license":"AGPL-3.0","licenseTier":"strong-copyleft","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-10-13T13:30:21.000Z","addedAt":"2026-10-21T05:17:58.088Z","logoUrl":"https://avatars.githubusercontent.com/u/342013637?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["data-analytics","databases","cloud-infra"],"tags":["analytics","attribution","privacy","revenue-analytics","rust","self-hosted","stripe","web-analytics"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-21T05:31:10.248Z","sample":false,"url":"https://conduits.dev/tools/virling","language":"Rust","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  <img src=\"https://virling.com/favicon.svg\" width=\"72\" height=\"72\" alt=\"Virling logo\">\n</p>\n\n<h1 align=\"center\">Virling</h1>\n\n<p align=\"center\">\n  Open-source revenue attribution. See which traffic channel brings paying customers, not just visitors.<br>\n  <a href=\"https://virling.com\">virling.com</a> · <a href=\"https://virling.com/demo/\">Live demo</a> · <a href=\"https://docs.virling.com\">Docs</a> · <a href=\"https://virling.com/agency\">For agencies</a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://virling.com/demo/\"><img src=\".github/dashboard.png\" alt=\"Virling dashboard: revenue, revenue per visitor and the channels that bring paying customers\" width=\"900\"></a>\n</p>\n\n---\n\nVirling joins every visit to the payment that followed. It answers the questions a founder asks every week:\n\n- Which channel brought the most revenue this month?\n- Did that launch, tweet or Reddit post make money, or just traffic?\n- What is a visitor from each source worth?\n- What path did my last paying customers take before they paid?\n\nIt runs as one Rust binary with embedded storage. No Postgres, no ClickHouse, no Redis.\n\n> **Status:** early development. Releases are on the [releases page](https://github.com/virling/virling/releases) and run on your own server today. Expect breaking changes until a stable release. The hosted beta is open to everyone at [beta.virling.com](https://beta.virling.com/login).\n\n## What works today\n\n- **Tracking script** (`/v.js`, about 1.3 KB gzipped, source in `assets/v.src.js`): pageviews, UTM tags, referrers, single-page-app route changes, custom goals, and a first-party visitor ID. Stripe Payment Links, Polar checkout links and Dodo payment links get the visitor ID added automatically.\n- **Cookieless mode**: a daily-rotating salted hash instead of a cookie, for sites that want no consent banner, at the cost of payment attribution.\n- **Event ingest** into embedded DuckDB, with bot filtering, per-site rate limits and channel rules (Paid, Email, AI, Organic search, Communities, Social, Referral, Direct). Visitor IPs are never stored.\n- **Payment sync** from Stripe, Dodo Payments, Polar and LemonSqueezy with a read-only key (LemonSqueezy keys cannot be limited): a 90-day backfill, then a poll every minute. Virling never creates, changes or refunds anything. LemonSqueezy payments count toward revenue, but linking them to visits waits on webhook support.\n- **Attribution**: last non-direct or first touch, with a 30, 60, 90 or 365 day lookback. Renewals keep the channel of the customer's first payment. Payments without a visitor ID count as Unattributed.\n- **Revenue dashboard**: revenue, revenue per visitor and conversion by channel, referrer, campaign, page and country, payment journeys, a Visitors page, retention by first channel, tracked short links, and AI assistant visits next to AI crawler hits.\n- **Reports and sharing**: weekly email reports with agency branding, and an optional public dashboard.\n- **Read API, MCP server and CLI**: read-only access with API keys or OAuth sign-in, so `virling query` and AI assistants such as Claude and ChatGPT can answer revenue questions. An agent skill is in `skills/virling`, and `claude plugin marketplace add virling/virling` installs it with the MCP server as a Claude Code plugin.\n- **WordPress plugin** in `integrations/wordpress`.\n- **Magic-link sign-in and onboarding** (behind `--app`).\n\nNot available yet: the hosted plan, team members, imports from other tools, other attribution models and Windows builds.\n\n## Run it\n\nWith Docker:\n\n```sh\ndocker run -d --name virling -p 8080:8080 -v virling-data:/data \\\n  -e VIRLING_BASE_URL=https://stats.example.com \\\n  ghcr.io/virling/virling:latest serve --app\ndocker exec virling virling add-site yourdomain.com --owner you@example.com\n```\n\nThe full guide, with release binaries, a reverse proxy and payment setup, is at [docs.virling.com](https://docs.virling.com). To run from source, you need Rust 1.99 or newer:\n\n```sh\ncargo run --release -- add-site yourdomain.com --owner you@example.com\ncargo run --release -- serve --app\n```\n\nThen add the script to your site:\n\n```html\n<script defer src=\"https://YOUR-VIRLING-HOST/v.js\" data-site=\"yourdomain.com\"></script>\n```\n\nTrack a goal from your code:\n\n```js\nvirling(\"goal\", \"signup\");\n```\n\nPass the visitor ID into checkout so payments can be matched back to visits:\n\n```js\nvirling.vid();\n```\n\n## Configuration\n\n| Variable | Default | What it does |\n| --- | --- | --- |\n| `VIRLING_DATA` | `./virling-data` | Folder for the SQLite and DuckDB files |\n| `VIRLING_ADDR` | `0.0.0.0:8080` | Address to listen on |\n| `VIRLING_BASE_URL` | `http://localhost:8080` | Public URL, used in emails and snippets |\n| `VIRLING_APP` | off | Serve sign-in and the app |\n| `VIRLING_SMTP_URL` | unset | SMTP for emails, e.g. `smtps://user:pass@smtp.example.com:465`. Unset: emails are logged |\n| `VIRLING_MAIL_FROM` | `Virling <login@virling.com>` | Sender for sign-in emails |\n| `VIRLING_TRUST_PROXY` | off | Read the client IP from `X-Forwarded-For` |\n| `VIRLING_EVENTS_PER_SECOND` | `200` | Ingest limit per site |\n\n## Development\n\n```sh\ncargo test\n```\n\n`worker/` holds the Cloudflare Worker that serves virling.com during the waitlist phase. It reuses the landing pages in `assets/` and builds with `wrangler deploy`.\n\n## License\n\n[AGPL-3.0](LICENSE). Self-host it freely. If you run a modified version as a service, share your changes.\n\nBuilt by [Stacklance Infotech LLP](https://stacklance.in).\n"}