Build on SelectX
Connect Claude over MCP, call the scoped SX API, or ship a plug-and-play plugin to the in-app marketplace.
Overview
SelectX is built to be extended without forking the app. There are three ways in:
- Connect Claude (or any MCP client) over the Model Context Protocol. No code - mint a token and paste a config.
- Call the SX API with a scoped token to build integrations, sync data, and run automations.
- Build a plugin that adds UI panels, event hooks, actions, and scheduled jobs, then publish it to the in-app marketplace.
x-bc, or proxy secrets.Quickstart
Claude MCP
The MCP server lets a Claude client read your analytics, creators, billing, earnings, growth, and schedule, and draft messages, add notes, and schedule posts. Every write flows through the same mediated pipeline and is executed by your desktop app - Claude never touches OnlyFans directly.
Connect
In the app, open Settings > MCP, mint a token (name it and tick the scopes you want), and copy the server URL. Paste your token in place of <YOUR_TOKEN> - it is shown only once, at mint.
Server URL: https://api.selectx.com/mcp
{
"mcpServers": {
"selectx": {
"url": "https://api.selectx.com/mcp",
"headers": { "Authorization": "Bearer <YOUR_TOKEN>" }
}
}
}
Tool scopes
| Scope | What the tool can do |
|---|---|
mcp:read.analytics | Read dashboard analytics |
mcp:read.creators | Read the creator roster |
mcp:read.earnings | Read earnings |
mcp:read.billing | Read billing & credits |
mcp:read.growth | Read growth & tracking links |
mcp:read.schedule | Read the queue / schedule |
mcp:write.message | Draft & send a DM (destructive) |
mcp:write.note | Write a fan note |
mcp:write.schedule | Schedule a post / message (destructive) |
SX API
Base URL: https://api.selectx.com
Authenticate with a scoped bearer token. Every request is checked against the capability catalog and row-level security, so a token can only ever touch the installing agency's data.
curl https://api.selectx.com/v1/creators \
-H "Authorization: Bearer sx_live_..."
Endpoint paths above are representative. The full route reference ships with developer access; tokens are gated by the scopes below regardless of route.
Common scopes
| Scope | Grants |
|---|---|
messages:read / messages:send | Read threads / send a DM |
creators:read / creators:write | Read / update creators |
accounts:read | Read connected accounts |
vault:read / vault:write | Read / organize vault media |
stats:read / billing:read | Read statistics / billing |
credits:consume | Spend the agency's AI credits (metered) |
events:subscribe | Receive webhooks |
Webhooks & events
Subscribe to events and receive an outbound POST when they fire. Payloads are HMAC-signed (the same scheme as the Stripe webhooks already in the platform), so you can verify each event came from SelectX.
| Event | Fires when |
|---|---|
message.created | A fan message arrives |
creator.added | A creator is connected |
payment.succeeded | A payment is captured |
trial.ending | A trial is about to end |
Build a plugin
Plugins extend the app without touching core code. There are two execution models - pick the lowest-trust one that fits.
Model A - external app (default)
You host your code; SelectX integrates over the API, install-time consent, and outbound webhooks. SelectX never executes your code. An MCP server is exactly this shape, so "bring your own MCP server" is one plugin class.
Model B - in-app, sandboxed
UI panels load in a sandboxed iframe from your CDN and talk to the host only through a postMessage bridge that enforces scopes. Logic that must run in-process runs as WebAssembly with no ambient filesystem or network - only explicit, scope-gated host functions. SelectX never runs untrusted JS in its own process.
Extension points
| Slot / hook | Adds |
|---|---|
slot:nav | A nav item |
slot:settings.tab | A Settings tab |
slot:messages.rightRail | A card in the Messages right rail |
slot:dashboard.widget | A dashboard widget |
| Event hook | React to events (signed webhook or bridge callback) |
| Scheduled job | "Every morning" / "hourly" via the scheduled-task system |
Manifest
Every plugin ships a manifest - the source of truth for what it is, what it needs, and how it is billed. It is validated against a published JSON Schema on submit; installs pin a version (semver).
{
"id": "com.acme.smart-replies",
"name": "Smart Replies",
"version": "1.2.0",
"model": "external", // "external" | "sandboxed"
"scopes": ["messages:read", "messages:send", "creators:read"],
"surfaces": [
{ "slot": "messages.rightRail", "title": "Smart Replies",
"entry": "https://cdn.acme.dev/sr/panel.html" }
],
"events": ["message.created", "creator.added"],
"webhookUrl": "https://api.acme.dev/sxcrm/webhook",
"schedules": [{ "id": "daily-digest", "cron": "0 9 * * *" }],
"configSchema": { /* JSON Schema for the per-agency settings form */ },
"pricing": { "model": "subscription", "amountCents": 1500,
"interval": "month", "trialDays": 14 }
}
Marketplace & billing
Plug and play: installing grants the consented scopes and turns surfaces on; uninstalling revokes the token and removes them. Enable, disable, and reorder per agency.
- One bill. Paid plugins are billed by SelectX through the existing Stripe integration - agencies do not pay each developer separately.
- Revenue share. Developers are paid out of the marketplace.
- Free or paid. Set a subscription or one-time price in the manifest, or list for free.
Submit & review
Automated checks run on submit (manifest validation, scope sanity, bundle malware scan). Sensitive scopes (messages:send, billing, credits) and any code-execution plugin get human review. Published bundles are content-hashed and signed; the app refuses to load a surface whose hash does not match the registry.
Security model
- No credential scope. Nothing exposes raw OnlyFans sessions,
x-bc, or proxy secrets. You call mediated actions ("send DM"), never the raw session. - Default deny, least privilege. No scope means no access; the agency owner consents to each scope on install.
- Row-level security. A token scoped to agency X can never read agency Y - enforced at the database layer, not in plugin-aware code.
- Signed everything. Install tokens are unique, scoped, and revocable; webhooks are HMAC-signed both ways.
- Quotas & kill switch. Per-plugin rate limits, webhook volume caps, and AI-credit spend caps. An admin can disable a plugin globally, revoking all its tokens, if it misbehaves.
Get access
MCP tokens are available today in Settings > MCP. The SX API and plugin submission are in private developer beta - email hello@selectx.com to request access, and tell us which model you are building (MCP client, API integration, or plugin).