MCPサーバー

OffStereo

io.github.andzar22/offstereo
メディア・コンテンツ 公開・接続可能 MCP 2026-07-28

このMCPでできること

Discovers music, builds playlists, creates narrated music stories, explores sample lineage, and manages playable listening sessions.

create_playlist
Create a playlist
Create one playlist from a natural-language idea or explicit track list. Call exactly once per listener turn: do not inspect the result and make a corrective second call or stack another playlist card in the same response. previewOnly=true returns one authoritative playlist that can be heard before saving and needs no music-service connection. After explicit approval, previewOnly=false with the approved tracks and the same concise editorial name creates one private playlist in the listener's active music service. Pass service only when the listener explicitly names Spotify or Apple Music. requiredArtists carries every artist the listener named as required. allowSecondPlaylist is true only for an explicit request for a separate additional playlist. Sign-in recovery preserves the exact request and pendingActionId for a safe retry.
外部アクセスあり
入力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'A concise editorial playlist title. Omit it when the listener did not supply a title; OffStereo derives one from the prompt.'}, 'count': {'type': 'number', 'description': 'Target song count for prompt-generated playlists (1-50, default 20).'}, 'prompt': {'type': 'string', 'description': "A conceptual playlist request, e.g. 'connect A Tribe Called Quest to Steely Dan'."}, 'tracks': {'type': 'array', 'items': {'type': 'object', 'required': ['artist', 'title'], 'properties': {'title': {'type': 'string'}, 'artist': {'type': 'string'}}}}, 'service': {'enum': ['spotify', 'apple_music'], 'type': 'string', 'description': 'Destination service. Pass only when the listener explicitly names one; otherwise OffStereo uses the active service on their account.'}, 'previewOnly': {'type': 'boolean', 'description': 'Resolve one unified playlist preview without saving or requiring a music-service connection. True when the listener asks to hear, inspect, or approve the songs before saving.'}, 'pendingActionId': {'type': 'string', 'description': 'Retry token returned by a prior auth_required result.'}, 'requiredArtists': {'type': 'array', 'items': {'type': 'string'}, 'description': "Every artist the user explicitly requires, especially endpoints in a request such as 'from Minnie Riperton to Solange'. OffStereo validates these before creating anything."}, 'allowSecondPlaylist': {'type': 'boolean', 'description': 'True only when the listener explicitly requests another separate playlist. Omit or pass false otherwise; this does not authorize a second create_playlist call in the same response.'}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'status'], 'properties': {'id': {'type': 'string'}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': "Always 'playlist'."}, 'status': {'type': 'string', 'description': 'preview, created, partial, auth_required, or failed.'}, 'tracks': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'webUrl': {'type': 'string'}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'message': {'type': 'string'}, 'privacy': {'type': 'object', 'description': 'Requested vs. confirmed privacy state.', 'additionalProperties': True}, 'service': {'enum': ['spotify', 'apple_music'], 'type': 'string'}, 'spotify': {'type': 'object', 'additionalProperties': True}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'retryTool': {'type': 'string'}, 'appleMusic': {'type': 'object', 'additionalProperties': True}, 'authReason': {'type': 'string'}, 'connectUrl': {'type': 'string', 'description': 'Sign-in URL when status is auth_required.'}, 'unresolved': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Songs that could not be confidently matched.'}, 'connections': {'type': 'object', 'additionalProperties': True}, 'pendingActionId': {'type': 'string', 'description': 'Retry token for a safe re-call after sign-in.'}}, 'description': 'A playlist result. status is preview (unsaved, hearable), created, partial, auth_required, or failed. Songs that could not be matched are reported in `unresolved` rather than substituted.', 'additionalProperties': True}
discover
Discover music
Discover genre-aware new releases, strong public-archive matches, or popular OffStereo shows. Call exactly once per listener request: put every positive genre into the same genres array, use [] when none were requested, and avoid one call or card per genre. query carries the listener's full wording, exclusions, counts, and no-padding constraint. Results remain relevant rather than padding a requested genre or archive search with unrelated rows. Dated music-history requests use music_today and are not a discover mode. playableOnly limits results to music that plays in ChatGPT. allowBuild and allowSave preserve a read-only request. The result card already includes song playback; a separate one-song card is for an explicit request for a dedicated song card.
読み取り専用 冪等
入力スキーマ
{'type': 'object', 'required': ['type', 'genres'], 'properties': {'type': {'enum': ['new_releases', 'archive', 'search', 'popular'], 'type': 'string', 'description': 'Discovery mode. search aliases archive; dated music-history requests use music_today.'}, 'limit': {'type': 'number', 'description': 'Maximum total results (1-20).'}, 'query': {'type': 'string', 'description': "Archive query, or the listener's release-discovery wording when it contains genres, balance, count, or no-padding constraints."}, 'genres': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Every positively requested genre; [] when the request is not genre-filtered. Results do not pad with unrelated genres.'}, 'allowSave': {'type': 'boolean', 'description': 'False preserves an explicit request not to create or save anything.'}, 'allowBuild': {'type': 'boolean', 'description': 'False preserves an explicit request not to create or build a story.'}, 'playableOnly': {'type': 'boolean', 'description': 'True limits results to music with audio that plays inside ChatGPT.'}, 'perGenreLimit': {'type': 'number', 'description': 'Maximum results from each named genre for a balanced new-release request.'}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'status'], 'properties': {'id': {'type': 'string'}, 'date': {'type': 'string', 'description': 'ISO date for music-today results.'}, 'note': {'type': 'string'}, 'exact': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Strong archive matches (show_search).'}, 'query': {'type': 'string'}, 'shows': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Related playable OffStereo shows.'}, 'title': {'type': 'string'}, 'events': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Dated music-history events (music-today).'}, 'object': {'type': 'string', 'description': 'discovery or show_search.'}, 'recent': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'status': {'type': 'string'}, 'webUrl': {'type': 'string'}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'related': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'releases': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'New releases (new_releases mode).'}, 'sections': {'type': 'array', 'items': {'type': 'string'}}, 'allowSave': {'type': 'boolean'}, 'allowBuild': {'type': 'boolean'}, 'archiveUrl': {'type': 'string'}, 'playableOnly': {'type': 'boolean'}, 'matchedGenres': {'type': 'array', 'items': {'type': 'string'}}, 'requestedGenres': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "A discovery card. object is 'discovery' (new releases or music-today) or 'show_search' (archive/popular). Which section arrays are populated depends on the mode.", 'additionalProperties': True}
explore_lineage
Explore sample lineage
Explore documented sample lineage. Pass artist + track for one song, or topic for one multi-song narrated lineage story. OffStereo only returns connections it can source and withholds uncertain matches rather than guessing.
入力スキーマ
{'type': 'object', 'properties': {'topic': {'type': 'string', 'description': "Artist/topic request such as 'notable samples used by Nas'."}, 'track': {'type': 'string', 'description': 'Track title for a track-level lineage.'}, 'artist': {'type': 'string', 'description': 'Artist for a track-level lineage.'}}}
出力スキーマ
{'type': 'object', 'required': ['id', 'object', 'status', 'title'], 'properties': {'id': {'type': 'string', 'description': 'Stable session id, reused for get_session and steer_session.'}, 'mode': {'enum': ['story', 'lineage', 'track'], 'type': 'string'}, 'queue': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Ordered narration and track items.'}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': 'playable_session, lineage, or lineage_show.'}, 'status': {'type': 'string', 'description': 'Lifecycle: building, partial, ready, failed, and similar.'}, 'thesis': {'type': 'string'}, 'webUrl': {'type': ['string', 'null']}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'chapters': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'progress': {'type': 'object', 'description': 'Current build stage and message.', 'additionalProperties': True}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'webLabel': {'type': ['string', 'null']}, 'citations': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'storyScope': {'type': ['object', 'null'], 'description': 'Count-level result assessment.', 'additionalProperties': True}, 'description': {'type': 'string'}, 'queueUpdate': {'type': 'object', 'description': 'Most recent model-authored queue change.', 'additionalProperties': True}, 'resumeStack': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'activeBranch': {'type': ['object', 'null'], 'additionalProperties': True}, 'nowPlayingContext': {'type': ['object', 'null'], 'additionalProperties': True}, 'playbackDirective': {'type': 'object', 'description': 'One-shot transport request the mounted card applies.', 'additionalProperties': True}}, 'description': 'A PlayableSession: one canonical OffStereo card with its ordered narration-and-song queue and live build/playback status.', 'additionalProperties': True}
get_session
Refresh the player
Application polling for an already-mounted OffStereo card. It refreshes one PlayableSession in place. A selected library story opens through make_playable(existingSessionId), while playback and contextual follow-ups use steer_session.
読み取り専用 冪等
入力スキーマ
{'type': 'object', 'required': ['sessionId'], 'properties': {'sessionId': {'type': 'string'}}}
出力スキーマ
{'type': 'object', 'required': ['id', 'object', 'status', 'title'], 'properties': {'id': {'type': 'string', 'description': 'Stable session id, reused for get_session and steer_session.'}, 'mode': {'enum': ['story', 'lineage', 'track'], 'type': 'string'}, 'queue': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Ordered narration and track items.'}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': 'playable_session, lineage, or lineage_show.'}, 'status': {'type': 'string', 'description': 'Lifecycle: building, partial, ready, failed, and similar.'}, 'thesis': {'type': 'string'}, 'webUrl': {'type': ['string', 'null']}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'chapters': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'progress': {'type': 'object', 'description': 'Current build stage and message.', 'additionalProperties': True}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'webLabel': {'type': ['string', 'null']}, 'citations': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'storyScope': {'type': ['object', 'null'], 'description': 'Count-level result assessment.', 'additionalProperties': True}, 'description': {'type': 'string'}, 'queueUpdate': {'type': 'object', 'description': 'Most recent model-authored queue change.', 'additionalProperties': True}, 'resumeStack': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'activeBranch': {'type': ['object', 'null'], 'additionalProperties': True}, 'nowPlayingContext': {'type': ['object', 'null'], 'additionalProperties': True}, 'playbackDirective': {'type': 'object', 'description': 'One-shot transport request the mounted card applies.', 'additionalProperties': True}}, 'description': 'A PlayableSession: one canonical OffStereo card with its ordered narration-and-song queue and live build/playback status.', 'additionalProperties': True}
get_story_audio
get story audio
Get a finished OffStereo story as ONE downloadable MP3 — the narrated story, without the records. Use this on any surface where a player card cannot render: send it as a WhatsApp or Telegram voice note, attach it to an email, play it over a phone or speaker, or hand it to someone as a file. The URL is public and needs no OffStereo account, so it can be forwarded to anyone. It is narration only, which is why it is freely shareable — say so rather than promising the songs; the songs are at webUrl. Prefer this over reading a summary aloud in your own synthetic voice: this is the produced story, already voiced. Only finished shows have audio — poll get_show until status is ready.
読み取り専用 冪等
入力スキーマ
{'type': 'object', 'properties': {'slug': {'type': 'string', 'description': "The show's slug, as find_shows returns it. Use either this or showId."}, 'showId': {'type': 'string', 'description': 'The show id, from find_shows, make_playable or get_show.'}}}
make_playable
Play music or a story
Create one playable OffStereo card for a direct standalone-song or narrated-story request. Discovery and Music Today already play their songs, so keep those results in their original card unless the listener asks for dedicated controls. experience=single_track returns exactly one recording with no narration or library save; pass artist plus track. experience=story progressively creates a sourced story; mode=fresh starts a new build. Pass artist plus album for an exact record and trackCount for an exact requested length. Spotify, Apple Music, and SoundCloud URLs are story seeds unless the listener requests only the recording. Playlist requests use create_playlist. existingSessionId opens a selected library story; get_session is reserved for card polling. The mounted card owns live progress and playback. Assistant prose should avoid restating transient stages such as building, recording, or still working because they become stale as the card updates, and should wait for Ready before stating final counts. A tool call opens the card without starting playback.
入力スキーマ
{'type': 'object', 'properties': {'mode': {'enum': ['auto', 'fresh'], 'type': 'string', 'description': 'fresh starts an explicitly new story; auto may reuse an exact strong match.'}, 'album': {'type': 'string', 'description': 'Exact album or EP title, paired with artist when the listener names or shows a specific record.'}, 'title': {'type': 'string', 'description': 'Short canonical artist, track, album, or subject title for the card, especially useful for an identified image or a prompt that also contains workflow instructions.'}, 'track': {'type': 'string', 'description': 'Exact song title, paired with artist for reliable single_track matching.'}, 'artist': {'type': 'string', 'description': 'Exact artist, paired with track for a one-song card or with album for an album-focused story.'}, 'length': {'enum': ['short', 'standard'], 'type': 'string', 'description': 'short fits an explicitly quick, brief, or concise narrated story and targets three narration-and-record chapters; standard keeps the full editorial arc.'}, 'prompt': {'type': 'string', 'description': 'What the listening experience should explain.'}, 'tracks': {'type': 'array', 'items': {'type': 'object', 'required': ['artist', 'title'], 'properties': {'title': {'type': 'string', 'description': 'Exact track title.'}, 'artist': {'type': 'string', 'description': 'Exact artist.'}}}, 'description': 'Optional: exact records the story should always include as playable tracks — e.g. every song a paired video names. They are pinned into the show in this order and curation fills the remaining slots up to trackCount, so a companion keeps the records the video discusses. Leave unset for normal curation.'}, 'sourceUrl': {'type': 'string', 'description': 'An http(s) article or source URL to adapt.'}, 'videoMode': {'type': 'boolean', 'description': 'When true, the story opens on a third-person editorial hook with no DJ greeting or time-of-day welcome — for a companion story paired with a video. Pair with an explicit `title` so page title, URL, and register all match the video.'}, 'experience': {'enum': ['story', 'single_track'], 'type': 'string', 'description': 'single_track means one immediate song card with no narration or story creation; story means the full progressive narrated experience.'}, 'sourceText': {'type': 'string', 'description': 'Source text or conversation context to adapt.'}, 'trackCount': {'type': 'number', 'description': 'Exact number of songs requested for a narrated story (2-12). Use 1 with experience=single_track.'}, 'resumeShowId': {'type': 'string', 'description': 'Rebuild an unfinished show in place, keeping its id and URL, instead of creating a second one. Pass the id of a show whose `retryable` is true. Rejected for a show that already finished or that belongs to someone else.'}, 'personalization': {'enum': ['library', 'none'], 'type': 'string', 'description': 'library uses connected-listener taste as retrieval seeds; none is the default.'}, 'existingSessionId': {'type': 'string', 'description': 'The chosen library story id for opening through the canonical player contract; get_session remains application polling.'}}}
出力スキーマ
{'type': 'object', 'required': ['id', 'object', 'status', 'title'], 'properties': {'id': {'type': 'string', 'description': 'Stable session id, reused for get_session and steer_session.'}, 'mode': {'enum': ['story', 'lineage', 'track'], 'type': 'string'}, 'queue': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Ordered narration and track items.'}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': 'playable_session, lineage, or lineage_show.'}, 'status': {'type': 'string', 'description': 'Lifecycle: building, partial, ready, failed, and similar.'}, 'thesis': {'type': 'string'}, 'webUrl': {'type': ['string', 'null']}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'chapters': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'progress': {'type': 'object', 'description': 'Current build stage and message.', 'additionalProperties': True}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'webLabel': {'type': ['string', 'null']}, 'citations': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'storyScope': {'type': ['object', 'null'], 'description': 'Count-level result assessment.', 'additionalProperties': True}, 'description': {'type': 'string'}, 'queueUpdate': {'type': 'object', 'description': 'Most recent model-authored queue change.', 'additionalProperties': True}, 'resumeStack': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'activeBranch': {'type': ['object', 'null'], 'additionalProperties': True}, 'nowPlayingContext': {'type': ['object', 'null'], 'additionalProperties': True}, 'playbackDirective': {'type': 'object', 'description': 'One-shot transport request the mounted card applies.', 'additionalProperties': True}}, 'description': 'A PlayableSession: one canonical OffStereo card with its ordered narration-and-song queue and live build/playback status.', 'additionalProperties': True}
manage_owned_item
Manage my library
Manage the signed-in listener's own OffStereo stories or service playlists. Removing an OffStereo story is a recoverable archive operation, and restore brings it back. Removing an owned Spotify playlist means remove from library because Spotify does not permanently delete playlists; the operation follows an explicit confirmation turn. Apple Music's public API does not expose playlist deletion, so that case returns an honest unsupported handoff. confirm=true records explicit confirmation of the named item and operation.
破壊的操作あり 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['itemType', 'id', 'action'], 'properties': {'id': {'type': 'string', 'description': 'OffStereo session id or saved playlist id.'}, 'action': {'enum': ['archive', 'restore', 'remove'], 'type': 'string'}, 'confirm': {'type': 'boolean', 'description': "Records the listener's explicit confirmation of the named destructive operation."}, 'service': {'enum': ['spotify', 'apple_music'], 'type': 'string', 'description': 'Required for playlists.'}, 'itemType': {'enum': ['story', 'playlist'], 'type': 'string'}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'status'], 'properties': {'id': {'type': 'string'}, 'title': {'type': 'string'}, 'action': {'type': 'string'}, 'object': {'type': 'string', 'description': "Always 'item_management'."}, 'status': {'type': 'string', 'description': 'confirmation_required, archived, restored, removed_from_library, unsupported, or auth_required.'}, 'webUrl': {'type': 'string'}, 'message': {'type': 'string'}, 'service': {'enum': ['spotify', 'apple_music'], 'type': 'string'}, 'itemType': {'enum': ['story', 'playlist'], 'type': 'string'}, 'authReason': {'type': 'string'}, 'connectUrl': {'type': 'string'}, 'recoverable': {'type': 'boolean'}}, 'description': 'Result of managing an owned OffStereo story or service playlist.', 'additionalProperties': True}
music_today
Music today
Call exactly once for a 'today in music' or dated music-history request. One response already combines album anniversaries, artist birthdays and memorials, current releases, current US song-chart context, and related playable OffStereo stories; use that one combined call rather than separate history, releases, charts, or shows calls. dateMode=today uses the listener's current day and omits date; dateMode=explicit pairs with a named YYYY-MM-DD date. limit is the maximum total across the combined response, playableOnly limits rows to music that plays in ChatGPT, and allowBuild=false plus allowSave=false preserves a read-only request. This is the only dated-music tool in the current schema.
読み取り専用 冪等
入力スキーマ
{'type': 'object', 'required': ['dateMode'], 'properties': {'date': {'type': 'string', 'description': 'ISO date YYYY-MM-DD for dateMode=explicit; absent for dateMode=today.'}, 'limit': {'type': 'number', 'description': 'Maximum total results across the already-combined response (1-20, default 8). Honor an explicit result count.'}, 'dateMode': {'enum': ['today', 'explicit'], 'type': 'string', 'description': "today represents the listener's current day; explicit represents one named calendar date."}, 'allowSave': {'type': 'boolean', 'description': 'False preserves an explicit request not to create or save anything.'}, 'allowBuild': {'type': 'boolean', 'description': 'False preserves an explicit request not to create or build a story.'}, 'playableOnly': {'type': 'boolean', 'description': 'True limits music-history results to rows with audio playable in ChatGPT.'}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'status'], 'properties': {'id': {'type': 'string'}, 'date': {'type': 'string', 'description': 'ISO date for music-today results.'}, 'note': {'type': 'string'}, 'exact': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Strong archive matches (show_search).'}, 'query': {'type': 'string'}, 'shows': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Related playable OffStereo shows.'}, 'title': {'type': 'string'}, 'events': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Dated music-history events (music-today).'}, 'object': {'type': 'string', 'description': 'discovery or show_search.'}, 'recent': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'status': {'type': 'string'}, 'webUrl': {'type': 'string'}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'related': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'releases': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'New releases (new_releases mode).'}, 'sections': {'type': 'array', 'items': {'type': 'string'}}, 'allowSave': {'type': 'boolean'}, 'allowBuild': {'type': 'boolean'}, 'archiveUrl': {'type': 'string'}, 'playableOnly': {'type': 'boolean'}, 'matchedGenres': {'type': 'array', 'items': {'type': 'string'}}, 'requestedGenres': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "A discovery card. object is 'discovery' (new releases or music-today) or 'show_search' (archive/popular). Which section arrays are populated depends on the mode.", 'additionalProperties': True}
my_offstereo
My OffStereo
Call once to return the signed-in listener's OffStereo library overview, currently including their completed, unarchived shows. This is the primary personal-library tool.
読み取り専用 冪等
入力スキーマ
{'type': 'object', 'properties': {'limit': {'type': 'number', 'description': 'Shows to return (1-50).'}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'shows'], 'properties': {'id': {'type': 'string'}, 'shows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'title': {'type': 'string'}, 'object': {'type': 'string'}, 'status': {'type': 'string'}, 'webUrl': {'type': 'string'}, 'coverUrl': {'type': ['string', 'null']}, 'trackCount': {'type': 'number'}}, 'additionalProperties': True}}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': "Always 'library'."}, 'status': {'type': 'string'}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}}, 'description': "The signed-in listener's OffStereo library overview (their completed, unarchived shows).", 'additionalProperties': True}
prepare_episode
Prepare a Spotify episode
Prepare one finished OffStereo story to become a private Spotify episode after the listener explicitly asks. OffStereo packages its completed intro, ordered narration, sign-off, branded title, show notes, OffStereo cover, chapters, and song timeline, then returns an honest handoff: the episode is not in Spotify until the listener finishes with Spotify's Save to Spotify helper on their own computer. Use the active or selected story's sessionId. This is for a narrated story, not a playlist or an unfinished build.
冪等
入力スキーマ
{'type': 'object', 'required': ['sessionId'], 'properties': {'sessionId': {'type': 'string', 'description': "The completed OffStereo story id from the active player or the listener's library."}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'status'], 'properties': {'note': {'type': 'string'}, 'show': {'type': 'object', 'description': 'The finished episode: id, title, description, coverUrl, episodeAudioUrl, durationMs, and audio metadata.', 'additionalProperties': True}, 'object': {'type': 'string', 'description': "Always 'spotify_episode'."}, 'status': {'type': 'string', 'description': "Always 'prepared'."}, 'chapters': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Final reconciled chapter markers.'}, 'requires': {'type': 'object', 'description': 'External dependencies the caller provides: the save-to-spotify CLI and network access, with install and source details.', 'additionalProperties': True}, 'timeline': {'type': 'object', 'description': 'Ordered timeline items plus completeness and chapter status.', 'additionalProperties': True}, 'howToPublish': {'type': 'object', 'description': 'Editorial, audio, safety, and step-by-step publish guidance.', 'additionalProperties': True}, 'publishState': {'type': 'object', 'description': 'Idempotent publish receipt location and resume rules.', 'additionalProperties': True}, 'omittedTracks': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Songs disclosed as omitted from the timeline.'}, 'spotifyTarget': {'type': 'object', 'description': 'Target Spotify show identity and settings.', 'additionalProperties': True}, 'desktopHandoff': {'type': 'object', 'description': 'A ready-to-forward request for a desktop agent to finish the private save.', 'additionalProperties': True}, 'includedTracks': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}}, 'description': 'A prepared Spotify episode handoff bundle. OffStereo produces the finished audio and metadata; the episode is not in Spotify until the listener completes the save on their own computer.', 'additionalProperties': True}
save_session
Save the story playlist
Explicitly save the matched music from one listening session as a private playlist in the listener's active music service. Pass service only when the listener explicitly names Spotify or Apple Music. Unmatched songs are excluded and reported. If sign-in is needed, OffStereo preserves the request for one safe retry.
外部アクセスあり
入力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'service': {'enum': ['spotify', 'apple_music'], 'type': 'string'}, 'sessionId': {'type': 'string'}, 'pendingActionId': {'type': 'string'}}}
出力スキーマ
{'type': 'object', 'required': ['object', 'status'], 'properties': {'id': {'type': 'string'}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': "Always 'playlist'."}, 'status': {'type': 'string', 'description': 'preview, created, partial, auth_required, or failed.'}, 'tracks': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'webUrl': {'type': 'string'}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'message': {'type': 'string'}, 'privacy': {'type': 'object', 'description': 'Requested vs. confirmed privacy state.', 'additionalProperties': True}, 'service': {'enum': ['spotify', 'apple_music'], 'type': 'string'}, 'spotify': {'type': 'object', 'additionalProperties': True}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'retryTool': {'type': 'string'}, 'appleMusic': {'type': 'object', 'additionalProperties': True}, 'authReason': {'type': 'string'}, 'connectUrl': {'type': 'string', 'description': 'Sign-in URL when status is auth_required.'}, 'unresolved': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Songs that could not be confidently matched.'}, 'connections': {'type': 'object', 'additionalProperties': True}, 'pendingActionId': {'type': 'string', 'description': 'Retry token for a safe re-call after sign-in.'}}, 'description': 'A playlist result. status is preview (unsaved, hearable), created, partial, auth_required, or failed. Songs that could not be matched are reported in `unresolved` rather than substituted.', 'additionalProperties': True}
steer_session
Steer the listening session
Control and contextual follow-ups for the active player: pause, resume, skip, play the next song, append one exact next song, adjust the music level, explain why a song is present, open an explicitly requested documented sample lineage, or return to the story. The result updates the mounted card in place. For an AI-DJ transition to a newly chosen record, pass queueTrack with exact artist and title; OffStereo resolves it and appends it to this same widget so the current song can finish and auto-advance. Keeping the transition in this queue avoids a second make_playable call. Use instruction='Queue this as the next song without interrupting the current song' to queue ahead, or 'Play this next now' to append and immediately advance. A why-this-song question preserves the queue. sessionId identifies the active session, and activeItemId plus positionMs preserve exact continuity when the card supplies them.
入力スキーマ
{'type': 'object', 'required': ['instruction'], 'properties': {'sessionId': {'type': 'string'}, 'positionMs': {'type': 'number'}, 'queueTrack': {'type': 'object', 'required': ['artist', 'title'], 'properties': {'title': {'type': 'string'}, 'artist': {'type': 'string'}, 'reason': {'type': 'string', 'description': 'A concise, factual transition reason for why this record follows the current one.'}}, 'description': 'One exact new record to append to the active widget queue. Use this instead of opening another one-song widget when the listener asks the AI DJ to choose what comes next.'}, 'instruction': {'type': 'string'}, 'activeItemId': {'type': 'string'}, 'playbackState': {'enum': ['playing', 'paused'], 'type': 'string'}, 'acknowledgeDirectiveId': {'type': 'string', 'description': 'Mounted-card acknowledgement for the exact one-shot playback directive it has finished applying. Periodic cursor syncs omit this field.'}}}
出力スキーマ
{'type': 'object', 'required': ['id', 'object', 'status', 'title'], 'properties': {'id': {'type': 'string', 'description': 'Stable session id, reused for get_session and steer_session.'}, 'mode': {'enum': ['story', 'lineage', 'track'], 'type': 'string'}, 'queue': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Ordered narration and track items.'}, 'title': {'type': 'string'}, 'object': {'type': 'string', 'description': 'playable_session, lineage, or lineage_show.'}, 'status': {'type': 'string', 'description': 'Lifecycle: building, partial, ready, failed, and similar.'}, 'thesis': {'type': 'string'}, 'webUrl': {'type': ['string', 'null']}, 'actions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'chapters': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'progress': {'type': 'object', 'description': 'Current build stage and message.', 'additionalProperties': True}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'webLabel': {'type': ['string', 'null']}, 'citations': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'storyScope': {'type': ['object', 'null'], 'description': 'Count-level result assessment.', 'additionalProperties': True}, 'description': {'type': 'string'}, 'queueUpdate': {'type': 'object', 'description': 'Most recent model-authored queue change.', 'additionalProperties': True}, 'resumeStack': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'activeBranch': {'type': ['object', 'null'], 'additionalProperties': True}, 'nowPlayingContext': {'type': ['object', 'null'], 'additionalProperties': True}, 'playbackDirective': {'type': 'object', 'description': 'One-shot transport request the mounted card applies.', 'additionalProperties': True}}, 'description': 'A PlayableSession: one canonical OffStereo card with its ordered narration-and-song queue and live build/playback status.', 'additionalProperties': True}
追加
get_story_audio
2026年9月21日2:50
変更
make_playable
2026年9月21日2:50
追加
my_offstereo
2026年9月17日12:40
追加
manage_owned_item
2026年9月17日12:40
追加
prepare_episode
2026年9月17日12:40
追加
save_session
2026年9月17日12:40
追加
create_playlist
2026年9月17日12:40
追加
explore_lineage
2026年9月17日12:40
追加
music_today
2026年9月17日12:40
追加
discover
2026年9月17日12:40
追加
steer_session
2026年9月17日12:40
追加
get_session
2026年9月17日12:40
追加
make_playable
2026年9月17日12:40