AI & Automation
Copy for Your Agent

Copy for Your Agent

A single self-contained block, meant to be copied and pasted straight into your AI agent's context or system prompt so it can read (and, for the narrow write paths listed, propose changes to) your local Tape hub. Use the copy icon in the corner of the block below — everything it needs is inside it; it does not depend on any other page.

For the full, browsable endpoint list (SSE feeds, remote/tunnel, diagnostics, license, sharing) see API Reference for Agents and the AI Integration Guide instead — this page is intentionally a condensed subset.

# Tape — Music Hub Agent Context
 
Tape is a self-hosted music library and streaming app (desktop hub + mobile
companion). This tells you how to read, and narrowly propose changes to, a
running Tape hub over its local REST API.
 
## Connection
 
- Base URL (installed Desktop app): http://localhost:38472 — fixed, not
  user-configurable from the app UI. You can hardcode it.
- Base URL (Docker/server deployment): ask whoever deployed it for the actual
  host/port. Only Docker deployments can override the port, via the `PORT`
  environment variable at container start.
- Format: JSON over REST, plus Server-Sent Events (SSE) for live updates.
- Data directory: ~/.music-hub
 
## Auth
 
- Same machine as Tape (loopback): no auth needed, full read access.
- Same Wi-Fi/LAN: most reads are open; writes may need pairing or
  MUSIC_HUB_API_TOKEN.
- Remote/proxied access: needs an active license plus a bearer token.
 
Pairing flow (only for remote/cross-device agents):
1. Arm a pairing window from the desktop UI: Settings > Pairing.
2. POST /api/auth/pair with {"pairingCode": "...", "deviceId": "...",
   "deviceName": "..."} -> returns accessToken + refreshToken.
3. Send `Authorization: Bearer <accessToken>` on subsequent requests.
4. POST /api/auth/refresh with {"deviceId": "...", "refreshToken": "..."}
   before it expires.
 
Before anything else, check health:
GET /api/ping
GET /api/info   -> check databaseHealth.status == "healthy"; most library
routes return 503 database_unavailable otherwise.
 
## Reading the library
 
- GET /api/library/stats — counts, sizes, distributions.
- GET /api/library/filters — distinct genres, tags, formats, BPM/year
  ranges, and folders actually present in the library.
- GET /browse — configured source folders at root; GET /browse?path=<folder>
  to walk one folder's contents.
- GET /api/tracks?limit=50&offset=0 — paginated tracks; filter with genre=,
  year=, bpm=, tags=, folder=, sort=; full-text with match=<query>.
- GET /api/tracks/:id — one track (core fields below).
- GET /api/tracks/:id/metadata — overlay: genres[], tags[], enrichment
  provenance, ISRC, barcode, MBIDs. Call it directly; its shape is not
  covered by the core fields table below.
- GET /api/albums, GET /api/albums/:id, GET /api/albums/:id/tracks
- GET /api/artists, GET /api/artists/:id, GET /api/artists/:id/tracks,
  GET /api/artists/:id/albums
- GET /api/labels, GET /api/labels/:id
- GET /api/playlists, GET /api/playlists/:id, GET /api/playlists/:id/tracks
- GET /api/search?q=...&type=tracks|albums|artists&limit=50
 
### Core track fields (GET /api/tracks/:id, and list-endpoint `tracks[]`)
 
| Field | Type | Description |
| --- | --- | --- |
| id | string | Unique track ID |
| title | string | Track title |
| artist | string | Primary artist |
| album | string | Album name |
| albumArtist | string? | Album artist |
| year | number? | Release year |
| genre | string? | Genre tag |
| trackNumber | number? | Track position in album |
| duration | number | Duration in seconds |
| bpm | number? | Beats per minute |
| bitrate | number? | Bitrate in kbps |
| format | string | File format (mp3, flac, etc.) |
| filePath | string | Absolute path to file |
| lastPlayed | string? | ISO 8601 timestamp |
| dateAdded | string | ISO 8601 timestamp |
 
There is no vector/embedding index in Tape's database. Reason over these
relational fields, not similarity vectors.
 
## Playback (optional)
 
- GET /api/playback/state — current queue.
- POST /api/agent/play {"trackIds": [...], "startIndex": 0}
- POST /api/agent/queue {"trackIds": [...]}
- GET /api/analytics/play-history?days=7&limit=100
 
## Proposing changes
 
The host is always the one that writes. These endpoints let you propose
field-level metadata changes; nothing here moves or renames a file.
 
- PUT /api/tracks/:id/metadata/curated {"genres": [...], "tags": [...],
  "styles": [...]}
- PUT /api/tracks/:id/primary-metadata {"title": "...", "artist": "...",
  "album": "..."}
- PUT /api/tracks/:id/metadata/overrides / DELETE same path
- POST /api/tracks/:id/re-enrich/search and /apply — MusicBrainz/Discogs
  re-enrichment candidates.
 
## What this API cannot do yet
 
- No endpoint moves or renames a file on disk. Physical folder/file
  reorganization is intentionally host-only and is not exposed via this API
  or the plugin SDK today. Do not attempt it through any other route
  (direct filesystem or database writes, etc.) — wait for a released
  organize endpoint.
- No /api/suggestions or /api/tracks/:id/similar.
- No /mcp server, and no /api/ai/suggest or /api/ai/patterns.
(These three don't exist despite appearing in some older/internal drafts.)
 
## Errors
 
401 auth missing/expired. 403 license required, or a local-only endpoint
called remotely. 404 not found. 409 pairing_not_armed — pairing window not
active. 503 database_unavailable — check /api/info's databaseHealth first.
 
## Full reference
 
This is a condensed snapshot, not the complete endpoint list. For SSE feeds,
remote/tunnel, diagnostics, license and sharing routes, see
https://docs.tapemusicsuite.com/agents/api-reference and
https://docs.tapemusicsuite.com/agents/integration.