gabriel / musehub public
mcp.md markdown
1499 lines 48.4 KB
d4eb1c39 Theme overhaul: domains, new-repo, MCP docs, copy icons; legacy CSS rem… Gabriel Cardona <cgcardona@gmail.com> 3d 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 to MuseHub — equivalent of `muse push` on the command line.
730
731 | Parameter | Type | Required | Description |
732 |-----------|------|----------|-------------|
733 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
734 | `owner` | string | no | Owner username (use with `slug`) |
735 | `slug` | string | no | Repository slug (use with `owner`) |
736 | `branch` | string | yes | Target branch name |
737 | `commit_data` | object | yes | Commit payload (message, snapshot, author) |
738
739 ---
740
741 #### `muse_config`
742
743 Read or write per-repo Muse configuration values — equivalent of `muse config` on the command line.
744
745 | Parameter | Type | Required | Description |
746 |-----------|------|----------|-------------|
747 | `repo_id` | string | no | Repository UUID (or use `owner` + `slug`) |
748 | `owner` | string | no | Owner username (use with `slug`) |
749 | `slug` | string | no | Repository slug (use with `owner`) |
750 | `key` | string | yes | Config key to read or write |
751 | `value` | string | no | Value to set (omit to read the current value) |
752
753 ---
754
755 ### Elicitation-Powered Tools (5)
756
757 > All elicitation tools require `Authorization: Bearer <jwt>`, an active session (`Mcp-Session-Id`), and a client that declared elicitation capability during `initialize`. They degrade gracefully for stateless clients, returning an `elicitation_unavailable` error that includes instructions for the non-interactive equivalent.
758
759 #### `musehub_create_with_preferences` _(form elicitation)_
760
761 Interview the user about a creation, then return a complete domain-specific plan.
762
763 **Elicits (MIDI/music domain):** key, tempo (BPM), time signature, mood, genre, reference artist, duration (bars), key modulation preference.
764
765 **Returns:** chord progressions per section, structural form (intro/verse/chorus/bridge/outro), harmonic tension profile, texture guidance, and a step-by-step Muse project workflow.
766
767 | Parameter | Type | Required | Description |
768 |-----------|------|----------|-------------|
769 | `repo_id` | string | no | Optional target repo to scaffold the plan into (or use `owner` + `slug`) |
770 | `owner` | string | no | Owner username (use with `slug`) |
771 | `slug` | string | no | Repository slug (use with `owner`) |
772
773 ---
774
775 #### `musehub_review_pr_interactive` _(form elicitation)_
776
777 Interactive PR review: collect the reviewer's focus before running the divergence analysis.
778
779 **Elicits:** dimension focus (all/melodic/harmonic/rhythmic/structural/dynamic), review depth (quick/standard/thorough), harmonic tension check, rhythmic consistency check, reviewer note.
780
781 **Returns:** per-dimension divergence scores, findings list, and a recommendation (APPROVE / REQUEST_CHANGES / COMMENT).
782
783 | Parameter | Type | Required | Description |
784 |-----------|------|----------|-------------|
785 | `repo_id` | string | yes | Repository UUID |
786 | `pr_id` | string | yes | Pull request UUID |
787
788 ---
789
790 #### `musehub_connect_streaming_platform` _(URL elicitation)_
791
792 OAuth-connect a streaming platform account for agent-triggered release distribution.
793
794 **Elicits (form, if platform not supplied):** platform name, confirm checkbox.
795 **Elicits (URL):** directs user to `GET /musehub/ui/mcp/connect/{platform}?elicitation_id=...` OAuth start page.
796
797 **Supported platforms:** Spotify, SoundCloud, Bandcamp, YouTube Music, Apple Music, TIDAL, Amazon Music, Deezer.
798
799 | Parameter | Type | Required | Description |
800 |-----------|------|----------|-------------|
801 | `platform` | string | no | Platform name (elicited if omitted) |
802 | `repo_id` | string | no | Repository context for distribution |
803
804 ---
805
806 #### `musehub_connect_daw_cloud` _(URL elicitation)_
807
808 OAuth-connect a cloud DAW or mastering service for cloud renders and exports.
809
810 **Elicits (form, if service not supplied):** service name, confirm checkbox.
811 **Elicits (URL):** directs user to `GET /musehub/ui/mcp/connect/daw/{service}?elicitation_id=...`.
812
813 **Supported services:** LANDR (AI mastering + distribution), Splice (sample sync + backup), Soundtrap, BandLab, Audiotool.
814
815 | Parameter | Type | Required | Description |
816 |-----------|------|----------|-------------|
817 | `service` | string | no | Service name (elicited if omitted) |
818
819 ---
820
821 #### `musehub_create_release_interactive` _(chained form + URL elicitation)_
822
823 Two-phase interactive release creator:
824
825 1. **Form elicitation:** collects tag, title, release notes, changelog highlight, and pre-release flag.
826 2. **URL elicitation (optional):** offers Spotify connection OAuth for immediate distribution.
827
828 | Parameter | Type | Required | Description |
829 |-----------|------|----------|-------------|
830 | `repo_id` | string | yes | Repository to create the release in |
831
832 ---
833
834 ## Resources
835
836 Resources are side-effect-free, cacheable, URI-addressable reads. All resources return `application/json`. They are read via the `resources/read` method.
837
838 ### Listing resources
839
840 ```json
841 {"jsonrpc":"2.0","id":1,"method":"resources/list"}
842 {"jsonrpc":"2.0","id":2,"method":"resources/templates/list"}
843 ```
844
845 ### Reading a resource
846
847 ```json
848 {
849 "jsonrpc": "2.0",
850 "id": 1,
851 "method": "resources/read",
852 "params": { "uri": "musehub://trending" }
853 }
854 ```
855
856 Response:
857
858 ```json
859 {
860 "jsonrpc": "2.0",
861 "id": 1,
862 "result": {
863 "contents": [{
864 "uri": "musehub://trending",
865 "mimeType": "application/json",
866 "text": "[{\"repo_id\":\"...\",\"name\":\"my-song\",...}]"
867 }]
868 }
869 }
870 ```
871
872 ---
873
874 ### Static Resources (12)
875
876 #### `musehub://trending`
877
878 Top 20 public repos ordered by star count. Anonymous-accessible.
879
880 **Returns:** array of repo summaries with `repo_id`, `name`, `owner`, `slug`, `description`, `visibility`, `clone_url`, `created_at`.
881
882 ---
883
884 #### `musehub://me`
885
886 Authenticated user's profile and their most recent 20 repos. Requires JWT.
887
888 **Returns:** `{ "user_id", "username", "repos": [...] }`
889
890 ---
891
892 #### `musehub://me/notifications`
893
894 Unread notifications for the authenticated user. Requires JWT.
895
896 **Returns:** `{ "notifications": [{ "id", "event_type", "read", "created_at" }] }`
897
898 ---
899
900 #### `musehub://me/starred`
901
902 Repos the authenticated user has starred. Requires JWT.
903
904 **Returns:** `{ "starred": [{ "repo_id", "name", "owner", "slug", "starred_at" }] }`
905
906 ---
907
908 #### `musehub://me/feed`
909
910 Activity feed for repos the authenticated user watches. Requires JWT.
911
912 **Returns:** `{ "feed": [...] }`
913
914 ---
915
916 ### Templated Resources (17)
917
918 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.
919
920 #### `musehub://repos/{owner}/{slug}`
921
922 Repo overview: metadata, visibility, default branch, tag list, description.
923
924 ---
925
926 #### `musehub://repos/{owner}/{slug}/branches`
927
928 All branches with their name, head commit ID, and last-updated timestamp.
929
930 ---
931
932 #### `musehub://repos/{owner}/{slug}/commits`
933
934 20 most recent commits on the default branch. Includes commit message, author, timestamp.
935
936 ---
937
938 #### `musehub://repos/{owner}/{slug}/commits/{commit_id}`
939
940 Single commit with its full snapshot manifest (all file paths and content hashes at that point).
941
942 ---
943
944 #### `musehub://repos/{owner}/{slug}/tree/{ref}`
945
946 File tree at a given ref. Returns all object paths and guessed MIME types.
947
948 ---
949
950 #### `musehub://repos/{owner}/{slug}/blob/{ref}/{path}`
951
952 Metadata for a single file at a given ref: path, content hash, MIME type, size.
953
954 ---
955
956 #### `musehub://repos/{owner}/{slug}/issues`
957
958 Open issues list with labels, assignees, and comment counts.
959
960 ---
961
962 #### `musehub://repos/{owner}/{slug}/issues/{number}`
963
964 Single issue with its full comment thread.
965
966 ---
967
968 #### `musehub://repos/{owner}/{slug}/pulls`
969
970 Open PRs with source/target branches and review counts.
971
972 ---
973
974 #### `musehub://repos/{owner}/{slug}/pulls/{number}`
975
976 Single PR with all inline comments and reviews (reviewer, state, body).
977
978 ---
979
980 #### `musehub://repos/{owner}/{slug}/releases`
981
982 All releases ordered newest first: tag, title, body, asset count, timestamp.
983
984 ---
985
986 #### `musehub://repos/{owner}/{slug}/releases/{tag}`
987
988 Single release matching a tag name, including the full release notes body.
989
990 ---
991
992 #### `musehub://repos/{owner}/{slug}/analysis/{ref}`
993
994 Musical analysis at a given ref: key, tempo, time signature, per-dimension scores (harmony, rhythm, groove, dynamics, orchestration, …).
995
996 ---
997
998 #### `musehub://repos/{owner}/{slug}/timeline`
999
1000 Musical evolution timeline: commits, section events, and track events in chronological order.
1001
1002 ---
1003
1004 #### `musehub://users/{username}`
1005
1006 User profile and their 20 most recent public repos.
1007
1008 ---
1009
1010 ## Prompts
1011
1012 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.
1013
1014 ### Getting a prompt
1015
1016 ```json
1017 {
1018 "jsonrpc": "2.0",
1019 "id": 1,
1020 "method": "prompts/get",
1021 "params": {
1022 "name": "musehub/orientation"
1023 }
1024 }
1025 ```
1026
1027 With arguments:
1028
1029 ```json
1030 {
1031 "jsonrpc": "2.0",
1032 "id": 1,
1033 "method": "prompts/get",
1034 "params": {
1035 "name": "musehub/contribute",
1036 "arguments": {
1037 "repo_id": "abc123",
1038 "owner": "alice",
1039 "slug": "my-song"
1040 }
1041 }
1042 }
1043 ```
1044
1045 ---
1046
1047 ### `musehub/orientation`
1048
1049 **Arguments:** `caller_type` (optional: `"human"` or `"agent"`)
1050
1051 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.
1052
1053 ---
1054
1055 ### `musehub/contribute`
1056
1057 **Arguments:** `repo_id`, `owner`, `slug`
1058
1059 End-to-end contribution workflow, including auth and push setup:
1060
1061 0. Confirm authentication and set up `muse remote` tracking
1062 1. `musehub_get_context` — understand the repo
1063 2. `musehub://repos/{owner}/{slug}/issues` — find open issues
1064 3. `musehub_create_issue` — or create a new one
1065 4. Make changes, push a commit via `muse_push`
1066 5. `musehub_create_pr` — open a PR
1067 6. `musehub_submit_pr_review` — request review
1068 7. `musehub_merge_pr` — merge when approved
1069
1070 ---
1071
1072 ### `musehub/create`
1073
1074 **Arguments:** `repo_id`
1075
1076 Domain-agnostic creation workflow:
1077
1078 1. `musehub_get_context` — understand existing content and structure
1079 2. `musehub://repos/{owner}/{slug}/analysis/{ref}` — study the domain-specific analysis
1080 3. Create domain artifacts matching the repo's dimensional constraints
1081 4. Push the commit via `muse_push`
1082 5. Verify with `musehub_get_domain_insights`
1083
1084 ---
1085
1086 ### `musehub/review_pr`
1087
1088 **Arguments:** `repo_id`, `pr_id`
1089
1090 Musical PR review:
1091
1092 1. `musehub_get_pr` — read the PR metadata
1093 2. `musehub_compare` — get per-dimension diff scores
1094 3. `musehub://repos/{owner}/{slug}/analysis/{ref}` — compare analyses for base and head
1095 4. `musehub_create_pr_comment` — post track/region-level comments
1096 5. `musehub_submit_pr_review` — approve or request changes
1097
1098 ---
1099
1100 ### `musehub/issue_triage`
1101
1102 **Arguments:** `repo_id`
1103
1104 Triage open issues:
1105
1106 1. `musehub_list_issues` — list open issues
1107 2. Categorise by type (bug, feature, discussion)
1108 3. `musehub_create_label` — create missing labels
1109 4. `musehub_update_issue` — apply labels, assign, close duplicates
1110
1111 ---
1112
1113 ### `musehub/release_prep`
1114
1115 **Arguments:** `repo_id`
1116
1117 Prepare a release:
1118
1119 1. `musehub_list_prs` — find merged PRs since the last release
1120 2. `musehub_list_releases` — check the latest release tag
1121 3. `musehub_get_domain_insights` — summarise domain-specific changes
1122 4. Draft release notes (Markdown)
1123 5. `musehub_create_release` — publish
1124
1125 ---
1126
1127 ### `musehub/onboard` _(MCP 2025-11-25)_
1128
1129 **Arguments:** `username` (optional)
1130
1131 Interactive artist onboarding using elicitation. Requires a client with session + elicitation capability:
1132
1133 1. `musehub_create_repo` — scaffold the first project repo
1134 2. `musehub_create_with_preferences` — elicits key, tempo, mood, genre; returns composition plan
1135 3. `musehub_connect_daw_cloud` — URL elicitation: OAuth-connect LANDR/Splice/Soundtrap
1136 4. Guides through first commit, collaboration invite, and activity feed
1137
1138 ---
1139
1140 ### `musehub/release_to_world` _(MCP 2025-11-25)_
1141
1142 **Arguments:** `repo_id`
1143
1144 Full elicitation-powered release and distribution pipeline:
1145
1146 1. `musehub_create_release_interactive` — form: collect tag, title, notes, highlight; URL: optional Spotify connect
1147 2. `musehub_connect_streaming_platform` — URL elicitation for each target platform
1148 3. `musehub_connect_daw_cloud` — optional cloud mastering via LANDR
1149 4. Post announcement issue and notify followers
1150
1151 ---
1152
1153 ### `musehub/domain-discovery`
1154
1155 **Arguments:** none
1156
1157 Discover and evaluate available domain plugins:
1158
1159 1. `musehub_list_domains` — enumerate all registered domain plugins
1160 2. `musehub_get_domain` — inspect a specific plugin's dimension manifest and capabilities
1161 3. `musehub_search_repos` — find repos using that domain
1162
1163 ---
1164
1165 ### `musehub/domain-authoring`
1166
1167 **Arguments:** `domain_id` (optional)
1168
1169 Author a new domain plugin from scratch or extend an existing one:
1170
1171 1. `musehub_list_domains` — understand the existing domain landscape
1172 2. Walk through dimension schema design, capability declaration, and scoped_id naming
1173 3. Validate by creating a test repo and calling `musehub_get_domain_insights`
1174
1175 ---
1176
1177 ## Error Handling
1178
1179 ### JSON-RPC error codes
1180
1181 | Code | Meaning |
1182 |------|---------|
1183 | `-32700` | Parse error — request body is not valid JSON |
1184 | `-32600` | Invalid request — not an object or array |
1185 | `-32601` | Method not found |
1186 | `-32602` | Invalid params — required argument missing or wrong type |
1187 | `-32603` | Internal error — unexpected server exception |
1188 | `-32001` | Authentication required — write tool called without valid JWT |
1189
1190 ### Tool errors
1191
1192 Tool execution errors are not JSON-RPC errors. The envelope is always a success response; the error is signalled inside the result:
1193
1194 ```json
1195 {
1196 "result": {
1197 "content": [{ "type": "text", "text": "repo not found: abc123" }],
1198 "isError": true
1199 }
1200 }
1201 ```
1202
1203 ---
1204
1205 ## Usage Patterns
1206
1207 ### Pattern 1: Discover and explore
1208
1209 ```
1210 1. resources/read musehub://trending → pick a repo
1211 2. resources/read musehub://repos/{owner}/{slug} → orientation
1212 3. tools/call musehub_get_context → full AI context
1213 4. resources/read musehub://repos/{owner}/{slug}/analysis/{ref} → musical detail
1214 ```
1215
1216 ### Pattern 2: Fix a bug, open a PR
1217
1218 ```
1219 1. tools/call musehub_list_issues { owner, slug, state: "open" }
1220 2. tools/call musehub_get_issue { owner, slug, issue_number }
1221 3. tools/call musehub_get_context { owner, slug }
1222 4. tools/call musehub_read_file { owner, slug, path }
1223 5. -- compose fix, push commit via muse_push --
1224 6. tools/call musehub_create_pr { owner, slug, title, from_branch, to_branch }
1225 ```
1226
1227 ### Pattern 3: Full musical PR review (elicitation-powered)
1228
1229 ```
1230 1. tools/call musehub_review_pr_interactive { repo_id, pr_id }
1231 → elicitation: "Focus on harmonic divergence, thorough depth"
1232 → returns: per-dimension scores, findings, APPROVE/REQUEST_CHANGES recommendation
1233 ```
1234
1235 Or stateless:
1236
1237 ```
1238 1. tools/call musehub_get_pr { repo_id, pr_id }
1239 2. tools/call musehub_compare { repo_id, base_ref, head_ref }
1240 3. tools/call musehub_create_pr_comment { repo_id, pr_id, body, target_type: "track", ... }
1241 4. tools/call musehub_submit_pr_review { repo_id, pr_id, event: "APPROVE" }
1242 ```
1243
1244 ### Pattern 4: Create with preferences (elicitation-powered)
1245
1246 ```
1247 1. POST initialize → Mcp-Session-Id: <id>
1248 2. GET /mcp (SSE) → open push channel
1249 3. tools/call musehub_create_with_preferences { owner, slug }
1250 → SSE: elicitation/create { mode: "form", schema: compose_preferences }
1251 → [user selects key: "D minor", tempo: 95, mood: "melancholic", genre: "neo-soul"]
1252 → POST elicitation result { action: "accept", content: { key: "D minor", ... } }
1253 → SSE: tools/call response { composition_plan: { ... } }
1254 ```
1255
1256 ### Pattern 5: Publish a release (elicitation-powered)
1257
1258 ```
1259 1. tools/call musehub_create_release_interactive { repo_id }
1260 → elicitation (form): tag, title, release notes, highlight
1261 → elicitation (URL, optional): Spotify OAuth
1262 → creates release + returns distribution guidance
1263 ```
1264
1265 Or stateless:
1266
1267 ```
1268 1. tools/call musehub_list_releases { owner, slug }
1269 2. tools/call musehub_list_prs { owner, slug, state: "closed" }
1270 3. tools/call musehub_get_domain_insights { owner, slug }
1271 4. tools/call musehub_create_release {
1272 owner, slug, tag: "v1.2.0", title: "Spring Drop",
1273 body: "## What changed\n..."
1274 }
1275 ```
1276
1277 ### Pattern 6: Connect and distribute (URL elicitation)
1278
1279 ```
1280 1. tools/call musehub_connect_streaming_platform { platform: "Spotify" }
1281 → SSE: elicitation/create { mode: "url", url: "https://musehub.app/musehub/ui/mcp/connect/spotify?elicitation_id=..." }
1282 → [user clicks through OAuth in browser]
1283 → SSE: notifications/elicitation/complete { action: "accept" }
1284 → returns: { platform: "Spotify", status: "connected" }
1285 ```
1286
1287 ---
1288
1289 ## Architecture Diagrams
1290
1291 ### Request flow
1292
1293 ```mermaid
1294 flowchart TD
1295 subgraph transports [Transports — MCP 2025-11-25]
1296 POST["POST /mcp\nJSON + SSE stream"]
1297 GET["GET /mcp\nSSE push channel"]
1298 DEL["DELETE /mcp\nSession termination"]
1299 stdio["stdio\npython -m musehub.mcp.stdio_server"]
1300 end
1301
1302 subgraph session [Session Layer]
1303 SID["Mcp-Session-Id"]
1304 ORIGIN["Origin validation"]
1305 SSE_Q["asyncio.Queue\nSSE queues"]
1306 FUTURES["asyncio.Future\nelicitation registry"]
1307 end
1308
1309 subgraph dispatcher [musehub/mcp/dispatcher.py]
1310 D["handle_request()"]
1311 D --> INIT["initialize"]
1312 D --> TL["tools/list"]
1313 D --> TC["tools/call"]
1314 D --> RL["resources/list"]
1315 D --> RR["resources/read"]
1316 D --> PL["prompts/list"]
1317 D --> PG["prompts/get"]
1318 D --> NC["notifications/cancelled"]
1319 D --> NEC["notifications/elicitation/complete"]
1320 end
1321
1322 subgraph execution [Execution Layer]
1323 READ["Read executors\nmusehub_mcp_executor.py"]
1324 WRITE["Write executors\nmcp/write_tools/"]
1325 ELICIT["Elicitation tools\nelicitation_tools.py"]
1326 CTX["ToolCallContext\ncontext.py"]
1327 RES["Resource handlers\nresources.py"]
1328 PROMPTS["Prompt assembler\nprompts.py"]
1329 end
1330
1331 POST --> ORIGIN
1332 POST --> SID
1333 SID --> D
1334 GET --> SSE_Q
1335 DEL --> SID
1336 stdio --> D
1337 TC --> READ
1338 TC --> WRITE
1339 TC --> ELICIT
1340 ELICIT --> CTX
1341 CTX --> SSE_Q
1342 CTX --> FUTURES
1343 RR --> RES
1344 PG --> PROMPTS
1345 NC --> FUTURES
1346 NEC --> FUTURES
1347 READ --> DB[("AsyncSession / Postgres")]
1348 WRITE --> DB
1349 RES --> DB
1350 ```
1351
1352 ### Tool catalogue structure
1353
1354 ```mermaid
1355 classDiagram
1356 class MUSEHUB_READ_TOOLS {
1357 <<list of MCPToolDef — 20 tools>>
1358 musehub_get_context
1359 musehub_list_branches
1360 musehub_list_commits
1361 musehub_read_file
1362 musehub_search
1363 musehub_get_commit
1364 musehub_compare
1365 musehub_list_issues
1366 musehub_get_issue
1367 musehub_list_prs
1368 musehub_get_pr
1369 musehub_list_releases
1370 musehub_search_repos
1371 musehub_list_domains
1372 musehub_get_domain
1373 musehub_get_domain_insights
1374 musehub_get_view
1375 musehub_whoami
1376 muse_pull
1377 muse_remote
1378 }
1379 class MUSEHUB_WRITE_TOOLS {
1380 <<list of MCPToolDef — 15 tools>>
1381 musehub_create_repo
1382 musehub_fork_repo
1383 musehub_create_issue
1384 musehub_update_issue
1385 musehub_create_issue_comment
1386 musehub_create_pr
1387 musehub_merge_pr
1388 musehub_create_pr_comment
1389 musehub_submit_pr_review
1390 musehub_create_release
1391 musehub_star_repo
1392 musehub_create_label
1393 musehub_create_agent_token
1394 muse_push
1395 muse_config
1396 }
1397 class MUSEHUB_ELICITATION_TOOLS {
1398 <<list of MCPToolDef — 5 tools — MCP 2025-11-25>>
1399 musehub_create_with_preferences
1400 musehub_review_pr_interactive
1401 musehub_connect_streaming_platform
1402 musehub_connect_daw_cloud
1403 musehub_create_release_interactive
1404 }
1405 class MCPDispatcher {
1406 +handle_request(raw, user_id, session)
1407 +handle_batch(raw, user_id, session)
1408 }
1409
1410 MCPDispatcher ..> MUSEHUB_READ_TOOLS : routes read calls
1411 MCPDispatcher ..> MUSEHUB_WRITE_TOOLS : routes write calls (JWT required)
1412 MCPDispatcher ..> MUSEHUB_ELICITATION_TOOLS : routes interactive calls (session required)
1413 ```
1414
1415 ### Resource URI hierarchy
1416
1417 ```mermaid
1418 flowchart TD
1419 root["musehub://"]
1420 root --> trending["trending"]
1421 root --> me["me"]
1422 root --> repos["repos/{owner}/{slug}"]
1423 root --> users["users/{username}"]
1424
1425 me --> notifications["me/notifications"]
1426 me --> starred["me/starred"]
1427 me --> feed["me/feed"]
1428
1429 repos --> branches["…/branches"]
1430 repos --> commits["…/commits"]
1431 commits --> commit["…/commits/{commit_id}"]
1432 repos --> tree["…/tree/{ref}"]
1433 repos --> blob["…/blob/{ref}/{path}"]
1434 repos --> issues["…/issues"]
1435 issues --> issue["…/issues/{number}"]
1436 repos --> pulls["…/pulls"]
1437 pulls --> pull["…/pulls/{number}"]
1438 repos --> releases["…/releases"]
1439 releases --> release["…/releases/{tag}"]
1440 repos --> analysis["…/analysis/{ref}"]
1441 repos --> timeline["…/timeline"]
1442 ```
1443
1444 ### Elicitation sequence (form mode)
1445
1446 ```mermaid
1447 sequenceDiagram
1448 participant Agent
1449 participant MCP as POST /mcp
1450 participant Session as Session Store
1451 participant Tool as Elicitation Tool
1452
1453 Agent->>MCP: POST initialize {capabilities: {elicitation: {form:{}, url:{}}}}
1454 MCP-->>Agent: 200 OK, Mcp-Session-Id: abc123
1455
1456 Agent->>MCP: GET /mcp (Accept: text/event-stream, Mcp-Session-Id: abc123)
1457 MCP-->>Agent: 200 text/event-stream (SSE channel open)
1458
1459 Agent->>MCP: POST tools/call musehub_create_with_preferences
1460 Note over MCP: tool needs elicitation → SSE response
1461 MCP->>Session: create_pending_elicitation("elicit-1")
1462 MCP-->>Agent: 200 text/event-stream (POST SSE open)
1463 MCP-->>Agent: SSE: elicitation/create {mode:"form", schema:{key,tempo,mood,...}}
1464
1465 Note over Agent: Shows form UI to user
1466
1467 Agent->>MCP: POST {jsonrpc:"2.0", id:"elicit-1", result:{action:"accept", content:{key:"Dm",...}}}
1468 MCP->>Session: resolve_elicitation("elicit-1", {action:"accept", content:...})
1469 MCP-->>Agent: 202 Accepted
1470
1471 Note over Tool: Future resolved, tool continues
1472
1473 MCP-->>Agent: SSE: tools/call response {composition_plan: {...}}
1474 Note over MCP: SSE stream closes
1475 ```
1476
1477 ### Elicitation sequence (URL mode)
1478
1479 ```mermaid
1480 sequenceDiagram
1481 participant Agent
1482 participant MCP as POST /mcp
1483 participant Browser as User's Browser
1484 participant UI as MuseHub UI /mcp/connect/...
1485
1486 Agent->>MCP: POST tools/call musehub_connect_streaming_platform {platform:"Spotify"}
1487 MCP-->>Agent: SSE: elicitation/create {mode:"url", url:"https://musehub.app/musehub/ui/mcp/connect/spotify?elicitation_id=xyz"}
1488
1489 Agent->>Browser: opens URL
1490 Browser->>UI: GET /musehub/ui/mcp/connect/spotify?elicitation_id=xyz
1491 UI-->>Browser: confirmation page
1492
1493 Browser->>UI: user clicks "Connect Spotify"
1494 UI->>UI: resolve_elicitation(session, "xyz", {action:"accept"})
1495 UI-->>Browser: callback page (auto-close tab)
1496
1497 MCP-->>Agent: SSE: notifications/elicitation/complete {elicitationId:"xyz", action:"accept"}
1498 MCP-->>Agent: SSE: tools/call response {platform:"Spotify", status:"connected"}
1499 ```