gabriel / musehub public
mcp.md markdown
1645 lines 53.0 KB
fe6ae740 docs + stress tests: elicitation bypass, ingest_push snapshots, MCP ref… Gabriel Cardona <cgcardona@gmail.com> 2d ago
1 # MuseHub MCP Reference
2
3 > Protocol version: **2025-11-25** | Implementation: pure-Python async, no external MCP SDK
4
5 MuseHub treats AI agents as first-class citizens. The MCP integration gives agents complete capability parity with the web UI: they can browse, search, compose, review, and publish — over a standard protocol that every major agent runtime supports.
6
7 MCP 2025-11-25 adds the full **Streamable HTTP transport** (`GET /mcp` SSE push channel, session management, Origin security) and **Elicitation** (server-initiated user input via form and URL modes), enabling real-time interactive tool calls that interview users mid-execution.
8
9 ---
10
11 ## Table of Contents
12
13 1. [Architecture](#architecture)
14 2. [Transports](#transports)
15 3. [Authentication](#authentication)
16 4. [Session Management](#session-management)
17 5. [Elicitation](#elicitation)
18 6. [Tools — 40 total](#tools)
19 - [Read Tools (20)](#read-tools-20)
20 - [Write Tools (15)](#write-tools-15)
21 - [Elicitation-Powered Tools (5)](#elicitation-powered-tools-5)
22 7. [Resources — 29 total](#resources)
23 - [Static Resources (12)](#static-resources-12)
24 - [Templated Resources (17)](#templated-resources-17)
25 8. [Prompts — 10 total](#prompts)
26 9. [Error Handling](#error-handling)
27 10. [Usage Patterns](#usage-patterns)
28 11. [Architecture Diagrams](#architecture-diagrams)
29
30 ---
31
32 ## Architecture
33
34 ```
35 MCP Client (Cursor, Claude Desktop, any SDK)
36
37 ├─ HTTP POST /mcp (all client→server)
38 ├─ HTTP GET /mcp (SSE push, server→client)
39 ├─ HTTP DELETE /mcp (session termination)
40 └─ stdio python -m musehub.mcp.stdio_server (local dev)
41
42 musehub/api/routes/mcp.py ← Streamable HTTP transport (2025-11-25)
43
44 musehub/mcp/dispatcher.py ← async JSON-RPC 2.0 engine
45
46 ┌───────┼───────────────┬────────────────┐
47 │ │ │ │
48 tools/call resources/read prompts/get notifications/*
49 │ │ │ │
50 Read executors Resource handlers Prompt Session/Elicitation
51 (musehub_mcp_executor.py) (resources.py) assembler (session.py)
52 Write executors (context.py)
53 Elicitation tools
54 (mcp/write_tools/elicitation_tools.py)
55
56 AsyncSession → Postgres
57 ```
58
59 The dispatcher speaks JSON-RPC 2.0 directly. The HTTP envelope is always `200 OK` — tool errors are signalled via `isError: true` on the content block, not via HTTP status codes. Notifications (no `id` field) return `202 Accepted` with an empty body. Elicitation-powered tools return `text/event-stream` so the server can push `elicitation/create` events mid-call.
60
61 ---
62
63 ## Transports
64
65 ### HTTP Streamable — Full 2025-11-25 Transport
66
67 #### `POST /mcp`
68
69 The production transport. Accepts `application/json`. Returns `application/json` for most requests, or `text/event-stream` for elicitation-powered tool calls.
70
71 ```http
72 POST /mcp HTTP/1.1
73 Content-Type: application/json
74 Authorization: Bearer <jwt>
75 Mcp-Session-Id: <session-id> ← required after initialize
76 MCP-Protocol-Version: 2025-11-25 ← optional; validated if present
77
78 {"jsonrpc":"2.0","id":1,"method":"tools/list"}
79 ```
80
81 **Batch requests** — send a JSON array; responses are returned as an array in the same order (notifications are filtered out):
82
83 ```http
84 POST /mcp
85 [
86 {"jsonrpc":"2.0","id":1,"method":"tools/list"},
87 {"jsonrpc":"2.0","id":2,"method":"resources/list"}
88 ]
89 ```
90
91 **Notifications** (no `id`) return `202 Accepted` with an empty body.
92
93 #### `GET /mcp` — SSE Push Channel
94
95 Persistent server-to-client event stream. Required for receiving elicitation requests and progress notifications outside of an active tool call.
96
97 ```http
98 GET /mcp HTTP/1.1
99 Accept: text/event-stream
100 Mcp-Session-Id: <session-id>
101 Last-Event-ID: <last-seen-event-id> ← optional; triggers replay
102 ```
103
104 Returns `text/event-stream`. Server pushes:
105 - `notifications/progress` — tool progress updates
106 - `elicitation/create` — server-initiated user input requests
107 - `notifications/elicitation/complete` — URL-mode OAuth completion signals
108 - `: heartbeat` — comment every 15 s to keep proxies alive
109
110 #### `DELETE /mcp` — Session Termination
111
112 ```http
113 DELETE /mcp HTTP/1.1
114 Mcp-Session-Id: <session-id>
115 ```
116
117 Returns `200 OK`. Closes all open SSE streams and cancels pending elicitation Futures for the session.
118
119 ### stdio — `python -m musehub.mcp.stdio_server`
120
121 The local dev and Cursor IDE transport. Reads newline-delimited JSON from `stdin`, writes JSON-RPC responses to `stdout`, logs to `stderr`.
122
123 **Cursor IDE integration** — create or update `.cursor/mcp.json` in your workspace:
124
125 ```json
126 {
127 "mcpServers": {
128 "musehub": {
129 "command": "python",
130 "args": ["-m", "musehub.mcp.stdio_server"],
131 "cwd": "/path/to/musehub"
132 }
133 }
134 }
135 ```
136
137 The stdio server runs without auth (trusted local process). Write tools are available unconditionally.
138
139 ---
140
141 ## Authentication
142
143 | Context | How |
144 |---------|-----|
145 | HTTP transport — read tools + public resources | No auth required |
146 | HTTP transport — write / elicitation tools | `Authorization: Bearer <jwt>` |
147 | HTTP transport — private repo resources | `Authorization: Bearer <jwt>` |
148 | stdio transport | No auth (trusted process) |
149
150 The JWT is the same token issued by the MuseHub auth endpoints (`POST /api/v1/auth/token`). The `sub` claim is used as the acting `user_id` for all write operations.
151
152 Attempting a write tool without a valid token returns a JSON-RPC error (`code: -32001`, `message: "Authentication required for write tools"`).
153
154 ---
155
156 ## Session Management
157
158 Session management is required for elicitation and the GET /mcp SSE push channel.
159
160 **Creating a session:**
161
162 ```http
163 POST /mcp
164 {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{"elicitation":{"form":{},"url":{}}}}}
165 ```
166
167 Response includes:
168 ```http
169 Mcp-Session-Id: <cryptographically-secure-session-id>
170 ```
171
172 **Using the session:** include `Mcp-Session-Id` in all subsequent requests. Sessions expire after 1 hour of inactivity.
173
174 **Ending a session:** `DELETE /mcp` with the `Mcp-Session-Id` header.
175
176 **Security:** All requests are validated against an Origin allowlist (`localhost` always permitted; production: `musehub.app`). Requests from unlisted Origins are rejected with `403 Forbidden`.
177
178 ---
179
180 ## Elicitation
181
182 Elicitation is a MCP 2025-11-25 feature that allows the server to request structured input from the user *mid-tool-call*. MuseHub supports both modes:
183
184 ### Form Mode
185
186 The server sends an `elicitation/create` request with a restricted JSON Schema object describing the fields to collect. The client shows a form to the user, then sends the response back via `POST /mcp`.
187
188 ```
189 Agent MuseHub MCP
190 │ │
191 │ POST tools/call │
192 │ (musehub_create_with_preferences)
193 │──────────────────────────►│
194 │ │ opens SSE stream
195 │◄──────────────────────────│
196 │ SSE: elicitation/create │
197 │ {mode:"form", schema:{ │
198 │ key, tempo, mood, ...}}│
199 │◄──────────────────────────│
200 │ [user fills form] │
201 │ POST elicitation result │
202 │ {action:"accept", │
203 │ content:{key:"Dm",...}} │
204 │──────────────────────────►│
205 │ │ tool continues
206 │ SSE: tools/call response │
207 │◄──────────────────────────│
208 ```
209
210 ### URL Mode
211
212 The server sends an `elicitation/create` request with `mode:"url"` directing the user to a MuseHub OAuth page. After the user completes the flow, the callback fires `notifications/elicitation/complete` into the agent's SSE stream.
213
214 ```
215 Agent MuseHub MCP Browser
216 │ │ │
217 │ POST musehub_connect_ │ │
218 │ streaming_platform │ │
219 │──────────────────────────►│ │
220 │ SSE: elicitation/create │ │
221 │ {mode:"url", url:"https://musehub.app/mcp/connect/spotify?..."}
222 │◄──────────────────────────│ │
223 │ [client opens URL] │──────────────────────►│
224 │ │ User authorises OAuth│
225 │ │◄──────────────────────│
226 │ SSE: notifications/ │ │
227 │ elicitation/complete │ │
228 │◄──────────────────────────│ │
229 │ SSE: tools/call response │ │
230 │◄──────────────────────────│ │
231 ```
232
233 ### Elicitation Schemas
234
235 MuseHub provides five musical form schemas:
236
237 | Schema key | Fields |
238 |------------|--------|
239 | `compose_preferences` | `key` (24 options), `tempo_bpm`, `time_signature`, `mood` (10 options), `genre` (10 options), `reference_artist`, `duration_bars`, `include_modulation` |
240 | `repo_creation` | `daw` (10 options), `primary_genre`, `key_signature`, `tempo_bpm`, `is_collab`, `collaborator_handles`, `initial_readme` |
241 | `pr_review_focus` | `dimension_focus` (all/melodic/harmonic/rhythmic/structural/dynamic), `review_depth` (quick/standard/thorough), `check_harmonic_tension`, `check_rhythmic_consistency`, `reviewer_note` |
242 | `release_metadata` | `tag`, `title`, `release_notes`, `is_prerelease`, `highlight` |
243 | `platform_connect_confirm` | `platform` (8 streaming services), `confirm` |
244
245 ---
246
247 ## Tools
248
249 All 40 tools use `server_side: true`. The JSON-RPC envelope is always a success response — errors are represented inside the content block via `isError: true`.
250
251 ### Repo identification: `repo_id` or `owner` + `slug`
252
253 All repo-scoped tools accept either form. The dispatcher resolves `owner` + `slug` to a `repo_id` transparently — agents can use human-readable names without a prior lookup step:
254
255 ```json
256 { "repo_id": "abc-123-uuid" }
257 // or equivalently:
258 { "owner": "cgcardona", "slug": "jazz-standards" }
259 ```
260
261 ### Calling a tool
262
263 ```json
264 {
265 "jsonrpc": "2.0",
266 "id": 1,
267 "method": "tools/call",
268 "params": {
269 "name": "musehub_get_context",
270 "arguments": { "owner": "cgcardona", "slug": "jazz-standards" }
271 }
272 }
273 ```
274
275 Response:
276
277 ```json
278 {
279 "jsonrpc": "2.0",
280 "id": 1,
281 "result": {
282 "content": [{ "type": "text", "text": "{\"name\":\"my-song\", ...}" }],
283 "isError": false
284 }
285 }
286 ```
287
288 ---
289
290 ### Read Tools (20)
291
292 #### `musehub_get_context`
293
294 **Start here.** Full AI context document for a repo — domain plugin (scoped_id, dimensions, capabilities), branches, recent commits, and artifact inventory in a single call. Always call this before creating or modifying state. For computed analytics, follow up with `musehub_get_domain_insights`. For the full viewer payload, follow up with `musehub_get_view`.
295
296 | Parameter | Type | Required | Description |
297 |-----------|------|----------|-------------|
298 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
299 | `owner` | string | no | Owner username (use with `slug`) |
300 | `slug` | string | no | Repository slug (use with `owner`) |
301
302 ---
303
304 #### `musehub_list_branches`
305
306 All branches with their head commit IDs and timestamps.
307
308 | Parameter | Type | Required | Description |
309 |-----------|------|----------|-------------|
310 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
311 | `owner` | string | no | Owner username (use with `slug`) |
312 | `slug` | string | no | Repository slug (use with `owner`) |
313
314 ---
315
316 #### `musehub_list_commits`
317
318 Paginated commit history, newest first.
319
320 | Parameter | Type | Required | Description |
321 |-----------|------|----------|-------------|
322 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
323 | `owner` | string | no | Owner username (use with `slug`) |
324 | `slug` | string | no | Repository slug (use with `owner`) |
325 | `branch` | string | no | Branch name filter |
326 | `limit` | integer | no | Max commits (default 20) |
327
328 ---
329
330 #### `musehub_read_file`
331
332 Metadata for a single artifact (MIDI, MP3, WebP, etc.) at a given commit.
333
334 | Parameter | Type | Required | Description |
335 |-----------|------|----------|-------------|
336 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
337 | `owner` | string | no | Owner username (use with `slug`) |
338 | `slug` | string | no | Repository slug (use with `owner`) |
339 | `path` | string | yes | File path within the repo |
340 | `commit_id` | string | no | Commit SHA (defaults to HEAD) |
341
342 ---
343
344 #### `musehub_search`
345
346 Keyword/path search over commits and file paths within a repo.
347
348 | Parameter | Type | Required | Description |
349 |-----------|------|----------|-------------|
350 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
351 | `owner` | string | no | Owner username (use with `slug`) |
352 | `slug` | string | no | Repository slug (use with `owner`) |
353 | `query` | string | yes | Search terms |
354 | `mode` | string | no | `"path"` (default) or `"commit"` |
355
356 ---
357
358 #### `musehub_get_commit`
359
360 Single commit detail with the full snapshot manifest (all file paths and content hashes at that point in history).
361
362 | Parameter | Type | Required | Description |
363 |-----------|------|----------|-------------|
364 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
365 | `owner` | string | no | Owner username (use with `slug`) |
366 | `slug` | string | no | Repository slug (use with `owner`) |
367 | `commit_id` | string | yes | Commit SHA |
368
369 ---
370
371 #### `musehub_compare`
372
373 Musical diff between two refs — returns per-dimension change scores (harmony, rhythm, groove, key, tempo) and a list of changed file paths.
374
375 | Parameter | Type | Required | Description |
376 |-----------|------|----------|-------------|
377 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
378 | `owner` | string | no | Owner username (use with `slug`) |
379 | `slug` | string | no | Repository slug (use with `owner`) |
380 | `base_ref` | string | yes | Base branch, tag, or commit SHA |
381 | `head_ref` | string | yes | Head branch, tag, or commit SHA |
382
383 ---
384
385 #### `musehub_list_issues`
386
387 Issues with optional state, label, and assignee filters.
388
389 | Parameter | Type | Required | Description |
390 |-----------|------|----------|-------------|
391 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
392 | `owner` | string | no | Owner username (use with `slug`) |
393 | `slug` | string | no | Repository slug (use with `owner`) |
394 | `state` | string | no | `"open"` (default) or `"closed"` |
395 | `label` | string | no | Label name filter |
396 | `assignee` | string | no | Assignee username filter |
397
398 ---
399
400 #### `musehub_get_issue`
401
402 Single issue with its full comment thread.
403
404 | Parameter | Type | Required | Description |
405 |-----------|------|----------|-------------|
406 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
407 | `owner` | string | no | Owner username (use with `slug`) |
408 | `slug` | string | no | Repository slug (use with `owner`) |
409 | `issue_number` | integer | yes | Issue number |
410
411 ---
412
413 #### `musehub_list_prs`
414
415 Pull requests with optional state and base branch filters.
416
417 | Parameter | Type | Required | Description |
418 |-----------|------|----------|-------------|
419 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
420 | `owner` | string | no | Owner username (use with `slug`) |
421 | `slug` | string | no | Repository slug (use with `owner`) |
422 | `state` | string | no | `"open"` (default), `"closed"`, or `"merged"` |
423 | `base` | string | no | Target branch filter |
424
425 ---
426
427 #### `musehub_get_pr`
428
429 Single PR with all inline comments and reviews.
430
431 | Parameter | Type | Required | Description |
432 |-----------|------|----------|-------------|
433 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
434 | `owner` | string | no | Owner username (use with `slug`) |
435 | `slug` | string | no | Repository slug (use with `owner`) |
436 | `pr_number` | integer | yes | Pull request number |
437
438 ---
439
440 #### `musehub_list_releases`
441
442 All releases for a repo with asset counts and timestamps.
443
444 | Parameter | Type | Required | Description |
445 |-----------|------|----------|-------------|
446 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
447 | `owner` | string | no | Owner username (use with `slug`) |
448 | `slug` | string | no | Repository slug (use with `owner`) |
449
450 ---
451
452 #### `musehub_search_repos`
453
454 Discover public repos by text query or musical attributes.
455
456 | Parameter | Type | Required | Description |
457 |-----------|------|----------|-------------|
458 | `query` | string | no | Text search query |
459 | `key` | string | no | Musical key filter (e.g. `"C major"`) |
460 | `tempo_min` | integer | no | Minimum BPM |
461 | `tempo_max` | integer | no | Maximum BPM |
462 | `tags` | array of strings | no | Tag filters |
463 | `limit` | integer | no | Max results (default 20) |
464
465 ---
466
467 #### `musehub_list_domains`
468
469 List all available domain plugins registered in MuseHub (e.g. MIDI, Genomics, Code).
470
471 _No parameters required._
472
473 ---
474
475 #### `musehub_get_domain`
476
477 Full definition for a single domain plugin — scoped_id, version, dimension manifest, capabilities, and schema.
478
479 | Parameter | Type | Required | Description |
480 |-----------|------|----------|-------------|
481 | `domain_id` | string | yes | Domain plugin identifier (e.g. `"midi-v1"`) |
482
483 ---
484
485 #### `musehub_get_domain_insights`
486
487 Computed analytics for a repo using its domain plugin — per-dimension scores, distribution stats, and trend data.
488
489 | Parameter | Type | Required | Description |
490 |-----------|------|----------|-------------|
491 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
492 | `owner` | string | no | Owner username (use with `slug`) |
493 | `slug` | string | no | Repository slug (use with `owner`) |
494 | `ref` | string | no | Branch, tag, or commit SHA (defaults to HEAD) |
495
496 ---
497
498 #### `musehub_get_view`
499
500 Full viewer payload — dimension slices, navigation strip, and the current state for each registered dimension. Use after `musehub_get_context` for the visual-layer detail.
501
502 | Parameter | Type | Required | Description |
503 |-----------|------|----------|-------------|
504 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
505 | `owner` | string | no | Owner username (use with `slug`) |
506 | `slug` | string | no | Repository slug (use with `owner`) |
507 | `ref` | string | no | Branch, tag, or commit SHA (defaults to HEAD) |
508
509 ---
510
511 #### `musehub_whoami`
512
513 Return the authenticated user's profile. Useful for confirming token identity before write operations.
514
515 _No parameters required._
516
517 ---
518
519 #### `muse_pull`
520
521 Pull latest commits from MuseHub into a local Muse working tree — equivalent of `muse pull` on the command line.
522
523 | Parameter | Type | Required | Description |
524 |-----------|------|----------|-------------|
525 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
526 | `owner` | string | no | Owner username (use with `slug`) |
527 | `slug` | string | no | Repository slug (use with `owner`) |
528 | `branch` | string | no | Branch to pull (defaults to current) |
529
530 ---
531
532 #### `muse_remote`
533
534 Inspect remote tracking configuration and get the clone URL for a repo — equivalent of `muse remote` on the command line. Returns `clone_url`, `clone_command`, and `visibility`. Pass `ref` to pin to a specific branch or tag.
535
536 | Parameter | Type | Required | Description |
537 |-----------|------|----------|-------------|
538 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
539 | `owner` | string | no | Owner username (use with `slug`) |
540 | `slug` | string | no | Repository slug (use with `owner`) |
541 | `ref` | string | no | Branch or tag to reference in the clone command |
542
543 ---
544
545 ### Write Tools (15)
546
547 > All write tools require `Authorization: Bearer <jwt>` on the HTTP transport.
548
549 #### `musehub_create_repo`
550
551 Create a new repository.
552
553 | Parameter | Type | Required | Description |
554 |-----------|------|----------|-------------|
555 | `name` | string | yes | Repository name |
556 | `owner` | string | yes | Owner username |
557 | `owner_user_id` | string | yes | Owner user UUID |
558 | `description` | string | no | Short description |
559 | `visibility` | string | no | `"public"` (default) or `"private"` |
560 | `tags` | array of strings | no | Initial tags |
561 | `key_signature` | string | no | Musical key (e.g. `"G major"`) |
562 | `tempo_bpm` | integer | no | Tempo in BPM |
563 | `initialize` | boolean | no | Create initial commit (default `true`) |
564
565 ---
566
567 #### `musehub_fork_repo`
568
569 Fork an existing repository into the authenticated user's account.
570
571 | Parameter | Type | Required | Description |
572 |-----------|------|----------|-------------|
573 | `repo_id` | string | yes | Source repository UUID |
574 | `new_owner` | string | yes | Fork owner username |
575 | `new_owner_user_id` | string | yes | Fork owner user UUID |
576
577 ---
578
579 #### `musehub_create_issue`
580
581 Open a new issue.
582
583 | Parameter | Type | Required | Description |
584 |-----------|------|----------|-------------|
585 | `repo_id` | string | yes | Repository UUID |
586 | `title` | string | yes | Issue title |
587 | `body` | string | no | Issue description (Markdown) |
588 | `labels` | array of strings | no | Label names to apply |
589 | `assignee_id` | string | no | Assignee user UUID |
590
591 ---
592
593 #### `musehub_update_issue`
594
595 Update issue state or metadata.
596
597 | Parameter | Type | Required | Description |
598 |-----------|------|----------|-------------|
599 | `repo_id` | string | yes | Repository UUID |
600 | `issue_number` | integer | yes | Issue number |
601 | `state` | string | no | `"open"` or `"closed"` |
602 | `title` | string | no | New title |
603 | `body` | string | no | New body |
604 | `assignee_id` | string | no | New assignee UUID |
605 | `labels` | array of strings | no | Replace label set |
606
607 ---
608
609 #### `musehub_create_issue_comment`
610
611 Post a comment on an issue.
612
613 | Parameter | Type | Required | Description |
614 |-----------|------|----------|-------------|
615 | `repo_id` | string | yes | Repository UUID |
616 | `issue_number` | integer | yes | Issue number |
617 | `body` | string | yes | Comment body (Markdown) |
618
619 ---
620
621 #### `musehub_create_pr`
622
623 Open a pull request.
624
625 | Parameter | Type | Required | Description |
626 |-----------|------|----------|-------------|
627 | `repo_id` | string | yes | Repository UUID |
628 | `title` | string | yes | PR title |
629 | `from_branch` | string | yes | Source branch |
630 | `to_branch` | string | yes | Target branch |
631 | `body` | string | no | PR description (Markdown) |
632
633 ---
634
635 #### `musehub_merge_pr`
636
637 Merge an open pull request.
638
639 | Parameter | Type | Required | Description |
640 |-----------|------|----------|-------------|
641 | `repo_id` | string | yes | Repository UUID |
642 | `pr_number` | integer | yes | Pull request number |
643 | `merge_message` | string | no | Custom merge commit message |
644
645 ---
646
647 #### `musehub_create_pr_comment`
648
649 Post an inline comment on a PR. Supports general, track-level, and beat-range comments — mirroring the musical diff view in the web UI.
650
651 | Parameter | Type | Required | Description |
652 |-----------|------|----------|-------------|
653 | `repo_id` | string | yes | Repository UUID |
654 | `pr_number` | integer | yes | Pull request number |
655 | `body` | string | yes | Comment body (Markdown) |
656 | `target_type` | string | no | `"general"` (default), `"track"`, `"region"`, or `"note"` |
657 | `target_track` | string | no | Track name (when `target_type` is `"track"` or finer) |
658 | `target_beat_start` | number | no | Start beat position |
659 | `target_beat_end` | number | no | End beat position |
660
661 ---
662
663 #### `musehub_submit_pr_review`
664
665 Submit a formal review on a PR.
666
667 | Parameter | Type | Required | Description |
668 |-----------|------|----------|-------------|
669 | `repo_id` | string | yes | Repository UUID |
670 | `pr_number` | integer | yes | Pull request number |
671 | `state` | string | yes | `"approved"`, `"changes_requested"`, or `"commented"` |
672 | `body` | string | no | Review summary |
673
674 ---
675
676 #### `musehub_create_release`
677
678 Publish a release.
679
680 | Parameter | Type | Required | Description |
681 |-----------|------|----------|-------------|
682 | `repo_id` | string | yes | Repository UUID |
683 | `tag` | string | yes | Tag name (e.g. `"v1.0.0"`) |
684 | `title` | string | yes | Release title |
685 | `body` | string | no | Release notes (Markdown) |
686 | `commit_id` | string | no | Target commit SHA (defaults to HEAD) |
687 | `is_prerelease` | boolean | no | Mark as pre-release (default `false`) |
688
689 ---
690
691 #### `musehub_star_repo`
692
693 Star a repository.
694
695 | Parameter | Type | Required | Description |
696 |-----------|------|----------|-------------|
697 | `repo_id` | string | yes | Repository UUID |
698
699 ---
700
701 #### `musehub_create_label`
702
703 Create a label scoped to a repository.
704
705 | Parameter | Type | Required | Description |
706 |-----------|------|----------|-------------|
707 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
708 | `owner` | string | no | Owner username (use with `slug`) |
709 | `slug` | string | no | Repository slug (use with `owner`) |
710 | `name` | string | yes | Label name |
711 | `color` | string | yes | Hex color (e.g. `"#0075ca"`) |
712 | `description` | string | no | Label description |
713
714 ---
715
716 #### `musehub_create_agent_token`
717
718 Mint a long-lived agent JWT with higher rate limits and an activity badge in the public feed.
719
720 | Parameter | Type | Required | Description |
721 |-----------|------|----------|-------------|
722 | `agent_name` | string | yes | Display name for the agent (shown in feed) |
723 | `scopes` | array of strings | no | Permission scopes (defaults to all) |
724
725 ---
726
727 #### `muse_push`
728
729 Push a Muse commit bundle to MuseHub — equivalent of `muse push` on the command line.
730
731 Accepts the full wire format: commits, snapshot manifests, and content-addressed
732 objects in a single round-trip. Snapshots are stored idempotently — re-pushing an
733 existing `snapshot_id` is a safe no-op.
734
735 ```json
736 {
737 "name": "muse_push",
738 "arguments": {
739 "owner": "alice",
740 "slug": "my-song",
741 "branch": "main",
742 "head_commit_id": "sha256:abc...",
743 "commits": [
744 {
745 "commit_id": "sha256:abc...",
746 "parent_ids": ["sha256:parent..."],
747 "message": "feat: add bridge section",
748 "author": "alice",
749 "timestamp": "2026-03-21T18:00:00Z",
750 "snapshot_id": "sha256:snap..."
751 }
752 ],
753 "snapshots": [
754 {
755 "snapshot_id": "sha256:snap...",
756 "manifest": {
757 "tracks/piano.mid": "sha256:obj-piano...",
758 "tracks/strings.mid": "sha256:obj-strings..."
759 }
760 }
761 ],
762 "objects": [
763 {
764 "object_id": "sha256:obj-piano...",
765 "path": "tracks/piano.mid",
766 "size": 4096,
767 "content_b64": "<base64-encoded bytes>"
768 }
769 ]
770 }
771 }
772 ```
773
774 **Fast-forward enforcement:** rejected with `HTTP 409 Conflict` if the push would
775 create a non-linear history. Use `force: true` to override (destructive — use with care).
776
777 | Parameter | Type | Required | Description |
778 |-----------|------|----------|-------------|
779 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
780 | `owner` | string | no | Owner username (use with `slug`) |
781 | `slug` | string | no | Repository slug (use with `owner`) |
782 | `branch` | string | yes | Target branch name |
783 | `head_commit_id` | string | yes | SHA of the new branch tip |
784 | `commits` | array | yes | List of `CommitInput` objects (see wire format) |
785 | `snapshots` | array | no | List of `SnapshotInput` objects — `snapshot_id` + `manifest` dict |
786 | `objects` | array | no | List of `ObjectInput` objects — content-addressed blobs |
787 | `force` | boolean | no | Override fast-forward check (default: `false`) |
788
789 ---
790
791 #### `muse_config`
792
793 Read or write per-repo Muse configuration values — equivalent of `muse config` on the command line.
794
795 | Parameter | Type | Required | Description |
796 |-----------|------|----------|-------------|
797 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
798 | `owner` | string | no | Owner username (use with `slug`) |
799 | `slug` | string | no | Repository slug (use with `owner`) |
800 | `key` | string | yes | Config key to read or write |
801 | `value` | string | no | Value to set (omit to read the current value) |
802
803 ---
804
805 ### Elicitation-Powered Tools (5)
806
807 > **Three execution paths — no session required for bypass or schema guide.**
808 >
809 > | Path | Requirements | Behaviour |
810 > |------|-------------|-----------|
811 > | **Elicitation** | Active session + elicitation capability declared | Interactive form / URL presented to user mid-call |
812 > | **Bypass** | Supply bypass params (see each tool) | Returns result immediately; zero round-trips |
813 > | **Schema guide** | No session, no bypass params | Returns `ok: true` with `mode: "schema_guide"` — a complete field guide for the next call |
814 >
815 > The bypass path makes all five tools usable in any headless agent, CI pipeline, or client that does not support MCP sessions.
816
817 #### `musehub_create_with_preferences` _(form elicitation | bypass: `preferences`)_
818
819 Generate a complete domain-specific composition plan, either interactively or directly.
820
821 **Elicitation path** — elicits: key signature, tempo (BPM), time signature, mood, genre, reference artist, duration (bars), key modulation.
822
823 **Bypass path** — pass `preferences` dict; every field is optional (falls back to sensible defaults):
824
825 ```json
826 {
827 "name": "musehub_create_with_preferences",
828 "arguments": {
829 "repo_id": "repo-uuid",
830 "preferences": {
831 "key_signature": "G major",
832 "tempo_bpm": 140,
833 "mood": "joyful",
834 "genre": "jazz",
835 "reference_artist": "Bill Evans",
836 "duration_bars": 64,
837 "include_modulation": false
838 }
839 }
840 }
841 ```
842
843 **Schema guide** (no session, no `preferences`) — returns available field names, types, and valid values.
844
845 **Returns:** `composition_plan` dict with chord progressions per section, structural form, harmonic tension profile, texture guidance, and a step-by-step Muse project workflow.
846
847 | Parameter | Type | Required | Description |
848 |-----------|------|----------|-------------|
849 | `repo_id` | string | no | Optional target repo to scaffold the plan into |
850 | `preferences` | object | no | **Bypass:** key\_signature, tempo\_bpm, time\_signature, mood, genre, reference\_artist, duration\_bars, include\_modulation |
851 | `owner` | string | no | Owner username (use with `slug`) |
852 | `slug` | string | no | Repository slug (use with `owner`) |
853
854 ---
855
856 #### `musehub_review_pr_interactive` _(form elicitation | bypass: `dimension`, `depth`)_
857
858 Deep musical PR review, either interactively or from explicit parameters.
859
860 **Elicitation path** — elicits: dimension focus, review depth, harmonic tension check, rhythmic consistency check, reviewer note.
861
862 **Bypass path** — pass `dimension` and/or `depth` directly:
863
864 ```json
865 {
866 "name": "musehub_review_pr_interactive",
867 "arguments": {
868 "repo_id": "repo-uuid",
869 "pr_id": "pr-uuid",
870 "dimension": "harmonic",
871 "depth": "thorough"
872 }
873 }
874 ```
875
876 Either or both bypass params may be provided; missing values default to `"all"` and `"standard"` respectively.
877
878 **Schema guide** (no session, no bypass params) — returns `dimension_options` and `depth_options` lists.
879
880 **Returns:** per-dimension divergence scores, findings list (with harmonic tension and rhythmic checks), and a recommendation (APPROVE / REQUEST_CHANGES / COMMENT).
881
882 | Parameter | Type | Required | Description |
883 |-----------|------|----------|-------------|
884 | `repo_id` | string | yes | Repository UUID |
885 | `pr_id` | string | yes | Pull request UUID |
886 | `dimension` | string | no | **Bypass:** one of `melodic`, `harmonic`, `rhythmic`, `structural`, `dynamic`, `all` |
887 | `depth` | string | no | **Bypass:** one of `quick`, `standard`, `thorough` |
888
889 ---
890
891 #### `musehub_connect_streaming_platform` _(URL elicitation | bypass: `platform`)_
892
893 OAuth-connect a streaming platform. When no session is present but a valid `platform`
894 is supplied, the OAuth URL is returned directly for manual browser navigation.
895
896 **Elicitation path** — full interactive OAuth flow via SSE session.
897
898 **Bypass path** (no session, `platform` known):
899
900 ```json
901 {
902 "name": "musehub_connect_streaming_platform",
903 "arguments": { "platform": "Spotify" }
904 }
905 ```
906
907 Returns `{ "status": "pending_oauth", "oauth_url": "https://...", "platform": "Spotify" }`.
908 Open `oauth_url` in a browser to complete the OAuth flow.
909
910 **Schema guide** (no session, no `platform`) — returns `platform_options` list.
911
912 **Supported platforms:** Spotify, SoundCloud, Bandcamp, YouTube Music, Apple Music, TIDAL, Amazon Music, Deezer.
913
914 | Parameter | Type | Required | Description |
915 |-----------|------|----------|-------------|
916 | `platform` | string | no | **Bypass:** platform name (elicited via form if omitted and session exists) |
917 | `repo_id` | string | no | Repository context for release distribution |
918
919 ---
920
921 #### `musehub_connect_daw_cloud` _(URL elicitation | bypass: `service`)_
922
923 OAuth-connect a cloud DAW or mastering service. When no session is present but a valid
924 `service` is supplied, the OAuth URL is returned directly.
925
926 **Bypass path** (no session, `service` known):
927
928 ```json
929 {
930 "name": "musehub_connect_daw_cloud",
931 "arguments": { "service": "LANDR" }
932 }
933 ```
934
935 Returns `{ "status": "pending_oauth", "oauth_url": "https://...", "service": "LANDR", "capabilities": [...] }`.
936
937 **Schema guide** (no session, no `service`) — returns `service_options` list.
938
939 **Supported services:** LANDR (AI mastering + distribution), Splice (sample sync + backup), Soundtrap, BandLab, Audiotool.
940
941 | Parameter | Type | Required | Description |
942 |-----------|------|----------|-------------|
943 | `service` | string | no | **Bypass:** service name (elicited via form if omitted and session exists) |
944
945 ---
946
947 #### `musehub_create_release_interactive` _(chained form + URL elicitation | bypass: `tag`)_
948
949 Two-phase interactive release creator, or direct release creation via bypass params.
950
951 **Elicitation path:**
952 1. **Form:** collects tag, title, release notes, changelog highlight, and pre-release flag.
953 2. **URL (optional):** offers Spotify OAuth for immediate distribution.
954
955 **Bypass path** — supply `tag` (required); `title` and `notes` are optional:
956
957 ```json
958 {
959 "name": "musehub_create_release_interactive",
960 "arguments": {
961 "repo_id": "repo-uuid",
962 "tag": "v1.2.0",
963 "title": "Spring release",
964 "notes": "New chord voicings, tempo map fixes."
965 }
966 }
967 ```
968
969 **Schema guide** (no session, no `tag`) — returns field guide with required/optional labels.
970
971 | Parameter | Type | Required | Description |
972 |-----------|------|----------|-------------|
973 | `repo_id` | string | yes | Repository to create the release in |
974 | `tag` | string | no | **Bypass:** semantic version tag (e.g. `v1.2.0`); triggers direct release creation |
975 | `title` | string | no | **Bypass:** human-readable release title (defaults to `tag`) |
976 | `notes` | string | no | **Bypass:** release notes / changelog body |
977
978 ---
979
980 ## Resources
981
982 Resources are side-effect-free, cacheable, URI-addressable reads. All resources return `application/json`. They are read via the `resources/read` method.
983
984 ### Listing resources
985
986 ```json
987 {"jsonrpc":"2.0","id":1,"method":"resources/list"}
988 {"jsonrpc":"2.0","id":2,"method":"resources/templates/list"}
989 ```
990
991 ### Reading a resource
992
993 ```json
994 {
995 "jsonrpc": "2.0",
996 "id": 1,
997 "method": "resources/read",
998 "params": { "uri": "musehub://trending" }
999 }
1000 ```
1001
1002 Response:
1003
1004 ```json
1005 {
1006 "jsonrpc": "2.0",
1007 "id": 1,
1008 "result": {
1009 "contents": [{
1010 "uri": "musehub://trending",
1011 "mimeType": "application/json",
1012 "text": "[{\"repo_id\":\"...\",\"name\":\"my-song\",...}]"
1013 }]
1014 }
1015 }
1016 ```
1017
1018 ---
1019
1020 ### Static Resources (12)
1021
1022 #### `musehub://trending`
1023
1024 Top 20 public repos ordered by star count. Anonymous-accessible.
1025
1026 **Returns:** array of repo summaries with `repo_id`, `name`, `owner`, `slug`, `description`, `visibility`, `clone_url`, `created_at`.
1027
1028 ---
1029
1030 #### `musehub://me`
1031
1032 Authenticated user's profile and their most recent 20 repos. Requires JWT.
1033
1034 **Returns:** `{ "user_id", "username", "repos": [...] }`
1035
1036 ---
1037
1038 #### `musehub://me/notifications`
1039
1040 Unread notifications for the authenticated user. Requires JWT.
1041
1042 **Returns:** `{ "notifications": [{ "id", "event_type", "read", "created_at" }] }`
1043
1044 ---
1045
1046 #### `musehub://me/starred`
1047
1048 Repos the authenticated user has starred. Requires JWT.
1049
1050 **Returns:** `{ "starred": [{ "repo_id", "name", "owner", "slug", "starred_at" }] }`
1051
1052 ---
1053
1054 #### `musehub://me/feed`
1055
1056 Activity feed for repos the authenticated user watches. Requires JWT.
1057
1058 **Returns:** `{ "feed": [...] }`
1059
1060 ---
1061
1062 ### Templated Resources (17)
1063
1064 All templated resources follow RFC 6570 Level 1. `{owner}` and `{slug}` are resolved to a `repo_id` by the dispatcher — agents use human-readable names, not UUIDs.
1065
1066 #### `musehub://repos/{owner}/{slug}`
1067
1068 Repo overview: metadata, visibility, default branch, tag list, description.
1069
1070 ---
1071
1072 #### `musehub://repos/{owner}/{slug}/branches`
1073
1074 All branches with their name, head commit ID, and last-updated timestamp.
1075
1076 ---
1077
1078 #### `musehub://repos/{owner}/{slug}/commits`
1079
1080 20 most recent commits on the default branch. Includes commit message, author, timestamp.
1081
1082 ---
1083
1084 #### `musehub://repos/{owner}/{slug}/commits/{commit_id}`
1085
1086 Single commit with its full snapshot manifest (all file paths and content hashes at that point).
1087
1088 ---
1089
1090 #### `musehub://repos/{owner}/{slug}/tree/{ref}`
1091
1092 File tree at a given ref. Returns all object paths and guessed MIME types.
1093
1094 ---
1095
1096 #### `musehub://repos/{owner}/{slug}/blob/{ref}/{path}`
1097
1098 Metadata for a single file at a given ref: path, content hash, MIME type, size.
1099
1100 ---
1101
1102 #### `musehub://repos/{owner}/{slug}/issues`
1103
1104 Open issues list with labels, assignees, and comment counts.
1105
1106 ---
1107
1108 #### `musehub://repos/{owner}/{slug}/issues/{number}`
1109
1110 Single issue with its full comment thread.
1111
1112 ---
1113
1114 #### `musehub://repos/{owner}/{slug}/pulls`
1115
1116 Open PRs with source/target branches and review counts.
1117
1118 ---
1119
1120 #### `musehub://repos/{owner}/{slug}/pulls/{number}`
1121
1122 Single PR with all inline comments and reviews (reviewer, state, body).
1123
1124 ---
1125
1126 #### `musehub://repos/{owner}/{slug}/releases`
1127
1128 All releases ordered newest first: tag, title, body, asset count, timestamp.
1129
1130 ---
1131
1132 #### `musehub://repos/{owner}/{slug}/releases/{tag}`
1133
1134 Single release matching a tag name, including the full release notes body.
1135
1136 ---
1137
1138 #### `musehub://repos/{owner}/{slug}/analysis/{ref}`
1139
1140 Musical analysis at a given ref: key, tempo, time signature, per-dimension scores (harmony, rhythm, groove, dynamics, orchestration, …).
1141
1142 ---
1143
1144 #### `musehub://repos/{owner}/{slug}/timeline`
1145
1146 Musical evolution timeline: commits, section events, and track events in chronological order.
1147
1148 ---
1149
1150 #### `musehub://users/{username}`
1151
1152 User profile and their 20 most recent public repos.
1153
1154 ---
1155
1156 ## Prompts
1157
1158 Prompts teach agents how to chain tools and resources to accomplish multi-step goals. They return a structured list of `role`/`content` messages that frame the task for the agent.
1159
1160 ### Getting a prompt
1161
1162 ```json
1163 {
1164 "jsonrpc": "2.0",
1165 "id": 1,
1166 "method": "prompts/get",
1167 "params": {
1168 "name": "musehub/orientation"
1169 }
1170 }
1171 ```
1172
1173 With arguments:
1174
1175 ```json
1176 {
1177 "jsonrpc": "2.0",
1178 "id": 1,
1179 "method": "prompts/get",
1180 "params": {
1181 "name": "musehub/contribute",
1182 "arguments": {
1183 "repo_id": "abc123",
1184 "owner": "alice",
1185 "slug": "my-song"
1186 }
1187 }
1188 }
1189 ```
1190
1191 ---
1192
1193 ### `musehub/orientation`
1194
1195 **Arguments:** `caller_type` (optional: `"human"` or `"agent"`)
1196
1197 The essential first read for any new agent or human. Explains MuseHub's model (repos, commits, branches, domain plugins, multidimensional state), the `musehub://` URI scheme, which tools to use for reads vs. writes, and how to authenticate. When `caller_type: "agent"` is passed, the response includes extended agent onboarding guidance — tool call sequencing, addressing scheme, and auth setup.
1198
1199 ---
1200
1201 ### `musehub/contribute`
1202
1203 **Arguments:** `repo_id`, `owner`, `slug`
1204
1205 End-to-end contribution workflow, including auth and push setup:
1206
1207 0. Confirm authentication and set up `muse remote` tracking
1208 1. `musehub_get_context` — understand the repo
1209 2. `musehub://repos/{owner}/{slug}/issues` — find open issues
1210 3. `musehub_create_issue` — or create a new one
1211 4. Make changes, push a commit via `muse_push`
1212 5. `musehub_create_pr` — open a PR
1213 6. `musehub_submit_pr_review` — request review
1214 7. `musehub_merge_pr` — merge when approved
1215
1216 ---
1217
1218 ### `musehub/create`
1219
1220 **Arguments:** `repo_id`
1221
1222 Domain-agnostic creation workflow:
1223
1224 1. `musehub_get_context` — understand existing content and structure
1225 2. `musehub://repos/{owner}/{slug}/analysis/{ref}` — study the domain-specific analysis
1226 3. Create domain artifacts matching the repo's dimensional constraints
1227 4. Push the commit via `muse_push`
1228 5. Verify with `musehub_get_domain_insights`
1229
1230 ---
1231
1232 ### `musehub/review_pr`
1233
1234 **Arguments:** `repo_id`, `pr_id`
1235
1236 Musical PR review:
1237
1238 1. `musehub_get_pr` — read the PR metadata
1239 2. `musehub_compare` — get per-dimension diff scores
1240 3. `musehub://repos/{owner}/{slug}/analysis/{ref}` — compare analyses for base and head
1241 4. `musehub_create_pr_comment` — post track/region-level comments
1242 5. `musehub_submit_pr_review` — approve or request changes
1243
1244 ---
1245
1246 ### `musehub/issue_triage`
1247
1248 **Arguments:** `repo_id`
1249
1250 Triage open issues:
1251
1252 1. `musehub_list_issues` — list open issues
1253 2. Categorise by type (bug, feature, discussion)
1254 3. `musehub_create_label` — create missing labels
1255 4. `musehub_update_issue` — apply labels, assign, close duplicates
1256
1257 ---
1258
1259 ### `musehub/release_prep`
1260
1261 **Arguments:** `repo_id`
1262
1263 Prepare a release:
1264
1265 1. `musehub_list_prs` — find merged PRs since the last release
1266 2. `musehub_list_releases` — check the latest release tag
1267 3. `musehub_get_domain_insights` — summarise domain-specific changes
1268 4. Draft release notes (Markdown)
1269 5. `musehub_create_release` — publish
1270
1271 ---
1272
1273 ### `musehub/onboard` _(MCP 2025-11-25)_
1274
1275 **Arguments:** `username` (optional)
1276
1277 Interactive artist onboarding using elicitation. Requires a client with session + elicitation capability:
1278
1279 1. `musehub_create_repo` — scaffold the first project repo
1280 2. `musehub_create_with_preferences` — elicits key, tempo, mood, genre; returns composition plan
1281 3. `musehub_connect_daw_cloud` — URL elicitation: OAuth-connect LANDR/Splice/Soundtrap
1282 4. Guides through first commit, collaboration invite, and activity feed
1283
1284 ---
1285
1286 ### `musehub/release_to_world` _(MCP 2025-11-25)_
1287
1288 **Arguments:** `repo_id`
1289
1290 Full elicitation-powered release and distribution pipeline:
1291
1292 1. `musehub_create_release_interactive` — form: collect tag, title, notes, highlight; URL: optional Spotify connect
1293 2. `musehub_connect_streaming_platform` — URL elicitation for each target platform
1294 3. `musehub_connect_daw_cloud` — optional cloud mastering via LANDR
1295 4. Post announcement issue and notify followers
1296
1297 ---
1298
1299 ### `musehub/domain-discovery`
1300
1301 **Arguments:** none
1302
1303 Discover and evaluate available domain plugins:
1304
1305 1. `musehub_list_domains` — enumerate all registered domain plugins
1306 2. `musehub_get_domain` — inspect a specific plugin's dimension manifest and capabilities
1307 3. `musehub_search_repos` — find repos using that domain
1308
1309 ---
1310
1311 ### `musehub/domain-authoring`
1312
1313 **Arguments:** `domain_id` (optional)
1314
1315 Author a new domain plugin from scratch or extend an existing one:
1316
1317 1. `musehub_list_domains` — understand the existing domain landscape
1318 2. Walk through dimension schema design, capability declaration, and scoped_id naming
1319 3. Validate by creating a test repo and calling `musehub_get_domain_insights`
1320
1321 ---
1322
1323 ## Error Handling
1324
1325 ### JSON-RPC error codes
1326
1327 | Code | Meaning |
1328 |------|---------|
1329 | `-32700` | Parse error — request body is not valid JSON |
1330 | `-32600` | Invalid request — not an object or array |
1331 | `-32601` | Method not found |
1332 | `-32602` | Invalid params — required argument missing or wrong type |
1333 | `-32603` | Internal error — unexpected server exception |
1334 | `-32001` | Authentication required — write tool called without valid JWT |
1335
1336 ### Tool errors
1337
1338 Tool execution errors are not JSON-RPC errors. The envelope is always a success response; the error is signalled inside the result:
1339
1340 ```json
1341 {
1342 "result": {
1343 "content": [{ "type": "text", "text": "repo not found: abc123" }],
1344 "isError": true
1345 }
1346 }
1347 ```
1348
1349 ---
1350
1351 ## Usage Patterns
1352
1353 ### Pattern 1: Discover and explore
1354
1355 ```
1356 1. resources/read musehub://trending → pick a repo
1357 2. resources/read musehub://repos/{owner}/{slug} → orientation
1358 3. tools/call musehub_get_context → full AI context
1359 4. resources/read musehub://repos/{owner}/{slug}/analysis/{ref} → musical detail
1360 ```
1361
1362 ### Pattern 2: Fix a bug, open a PR
1363
1364 ```
1365 1. tools/call musehub_list_issues { owner, slug, state: "open" }
1366 2. tools/call musehub_get_issue { owner, slug, issue_number }
1367 3. tools/call musehub_get_context { owner, slug }
1368 4. tools/call musehub_read_file { owner, slug, path }
1369 5. -- compose fix, push commit via muse_push --
1370 6. tools/call musehub_create_pr { owner, slug, title, from_branch, to_branch }
1371 ```
1372
1373 ### Pattern 3: Full musical PR review (elicitation-powered)
1374
1375 ```
1376 1. tools/call musehub_review_pr_interactive { repo_id, pr_id }
1377 → elicitation: "Focus on harmonic divergence, thorough depth"
1378 → returns: per-dimension scores, findings, APPROVE/REQUEST_CHANGES recommendation
1379 ```
1380
1381 Or stateless:
1382
1383 ```
1384 1. tools/call musehub_get_pr { repo_id, pr_id }
1385 2. tools/call musehub_compare { repo_id, base_ref, head_ref }
1386 3. tools/call musehub_create_pr_comment { repo_id, pr_id, body, target_type: "track", ... }
1387 4. tools/call musehub_submit_pr_review { repo_id, pr_id, event: "APPROVE" }
1388 ```
1389
1390 ### Pattern 4: Create with preferences (elicitation-powered)
1391
1392 ```
1393 1. POST initialize → Mcp-Session-Id: <id>
1394 2. GET /mcp (SSE) → open push channel
1395 3. tools/call musehub_create_with_preferences { owner, slug }
1396 → SSE: elicitation/create { mode: "form", schema: compose_preferences }
1397 → [user selects key: "D minor", tempo: 95, mood: "melancholic", genre: "neo-soul"]
1398 → POST elicitation result { action: "accept", content: { key: "D minor", ... } }
1399 → SSE: tools/call response { composition_plan: { ... } }
1400 ```
1401
1402 ### Pattern 5: Publish a release (elicitation-powered)
1403
1404 ```
1405 1. tools/call musehub_create_release_interactive { repo_id }
1406 → elicitation (form): tag, title, release notes, highlight
1407 → elicitation (URL, optional): Spotify OAuth
1408 → creates release + returns distribution guidance
1409 ```
1410
1411 Or stateless:
1412
1413 ```
1414 1. tools/call musehub_list_releases { owner, slug }
1415 2. tools/call musehub_list_prs { owner, slug, state: "closed" }
1416 3. tools/call musehub_get_domain_insights { owner, slug }
1417 4. tools/call musehub_create_release {
1418 owner, slug, tag: "v1.2.0", title: "Spring Drop",
1419 body: "## What changed\n..."
1420 }
1421 ```
1422
1423 ### Pattern 6: Connect and distribute (URL elicitation)
1424
1425 ```
1426 1. tools/call musehub_connect_streaming_platform { platform: "Spotify" }
1427 → SSE: elicitation/create { mode: "url", url: "https://musehub.app/musehub/ui/mcp/connect/spotify?elicitation_id=..." }
1428 → [user clicks through OAuth in browser]
1429 → SSE: notifications/elicitation/complete { action: "accept" }
1430 → returns: { platform: "Spotify", status: "connected" }
1431 ```
1432
1433 ---
1434
1435 ## Architecture Diagrams
1436
1437 ### Request flow
1438
1439 ```mermaid
1440 flowchart TD
1441 subgraph transports [Transports — MCP 2025-11-25]
1442 POST["POST /mcp\nJSON + SSE stream"]
1443 GET["GET /mcp\nSSE push channel"]
1444 DEL["DELETE /mcp\nSession termination"]
1445 stdio["stdio\npython -m musehub.mcp.stdio_server"]
1446 end
1447
1448 subgraph session [Session Layer]
1449 SID["Mcp-Session-Id"]
1450 ORIGIN["Origin validation"]
1451 SSE_Q["asyncio.Queue\nSSE queues"]
1452 FUTURES["asyncio.Future\nelicitation registry"]
1453 end
1454
1455 subgraph dispatcher [musehub/mcp/dispatcher.py]
1456 D["handle_request()"]
1457 D --> INIT["initialize"]
1458 D --> TL["tools/list"]
1459 D --> TC["tools/call"]
1460 D --> RL["resources/list"]
1461 D --> RR["resources/read"]
1462 D --> PL["prompts/list"]
1463 D --> PG["prompts/get"]
1464 D --> NC["notifications/cancelled"]
1465 D --> NEC["notifications/elicitation/complete"]
1466 end
1467
1468 subgraph execution [Execution Layer]
1469 READ["Read executors\nmusehub_mcp_executor.py"]
1470 WRITE["Write executors\nmcp/write_tools/"]
1471 ELICIT["Elicitation tools\nelicitation_tools.py"]
1472 CTX["ToolCallContext\ncontext.py"]
1473 RES["Resource handlers\nresources.py"]
1474 PROMPTS["Prompt assembler\nprompts.py"]
1475 end
1476
1477 POST --> ORIGIN
1478 POST --> SID
1479 SID --> D
1480 GET --> SSE_Q
1481 DEL --> SID
1482 stdio --> D
1483 TC --> READ
1484 TC --> WRITE
1485 TC --> ELICIT
1486 ELICIT --> CTX
1487 CTX --> SSE_Q
1488 CTX --> FUTURES
1489 RR --> RES
1490 PG --> PROMPTS
1491 NC --> FUTURES
1492 NEC --> FUTURES
1493 READ --> DB[("AsyncSession / Postgres")]
1494 WRITE --> DB
1495 RES --> DB
1496 ```
1497
1498 ### Tool catalogue structure
1499
1500 ```mermaid
1501 classDiagram
1502 class MUSEHUB_READ_TOOLS {
1503 <<list of MCPToolDef — 20 tools>>
1504 musehub_get_context
1505 musehub_list_branches
1506 musehub_list_commits
1507 musehub_read_file
1508 musehub_search
1509 musehub_get_commit
1510 musehub_compare
1511 musehub_list_issues
1512 musehub_get_issue
1513 musehub_list_prs
1514 musehub_get_pr
1515 musehub_list_releases
1516 musehub_search_repos
1517 musehub_list_domains
1518 musehub_get_domain
1519 musehub_get_domain_insights
1520 musehub_get_view
1521 musehub_whoami
1522 muse_pull
1523 muse_remote
1524 }
1525 class MUSEHUB_WRITE_TOOLS {
1526 <<list of MCPToolDef — 15 tools>>
1527 musehub_create_repo
1528 musehub_fork_repo
1529 musehub_create_issue
1530 musehub_update_issue
1531 musehub_create_issue_comment
1532 musehub_create_pr
1533 musehub_merge_pr
1534 musehub_create_pr_comment
1535 musehub_submit_pr_review
1536 musehub_create_release
1537 musehub_star_repo
1538 musehub_create_label
1539 musehub_create_agent_token
1540 muse_push
1541 muse_config
1542 }
1543 class MUSEHUB_ELICITATION_TOOLS {
1544 <<list of MCPToolDef — 5 tools — MCP 2025-11-25>>
1545 musehub_create_with_preferences
1546 musehub_review_pr_interactive
1547 musehub_connect_streaming_platform
1548 musehub_connect_daw_cloud
1549 musehub_create_release_interactive
1550 }
1551 class MCPDispatcher {
1552 +handle_request(raw, user_id, session)
1553 +handle_batch(raw, user_id, session)
1554 }
1555
1556 MCPDispatcher ..> MUSEHUB_READ_TOOLS : routes read calls
1557 MCPDispatcher ..> MUSEHUB_WRITE_TOOLS : routes write calls (JWT required)
1558 MCPDispatcher ..> MUSEHUB_ELICITATION_TOOLS : routes interactive calls (session required)
1559 ```
1560
1561 ### Resource URI hierarchy
1562
1563 ```mermaid
1564 flowchart TD
1565 root["musehub://"]
1566 root --> trending["trending"]
1567 root --> me["me"]
1568 root --> repos["repos/{owner}/{slug}"]
1569 root --> users["users/{username}"]
1570
1571 me --> notifications["me/notifications"]
1572 me --> starred["me/starred"]
1573 me --> feed["me/feed"]
1574
1575 repos --> branches["…/branches"]
1576 repos --> commits["…/commits"]
1577 commits --> commit["…/commits/{commit_id}"]
1578 repos --> tree["…/tree/{ref}"]
1579 repos --> blob["…/blob/{ref}/{path}"]
1580 repos --> issues["…/issues"]
1581 issues --> issue["…/issues/{number}"]
1582 repos --> pulls["…/pulls"]
1583 pulls --> pull["…/pulls/{number}"]
1584 repos --> releases["…/releases"]
1585 releases --> release["…/releases/{tag}"]
1586 repos --> analysis["…/analysis/{ref}"]
1587 repos --> timeline["…/timeline"]
1588 ```
1589
1590 ### Elicitation sequence (form mode)
1591
1592 ```mermaid
1593 sequenceDiagram
1594 participant Agent
1595 participant MCP as POST /mcp
1596 participant Session as Session Store
1597 participant Tool as Elicitation Tool
1598
1599 Agent->>MCP: POST initialize {capabilities: {elicitation: {form:{}, url:{}}}}
1600 MCP-->>Agent: 200 OK, Mcp-Session-Id: abc123
1601
1602 Agent->>MCP: GET /mcp (Accept: text/event-stream, Mcp-Session-Id: abc123)
1603 MCP-->>Agent: 200 text/event-stream (SSE channel open)
1604
1605 Agent->>MCP: POST tools/call musehub_create_with_preferences
1606 Note over MCP: tool needs elicitation → SSE response
1607 MCP->>Session: create_pending_elicitation("elicit-1")
1608 MCP-->>Agent: 200 text/event-stream (POST SSE open)
1609 MCP-->>Agent: SSE: elicitation/create {mode:"form", schema:{key,tempo,mood,...}}
1610
1611 Note over Agent: Shows form UI to user
1612
1613 Agent->>MCP: POST {jsonrpc:"2.0", id:"elicit-1", result:{action:"accept", content:{key:"Dm",...}}}
1614 MCP->>Session: resolve_elicitation("elicit-1", {action:"accept", content:...})
1615 MCP-->>Agent: 202 Accepted
1616
1617 Note over Tool: Future resolved, tool continues
1618
1619 MCP-->>Agent: SSE: tools/call response {composition_plan: {...}}
1620 Note over MCP: SSE stream closes
1621 ```
1622
1623 ### Elicitation sequence (URL mode)
1624
1625 ```mermaid
1626 sequenceDiagram
1627 participant Agent
1628 participant MCP as POST /mcp
1629 participant Browser as User's Browser
1630 participant UI as MuseHub UI /mcp/connect/...
1631
1632 Agent->>MCP: POST tools/call musehub_connect_streaming_platform {platform:"Spotify"}
1633 MCP-->>Agent: SSE: elicitation/create {mode:"url", url:"https://musehub.app/musehub/ui/mcp/connect/spotify?elicitation_id=xyz"}
1634
1635 Agent->>Browser: opens URL
1636 Browser->>UI: GET /musehub/ui/mcp/connect/spotify?elicitation_id=xyz
1637 UI-->>Browser: confirmation page
1638
1639 Browser->>UI: user clicks "Connect Spotify"
1640 UI->>UI: resolve_elicitation(session, "xyz", {action:"accept"})
1641 UI-->>Browser: callback page (auto-close tab)
1642
1643 MCP-->>Agent: SSE: notifications/elicitation/complete {elicitationId:"xyz", action:"accept"}
1644 MCP-->>Agent: SSE: tools/call response {platform:"Spotify", status:"connected"}
1645 ```