Agent Setup
Plug ONCE into your MCP client, authenticate once, and the agent can run discovery and tool calls normally.
Client configuration
The server URL is https://beta.once.app/api/mcp. If a client asks for a transport, choose Streamable HTTP (or just HTTP).
ChatGPT (Developer Mode)
ChatGPT has its own server URL: https://beta.once.app/api/mcp/chatgpt. It runs the same tools, shows your releases, store status, and streams as interactive cards in the chat, and lets you attach audio or cover art straight into the conversation instead of pasting links.
- Enable Developer Mode under Settings → Apps & Connectors → Advanced settings.
- Go to Settings → Connectors → Create and paste
https://beta.once.app/api/mcp/chatgpt. - Give it a name and description, choose OAuth for authentication, then click Create and sign in to ONCE when prompted.
- In a new chat, click + → More → Developer Mode and add the connector.
Developer Mode is in beta and requires an eligible ChatGPT plan. Try “show my ONCE releases” or “how are my streams this month?” to see the cards.
Claude (web)
- Open Settings → Connectors → Add custom connector.
- Paste the server URL and finish any auth prompts during discovery.
You can attach resources such as the schema from the connector menu once connected. Claude Desktop loads only local MCP servers from claude_desktop_config.json; ONCE is a remote server, so use the web connector, or a local bridge per the MCP local-server docs.
Cursor
Create .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"once": {
"url": "https://beta.once.app/api/mcp"
}
}
}Cline (VS Code)
Open the Cline panel → menu (⋮) → MCP Servers → Remote Servers → Add Server, with the server URL and transport Streamable HTTP. The JSON form is the same as Cursor’s with "type": "streamableHttp" added.
MCP client support evolves quickly; see the official MCP client list for others.
What happens after you connect
Most clients scan the server immediately: tools/list loads the tool catalog, resources/list shows the docs and schema, and some fetch the server card at /.well-known/mcp/server-card.json.
If a scan or action returns 401 Unauthorized, click Authenticate / Sign in and complete the browser flow. There is no separate in-chat login step, and once the flow finishes the client attaches the bearer token itself, so tool calls do not need an access_token argument.
Agents must read the metadata rules hitlist right after authentication: resources/read on mcp://docs/metadata-rules-hitlist, or the get_metadata_rules tool. It summarizes the ONCE metadata policies (generic artist names, writers, UPC, AI disclosure, cover songs) so the agent can guide the user correctly before submitting.
Example: one-prompt release
Once configured, you can tell the agent what you want in a single message:
“Connect to ONCE MCP, authenticate, upload cover.jpg as cover art and track.wav as audio, then submit a release called ‘My Song’ by ‘Artist Name’ in the Pop genre for February 1st 2026. The track is not explicit and I wrote it.”
The agent loads tools and resources, triggers sign-in, uploads the assets (or uses prepare_local_file_upload for large local files), calls submit_release, and returns the release ID and status. The steps below show what that looks like on the wire.
1. Read the rules and the schema
{
"jsonrpc": "2.0",
"id": 0,
"method": "resources/read",
"params": { "uri": "mcp://docs/metadata-rules-hitlist" }
}{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/read",
"params": { "uri": "mcp://schemas/release-required" }
}2. Upload or generate assets
| Method | Use it for |
|---|---|
upload_file | Small local files (base64, under ~3 MB) |
upload_file_from_url | Files at a public URL, any size |
prepare_local_file_upload | Large local files in Claude Code or Cursor |
generate_cover_art | AI album art from a prompt, or an edit of a previous generation |
Each returns a fileUrl to use in the submission. Details and limits are on Uploads; the cover art tool is documented in the API Reference.
3. Run AI detection (optional)
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "detect_audio_ai",
"arguments": { "fileUrl": "/api/files/audio/USER_ID/track.wav" }
}
}The response includes containsAi, an aiScore, and the predicted model (for example Suno or Udio) with its confidence. Results are cached per file, so repeat calls are cheap. detect_audio_pex_search_acr runs the registry-match check the same way.
4. Submit the release
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "submit_release",
"arguments": {
"release": {
"title": "My Release",
"primary_artist_name": "Artist Name",
"genre": "Pop",
"release_date": "2026-02-01",
"cover_art_file_url": "/api/files/cover-art/USER_ID/cover.jpg"
},
"tracks": [
{
"title": "My Release",
"primary_artist_name": "Artist Name",
"audio_file_url": "/api/files/audio/USER_ID/track.wav",
"explicit_flag": false,
"writers": [{ "name": "First Last" }]
}
],
"tokenOffset": false
}
}
}This is the minimal backward-compatible shape. New clients should also send store selection, label, C/P copyright credits, track_type, and role credits; see Schema.
Token Offset. The optional tokenOffset add-on (default false, top-level, not inside release) adds a flat +1 credit ($1) that funds tokenoffset.com to offset the AI environmental cost of the release. In an interactive chat the agent should offer it before submitting; running autonomously, it submits with false unless instructed otherwise.
5. Monitor and report
get_release_status: store delivery statusget_release_job: processing job statusget_release_metadata: current metadataget_performance_summary/get_release_performance: streaming analytics once distributed (passincludeTracks: truefor a per-song breakdown)
Checking and buying credits
get_profile gives the agent the user’s identity. quote_release prices the tracks it is about to submit against the live balance and reports whether they are covered — always gate on that rather than working the cost out yourself, since an estimate that lands high blocks a user whose balance is sufficient. If it reports a shortfall, create_credit_checkout_session with uiMode: "hosted" returns a Stripe Checkout URL:
{
"jsonrpc": "2.0",
"id": 9,
"method": "tools/call",
"params": {
"name": "create_credit_checkout_session",
"arguments": { "credits": 5, "uiMode": "hosted" }
}
}Agents with payment capability can complete it directly; otherwise the agent shares the link and the user pays, which is the only step that can require a human. Credits land by webhook once payment succeeds, so the agent polls quote_release until balance.covered is true and continues to submit_release. Bulk bundles (packageId from get_pricing) and auto-reload (set_autoreload) are covered in the API Reference.
Best practices
- Let discovery finish before asking for actions.
- Read resources early: the metadata rules hitlist first, then
mcp://docs/agent-guideandmcp://schemas/release-requiredbefore building payloads. - Pick the right upload path:
upload_file_from_urlfor big hosted files,prepare_local_file_uploadfor big local files. - Save drafts with
upsert_release_snapshotwhen collecting metadata over multiple turns. - Handle rate limits: on a 429, retry after
retryAfterSeconds. ONCE Insiders get higher ceilings, for example 900 PAT requests per minute versus 300. - Refresh if tools look stale: lists are static per session, so restart or re-add the server after an update.