MuseHub MCP Reference
Protocol version: 2025-11-25 | Implementation: pure-Python async, no external MCP SDK
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.
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.
Table of Contents
- Architecture
- Transports
- Authentication
- Session Management
- Elicitation
- Tools — 40 total
- Resources — 29 total
- Prompts — 10 total
- Error Handling
- Usage Patterns
- Architecture Diagrams
Architecture
MCP Client (Cursor, Claude Desktop, any SDK)
│
├─ HTTP POST /mcp (all client→server)
├─ HTTP GET /mcp (SSE push, server→client)
├─ HTTP DELETE /mcp (session termination)
└─ stdio python -m musehub.mcp.stdio_server (local dev)
│
musehub/api/routes/mcp.py ← Streamable HTTP transport (2025-11-25)
│
musehub/mcp/dispatcher.py ← async JSON-RPC 2.0 engine
│
┌───────┼───────────────┬────────────────┐
│ │ │ │
tools/call resources/read prompts/get notifications/*
│ │ │ │
Read executors Resource handlers Prompt Session/Elicitation
(musehub_mcp_executor.py) (resources.py) assembler (session.py)
Write executors (context.py)
Elicitation tools
(mcp/write_tools/elicitation_tools.py)
│
AsyncSession → Postgres
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.
Transports
HTTP Streamable — Full 2025-11-25 Transport
POST /mcp
The production transport. Accepts application/json. Returns application/json for most requests, or text/event-stream for elicitation-powered tool calls.
POST /mcp HTTP/1.1
Content-Type: application/json
Authorization: MSign handle="..." ts=... sig="..."
Mcp-Session-Id: <session-id> ← required after initialize
MCP-Protocol-Version: 2025-11-25 ← optional; validated if present
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
Batch requests — send a JSON array; responses are returned as an array in the same order (notifications are filtered out):
POST /mcp
[
{"jsonrpc":"2.0","id":1,"method":"tools/list"},
{"jsonrpc":"2.0","id":2,"method":"resources/list"}
]
Notifications (no id) return 202 Accepted with an empty body.
GET /mcp — SSE Push Channel
Persistent server-to-client event stream. Required for receiving elicitation requests and progress notifications outside of an active tool call.
GET /mcp HTTP/1.1
Accept: text/event-stream
Mcp-Session-Id: <session-id>
Last-Event-ID: <last-seen-event-id> ← optional; triggers replay
Returns text/event-stream. Server pushes:
notifications/progress— tool progress updateselicitation/create— server-initiated user input requestsnotifications/elicitation/complete— URL-mode OAuth completion signals: heartbeat— comment every 15 s to keep proxies alive
DELETE /mcp — Session Termination
DELETE /mcp HTTP/1.1
Mcp-Session-Id: <session-id>
Returns 200 OK. Closes all open SSE streams and cancels pending elicitation Futures for the session.
stdio — python -m musehub.mcp.stdio_server
The local dev and Cursor IDE transport. Reads newline-delimited JSON from stdin, writes JSON-RPC responses to stdout, logs to stderr.
Cursor IDE integration — create or update .cursor/mcp.json in your workspace:
{
"mcpServers": {
"musehub": {
"command": "python",
"args": ["-m", "musehub.mcp.stdio_server"],
"cwd": "/path/to/musehub"
}
}
}
The stdio server runs without auth (trusted local process). Write tools are available unconditionally.
Authentication
| Context | How |
|---|---|
| HTTP transport — read tools + public resources | No auth required |
| HTTP transport — write / elicitation tools | Authorization: MSign handle="..." ts=... sig="..." |
| HTTP transport — private repo resources | Authorization: MSign handle="..." ts=... sig="..." |
| stdio transport | No auth (trusted process) |
MuseHub uses Ed25519 / MSign request signing. Register your Ed25519 public key via POST /api/auth/challenge → POST /api/auth/verify. The muse CLI manages key registration and signs all requests automatically. The verified handle claim is used as the acting user_id for all write operations.
Attempting a write tool without a valid MSign request returns a JSON-RPC error (code: -32001, message: "Authentication required for write tools").
Session Management
Session management is required for elicitation and the GET /mcp SSE push channel.
Creating a session:
POST /mcp
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{"elicitation":{"form":{},"url":{}}}}}
Response includes:
Mcp-Session-Id: <cryptographically-secure-session-id>
Using the session: include Mcp-Session-Id in all subsequent requests. Sessions expire after 1 hour of inactivity.
Ending a session: DELETE /mcp with the Mcp-Session-Id header.
Security: All requests are validated against an Origin allowlist (localhost always permitted; production: musehub.ai). Requests from unlisted Origins are rejected with 403 Forbidden.
Elicitation
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:
Form Mode
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.
Agent MuseHub MCP
│ │
│ POST tools/call │
│ (musehub_review_proposal_interactive)
│──────────────────────────►│
│ │ opens SSE stream
│◄──────────────────────────│
│ SSE: elicitation/create │
│ {mode:"form", schema:{ │
│ dimension_focus, depth,│
│ reviewer_note, ...}} │
│◄──────────────────────────│
│ [user fills form] │
│ POST elicitation result │
│ {action:"accept", │
│ content:{dimension_focus│
│ :"harmonic",...}} │
│──────────────────────────►│
│ │ tool continues
│ SSE: tools/call response │
│◄──────────────────────────│
Elicitation Schemas
MuseHub exposes two form schemas used by the interactive tools:
| Schema key | Used by | Fields |
|---|---|---|
proposal_review_focus |
musehub_review_proposal_interactive |
dimension_focus (all/melodic/harmonic/rhythmic/structural/dynamic), review_depth (quick/standard/thorough), check_harmonic_tension, check_rhythmic_consistency, reviewer_note |
release_metadata |
musehub_create_release_interactive |
tag, title, release_notes, is_prerelease, highlight |
Tools
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.
Repo identification: repo_id or owner + slug
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:
{ "repo_id": "abc-123-uuid" }
// or equivalently:
{ "owner": "gabriel", "slug": "jazz-standards" }
Calling a tool
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "musehub_get_context",
"arguments": { "owner": "gabriel", "slug": "jazz-standards" }
}
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [{ "type": "text", "text": "{\"name\":\"my-song\", ...}" }],
"isError": false
}
}
Read Tools (21)
musehub_get_context
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
musehub_list_branches
All branches with their head commit IDs and timestamps.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
musehub_list_commits
Paginated commit history, newest first.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
branch |
string | no | Branch name filter |
limit |
integer | no | Max commits (default 20) |
musehub_read_file
Metadata for a single artifact (MIDI, MP3, WebP, etc.) at a given commit.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
path |
string | yes | File path within the repo |
commit_id |
string | no | Commit SHA (defaults to HEAD) |
musehub_search
Keyword/path search over commits and file paths within a repo.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
query |
string | yes | Search terms |
mode |
string | no | "path" (default) or "commit" |
musehub_get_commit
Single commit detail with the full snapshot manifest (all file paths and content hashes at that point in history).
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
commit_id |
string | yes | Commit SHA |
musehub_compare
Musical diff between two refs — returns per-dimension change scores (harmony, rhythm, groove, key, tempo) and a list of changed file paths.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
base_ref |
string | yes | Base branch, tag, or commit SHA |
head_ref |
string | yes | Head branch, tag, or commit SHA |
musehub_list_issues
Issues with optional state, label, and assignee filters.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
state |
string | no | "open" (default) or "closed" |
label |
string | no | Label name filter |
assignee |
string | no | Assignee username filter |
musehub_get_issue
Single issue with its full comment thread.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
issue_number |
integer | yes | Issue number |
musehub_list_proposals
Proposals with optional state and base branch filters.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
state |
string | no | "open" (default), "closed", or "merged" |
base |
string | no | Target branch filter |
musehub_get_proposal
Single proposal with all inline comments and reviews.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
proposal_number |
integer | yes | Proposal number |
musehub_list_releases
All releases for a repo with asset counts and timestamps.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
musehub_search_repos
Discover public repos by text query or musical attributes.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | no | Text search query |
key |
string | no | Musical key filter (e.g. "C major") |
tempo_min |
integer | no | Minimum BPM |
tempo_max |
integer | no | Maximum BPM |
tags |
array of strings | no | Tag filters |
limit |
integer | no | Max results (default 20) |
musehub_list_domains
List all available domain plugins registered in MuseHub (e.g. MIDI, Genomics, Code).
No parameters required.
musehub_get_domain
Full definition for a single domain plugin — scoped_id, version, dimension manifest, capabilities, and schema.
| Parameter | Type | Required | Description |
|---|---|---|---|
domain_id |
string | yes | Domain plugin identifier (e.g. "midi-v1") |
musehub_get_domain_insights
Computed analytics for a repo using its domain plugin — per-dimension scores, distribution stats, and trend data.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
ref |
string | no | Branch, tag, or commit SHA (defaults to HEAD) |
musehub_get_view
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
ref |
string | no | Branch, tag, or commit SHA (defaults to HEAD) |
musehub_whoami
Return the authenticated user's profile. Useful for confirming token identity before write operations.
No parameters required.
musehub_list_labels
List all labels defined in a repository. Returns label_id, name, color, and description for each label. Use the label_id values with musehub_update_label and musehub_delete_label. No authentication required.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
muse_pull
Pull latest commits from MuseHub into a local Muse working tree — equivalent of muse pull on the command line.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
branch |
string | no | Branch to pull (defaults to current) |
muse_remote
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
ref |
string | no | Branch or tag to reference in the clone command |
Write Tools (22)
All write tools require a valid MSign request signature (
Authorization: MSign handle="..." ts=... sig="...") on the HTTP transport.
musehub_create_repo
Create a new repository.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Repository name |
owner |
string | yes | Owner username |
owner_user_id |
string | yes | Owner user UUID |
description |
string | no | Short description |
visibility |
string | no | "public" (default) or "private" |
tags |
array of strings | no | Initial tags |
key_signature |
string | no | Musical key (e.g. "G major") |
tempo_bpm |
integer | no | Tempo in BPM |
initialize |
boolean | no | Create initial commit (default true) |
musehub_create_issue
Open a new issue.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
title |
string | yes | Issue title |
body |
string | no | Issue description (Markdown) |
labels |
array of strings | no | Label names to apply |
assignee_id |
string | no | Assignee user UUID |
musehub_update_issue
Update issue state or metadata.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Issue number |
state |
string | no | "open" or "closed" |
title |
string | no | New title |
body |
string | no | New body |
assignee_id |
string | no | New assignee UUID |
labels |
array of strings | no | Replace label set |
musehub_create_issue_comment
Post a comment on an issue.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Issue number |
body |
string | yes | Comment body (Markdown) |
musehub_create_proposal
Open a merge proposal.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
title |
string | yes | Proposal title |
from_branch |
string | yes | Source branch |
to_branch |
string | yes | Target branch |
body |
string | no | Proposal description (Markdown) |
musehub_merge_proposal
Merge an open proposal.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
proposal_number |
integer | yes | Proposal number |
merge_message |
string | no | Custom merge commit message |
musehub_create_proposal_comment
Post an inline comment on a proposal. Supports general, track-level, and beat-range comments — mirroring the musical diff view in the web UI.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
proposal_number |
integer | yes | Proposal number |
body |
string | yes | Comment body (Markdown) |
target_type |
string | no | "general" (default), "track", "region", or "note" |
target_track |
string | no | Track name (when target_type is "track" or finer) |
target_beat_start |
number | no | Start beat position |
target_beat_end |
number | no | End beat position |
musehub_submit_proposal_review
Submit a formal review on a proposal.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
proposal_number |
integer | yes | Proposal number |
state |
string | yes | "approved", "changes_requested", or "commented" |
body |
string | no | Review summary |
musehub_create_release
Publish a release.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
tag |
string | yes | Tag name (e.g. "v1.0.0") |
title |
string | yes | Release title |
body |
string | no | Release notes (Markdown) |
commit_id |
string | no | Target commit SHA (defaults to HEAD) |
is_prerelease |
boolean | no | Mark as pre-release (default false) |
musehub_create_label
Create a label scoped to a repository. Names must be unique within the repo; color must be a 7-character hex string starting with # (e.g. "#d73a4a"). Repos are pre-seeded with default labels (bug, enhancement, question, documentation, etc.) on creation.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
name |
string | yes | Label name (max 50 chars, unique per repo) |
color |
string | yes | 7-char hex color starting with # (e.g. "#d73a4a") |
description |
string | no | Label description (max 200 chars) |
musehub_update_label
Partially update an existing label — rename it, change its colour, or update its description. Only the fields you provide are changed; omitted fields stay as-is. The new name must still be unique within the repository. Get label_id from musehub_list_labels.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
label_id |
string | yes | UUID of the label to update (from musehub_list_labels) |
name |
string | no | New label name (max 50 chars, must be unique per repo) |
color |
string | no | New 7-char hex color starting with # (e.g. "#b60205") |
description |
string | no | New description (max 200 chars; pass "" to clear) |
musehub_delete_label
Permanently delete a label from a repository and remove it from every issue and proposal it is currently attached to. This operation is irreversible. Get label_id from musehub_list_labels.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
label_id |
string | yes | UUID of the label to delete (from musehub_list_labels) |
musehub_close_issue
Close an open issue. Idempotent — closing an already-closed issue returns the issue unchanged. Reverse with musehub_reopen_issue.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Per-repo issue number |
musehub_reopen_issue
Reopen a closed issue. Idempotent — reopening an already-open issue returns the issue unchanged. Reverse with musehub_close_issue.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Per-repo issue number |
musehub_assign_issue
Assign or unassign a collaborator on an issue. Pass assignee="" (empty string) to clear the current assignee.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Per-repo issue number |
assignee |
string | yes | Username to assign, or empty string to unassign |
musehub_set_issue_labels
Bulk-replace the label list on an issue. The new list replaces all existing labels. Pass labels=[] to remove all labels. Use musehub_remove_issue_label to remove a single label without affecting others.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Per-repo issue number |
labels |
array of strings | yes | Replacement label list (replaces all existing labels) |
musehub_remove_issue_label
Remove a single label from an issue. Idempotent — silently no-ops when the label is not present. Use musehub_set_issue_labels to replace the entire label list.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
issue_number |
integer | yes | Per-repo issue number |
label |
string | yes | Label name to remove |
muse_push
Push a Muse mpack to MuseHub — equivalent of muse push on the command line.
Accepts the full wire format: commits, snapshot manifests, and content-addressed
objects in a single round-trip. Snapshots are stored idempotently — re-pushing an
existing snapshot_id is a safe no-op.
{
"name": "muse_push",
"arguments": {
"owner": "alice",
"slug": "my-song",
"branch": "main",
"head_commit_id": "sha256:abc...",
"commits": [
{
"commit_id": "sha256:abc...",
"parent_ids": ["sha256:parent..."],
"message": "feat: add bridge section",
"author": "alice",
"timestamp": "2026-03-21T18:00:00Z",
"snapshot_id": "sha256:snap..."
}
],
"snapshots": [
{
"snapshot_id": "sha256:snap...",
"manifest": {
"tracks/piano.mid": "sha256:obj-piano...",
"tracks/strings.mid": "sha256:obj-strings..."
}
}
],
"objects": [
{
"object_id": "sha256:obj-piano...",
"path": "tracks/piano.mid",
"size": 4096,
"content_b64": "<base64-encoded bytes>"
}
]
}
}
Fast-forward enforcement: rejected with HTTP 409 Conflict if the push would
create a non-linear history. Use force: true to override (destructive — use with care).
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
branch |
string | yes | Target branch name |
head_commit_id |
string | yes | SHA of the new branch tip |
commits |
array | yes | List of CommitInput objects (see wire format) |
snapshots |
array | no | List of SnapshotInput objects — snapshot_id + manifest dict |
objects |
array | no | List of ObjectInput objects — content-addressed blobs |
force |
boolean | no | Override fast-forward check (default: false) |
muse_config
Read or write per-repo Muse configuration values — equivalent of muse config on the command line.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | no | Repository UUID (or use owner + slug) |
owner |
string | no | Owner username (use with slug) |
slug |
string | no | Repository slug (use with owner) |
key |
string | yes | Config key to read or write |
value |
string | no | Value to set (omit to read the current value) |
Elicitation-Powered Tools (5)
Three execution paths — no session required for bypass or schema guide.
| Path | Requirements | Behaviour | |------|-------------|-----------| | Elicitation | Active session + elicitation capability declared | Interactive form / URL presented to user mid-call | | Bypass | Supply bypass params (see each tool) | Returns result immediately; zero round-trips | | Schema guide | No session, no bypass params | Returns
ok: truewithmode: "schema_guide"— a complete field guide for the next call |The bypass path makes all five tools usable in any headless agent, CI pipeline, or client that does not support MCP sessions.
musehub_review_proposal_interactive (form elicitation | bypass: dimension, depth)
Deep musical proposal review, either interactively or from explicit parameters.
Elicitation path — elicits: dimension focus, review depth, harmonic tension check, rhythmic consistency check, reviewer note.
Bypass path — pass dimension and/or depth directly:
{
"name": "musehub_review_proposal_interactive",
"arguments": {
"repo_id": "repo-uuid",
"proposal_id": "proposal-uuid",
"dimension": "harmonic",
"depth": "thorough"
}
}
Either or both bypass params may be provided; missing values default to "all" and "standard" respectively.
Schema guide (no session, no bypass params) — returns dimension_options and depth_options lists.
Returns: per-dimension divergence scores, findings list (with harmonic tension and rhythmic checks), and a recommendation (APPROVE / REQUEST_CHANGES / COMMENT).
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository UUID |
proposal_id |
string | yes | Proposal UUID |
dimension |
string | no | Bypass: one of melodic, harmonic, rhythmic, structural, dynamic, all |
depth |
string | no | Bypass: one of quick, standard, thorough |
musehub_create_release_interactive (chained form + URL elicitation | bypass: tag)
Two-phase interactive release creator, or direct release creation via bypass params.
Elicitation path:
- Form: collects tag, title, release notes, changelog highlight, and pre-release flag.
- URL (optional): offers Spotify OAuth for immediate distribution.
Bypass path — supply tag (required); title and notes are optional:
{
"name": "musehub_create_release_interactive",
"arguments": {
"repo_id": "repo-uuid",
"tag": "v1.2.0",
"title": "Spring release",
"notes": "New chord voicings, tempo map fixes."
}
}
Schema guide (no session, no tag) — returns field guide with required/optional labels.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_id |
string | yes | Repository to create the release in |
tag |
string | no | Bypass: semantic version tag (e.g. v1.2.0); triggers direct release creation |
title |
string | no | Bypass: human-readable release title (defaults to tag) |
notes |
string | no | Bypass: release notes / changelog body |
Resources
Resources are side-effect-free, cacheable, URI-addressable reads. All resources return application/json. They are read via the resources/read method.
Listing resources
{"jsonrpc":"2.0","id":1,"method":"resources/list"}
{"jsonrpc":"2.0","id":2,"method":"resources/templates/list"}
Reading a resource
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/read",
"params": { "uri": "musehub://trending" }
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"contents": [{
"uri": "musehub://trending",
"mimeType": "application/json",
"text": "[{\"repo_id\":\"...\",\"name\":\"my-song\",...}]"
}]
}
}
Static Resources (12)
musehub://trending
Top 20 public repos ordered by star count. Anonymous-accessible.
Returns: array of repo summaries with repo_id, name, owner, slug, description, visibility, clone_url, created_at.
musehub://me
Authenticated user's profile and their most recent 20 repos. Requires MSign auth.
Returns: { "user_id", "username", "repos": [...] }
musehub://me/notifications
Unread notifications for the authenticated user. Requires MSign auth.
Returns: { "notifications": [{ "id", "event_type", "read", "created_at" }] }
musehub://me/starred
Repos the authenticated user has starred. Requires MSign auth.
Returns: { "starred": [{ "repo_id", "name", "owner", "slug", "starred_at" }] }
musehub://me/feed
Activity feed for repos the authenticated user watches. Requires MSign auth.
Returns: { "feed": [...] }
Templated Resources (17)
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.
musehub://repos/{owner}/{slug}
Repo overview: metadata, visibility, default branch, tag list, description.
musehub://repos/{owner}/{slug}/branches
All branches with their name, head commit ID, and last-updated timestamp.
musehub://repos/{owner}/{slug}/commits
20 most recent commits on the default branch. Includes commit message, author, timestamp.
musehub://repos/{owner}/{slug}/commits/{commit_id}
Single commit with its full snapshot manifest (all file paths and content hashes at that point).
musehub://repos/{owner}/{slug}/tree/{ref}
File tree at a given ref. Returns all object paths and guessed MIME types.
musehub://repos/{owner}/{slug}/blob/{ref}/{path}
Metadata for a single file at a given ref: path, content hash, MIME type, size.
musehub://repos/{owner}/{slug}/issues
Open issues list with labels, assignees, and comment counts.
musehub://repos/{owner}/{slug}/issues/{number}
Single issue with its full comment thread.
musehub://repos/{owner}/{slug}/pulls
Open proposals with source/target branches and review counts.
musehub://repos/{owner}/{slug}/pulls/{number}
Single proposal with all inline comments and reviews (reviewer, state, body).
musehub://repos/{owner}/{slug}/releases
All releases ordered newest first: tag, title, body, asset count, timestamp.
musehub://repos/{owner}/{slug}/releases/{tag}
Single release matching a tag name, including the full release notes body.
musehub://repos/{owner}/{slug}/analysis/{ref}
Musical analysis at a given ref: key, tempo, time signature, per-dimension scores (harmony, rhythm, groove, dynamics, orchestration, …).
musehub://repos/{owner}/{slug}/timeline
Musical evolution timeline: commits, section events, and track events in chronological order.
musehub://users/{username}
User profile and their 20 most recent public repos.
Prompts
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.
Getting a prompt
{
"jsonrpc": "2.0",
"id": 1,
"method": "prompts/get",
"params": {
"name": "musehub/orientation"
}
}
With arguments:
{
"jsonrpc": "2.0",
"id": 1,
"method": "prompts/get",
"params": {
"name": "musehub/contribute",
"arguments": {
"repo_id": "abc123",
"owner": "alice",
"slug": "my-song"
}
}
}
musehub/orientation
Arguments: caller_type (optional: "human" or "agent")
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.
musehub/contribute
Arguments: repo_id, owner, slug
End-to-end contribution workflow, including auth and push setup:
- Confirm authentication and set up
muse remotetracking musehub_get_context— understand the repomusehub://repos/{owner}/{slug}/issues— find open issuesmusehub_create_issue— or create a new one- Make changes, push a commit via
muse_push musehub_create_proposal— open a proposalmusehub_submit_proposal_review— request reviewmusehub_merge_proposal— merge when approved
musehub/create
Arguments: repo_id
Domain-agnostic creation workflow:
musehub_get_context— understand existing content and structuremusehub://repos/{owner}/{slug}/analysis/{ref}— study the domain-specific analysis- Create domain artifacts matching the repo's dimensional constraints
- Push the commit via
muse_push - Verify with
musehub_get_domain_insights
musehub/review_proposaloposal
Arguments: repo_id, proposal_id
Dimension-aware proposal review: get proposal → read domain insights → compare branches → submit review with dimension_ref-anchored comments.
musehub_get_proposal— read the proposal metadatamusehub_compare— get per-dimension diff scoresmusehub_create_proposal_comment— post dimension-anchored commentsmusehub_submit_proposal_review— approve or request changes
musehub/issue_triage
Arguments: repo_id
Triage open issues: list → label → assign → link to milestones.
musehub_list_issues— list open issues- Categorise by type (bug, feature, discussion)
musehub_create_label— create missing labelsmusehub_update_issue— apply labels, assign, close duplicates
musehub/release_prep
Arguments: repo_id
Prepare a release: check merged proposals → write release notes → create release with version tag.
musehub_list_proposals— find merged proposals since the last releasemusehub_list_releases— check the latest release tagmusehub_get_domain_insights— summarise domain-specific changes- Draft release notes (Markdown)
musehub_create_release— publish
musehub/onboard (MCP 2025-11-25)
Arguments: username
Interactive creator onboarding (MCP 2025-11-25 elicitation-aware). Guides a new MuseHub creator through: profile setup → domain selection (via musehub_list_domains) → first repo creation → initial state scaffold → optional cloud integration. Requires an active session with elicitation capability.
musehub/safe-to-merge
Arguments: repo_id, proposal_id
Pre-merge safety audit for a merge proposal. Runs: risk score → symbol diff → breakage check → blast radius → CI status → reviews. Produces a structured merge recommendation: APPROVE, APPROVE WITH CAUTION, or BLOCK.
musehub_proposal_risk— overall risk scoremusehub_proposal_symbol_diff— symbol-level changesmusehub_proposal_breakage— structural breakage check
musehub/pre-release-audit
Arguments: repo_id
Full repository health audit before cutting a release. Runs: health score → hotspots → dead code → blast risk → open proposals → recent breakages. Produces a structured GO / GO WITH CAUTION / NO-GO release recommendation.
musehub_intel_health_score— overall healthmusehub_intel_hotspots— high-churn symbolsmusehub_intel_dead— dead code detectionmusehub_intel_blast_risk— highest-impact symbols
musehub/agent-onboarding
Arguments: repo_id, agent_id, queue
Onboarding guide for a new agent joining a multi-agent swarm on a MuseHub repository. Covers: authenticate → get context → survey swarm state → reserve symbols → claim task → commit with provenance → complete task. Teaches the read-reserve-edit-commit cycle and how to avoid conflicts with concurrent agents.
musehub_coord_swarm— survey active agentsmusehub_coord_tasks— see available workmusehub_coord_claim_task— claim a taskmusehub_coord_reserve— reserve symbols before editing
musehub/symbol-investigation
Arguments: repo_id, address
Deep-dive symbol investigation workflow: find a symbol → read its body → compute blast radius → trace provenance → surface co-change partners → check for active reservations. Produces a structured investigation report suitable for deciding whether to edit the symbol or delegate to another agent.
musehub_get_symbol— read symbol body and metadatamusehub_symbol_impact— compute blast radiusmusehub_coord_reservations— check for active reservations
Error Handling
JSON-RPC error codes
| Code | Meaning |
|---|---|
-32700 |
Parse error — request body is not valid JSON |
-32600 |
Invalid request — not an object or array |
-32601 |
Method not found |
-32602 |
Invalid params — required argument missing or wrong type |
-32603 |
Internal error — unexpected server exception |
-32001 |
Authentication required — write tool called without a valid MSign request |
Tool errors
Tool execution errors are not JSON-RPC errors. The envelope is always a success response; the error is signalled inside the result:
{
"result": {
"content": [{ "type": "text", "text": "repo not found: abc123" }],
"isError": true
}
}
Usage Patterns
Pattern 1: Discover and explore
1. resources/read musehub://trending → pick a repo
2. resources/read musehub://repos/{owner}/{slug} → orientation
3. tools/call musehub_get_context → full AI context
4. resources/read musehub://repos/{owner}/{slug}/analysis/{ref} → musical detail
Pattern 2: Fix a bug, open a proposal
1. tools/call musehub_list_issues { owner, slug, state: "open" }
2. tools/call musehub_get_issue { owner, slug, issue_number }
3. tools/call musehub_get_context { owner, slug }
4. tools/call musehub_read_file { owner, slug, path }
5. -- compose fix, push commit via muse_push --
6. tools/call musehub_create_proposal { owner, slug, title, from_branch, to_branch }
Pattern 3: Full musical proposal review (elicitation-powered)
1. tools/call musehub_review_proposal_interactive { repo_id, proposal_id }
→ elicitation: "Focus on harmonic divergence, thorough depth"
→ returns: per-dimension scores, findings, APPROVE/REQUEST_CHANGES recommendation
Or stateless:
1. tools/call musehub_get_proposal { repo_id, proposal_id }
2. tools/call musehub_compare { repo_id, base_ref, head_ref }
3. tools/call musehub_create_proposal_comment { repo_id, proposal_id, body, target_type: "track", ... }
4. tools/call musehub_submit_proposal_review { repo_id, proposal_id, event: "APPROVE" }
Pattern 4: Publish a release (elicitation-powered)
1. tools/call musehub_create_release_interactive { repo_id }
→ elicitation (form): tag, title, release notes, highlight
→ creates release + returns release record
Or stateless:
1. tools/call musehub_list_releases { owner, slug }
2. tools/call musehub_list_proposals { owner, slug, state: "closed" }
3. tools/call musehub_get_domain_insights { owner, slug }
4. tools/call musehub_create_release {
owner, slug, tag: "v1.2.0", title: "Spring Drop",
body: "## What changed\n..."
}
Architecture Diagrams
Request flow
flowchart TD
subgraph transports [Transports — MCP 2025-11-25]
POST["POST /mcp\nJSON + SSE stream"]
GET["GET /mcp\nSSE push channel"]
DEL["DELETE /mcp\nSession termination"]
stdio["stdio\npython -m musehub.mcp.stdio_server"]
end
subgraph session [Session Layer]
SID["Mcp-Session-Id"]
ORIGIN["Origin validation"]
SSE_Q["asyncio.Queue\nSSE queues"]
FUTURES["asyncio.Future\nelicitation registry"]
end
subgraph dispatcher [musehub/mcp/dispatcher.py]
D["handle_request()"]
D --> INIT["initialize"]
D --> TL["tools/list"]
D --> TC["tools/call"]
D --> RL["resources/list"]
D --> RR["resources/read"]
D --> PL["prompts/list"]
D --> PG["prompts/get"]
D --> NC["notifications/cancelled"]
D --> NEC["notifications/elicitation/complete"]
end
subgraph execution [Execution Layer]
READ["Read executors\nmusehub_mcp_executor.py"]
WRITE["Write executors\nmcp/write_tools/"]
ELICIT["Elicitation tools\nelicitation_tools.py"]
CTX["ToolCallContext\ncontext.py"]
RES["Resource handlers\nresources.py"]
PROMPTS["Prompt assembler\nprompts.py"]
end
POST --> ORIGIN
POST --> SID
SID --> D
GET --> SSE_Q
DEL --> SID
stdio --> D
TC --> READ
TC --> WRITE
TC --> ELICIT
ELICIT --> CTX
CTX --> SSE_Q
CTX --> FUTURES
RR --> RES
PG --> PROMPTS
NC --> FUTURES
NEC --> FUTURES
READ --> DB[("AsyncSession / Postgres")]
WRITE --> DB
RES --> DB
Tool catalogue structure
classDiagram
class MUSEHUB_READ_TOOLS {
<<list of MCPToolDef — 38 tools>>
musehub_set_context
musehub_get_context
musehub_list_branches
musehub_list_commits
musehub_read_file
musehub_search
musehub_get_commit
musehub_compare
musehub_list_issues
musehub_get_issue
musehub_list_proposals
musehub_get_proposal
musehub_proposal_risk
musehub_proposal_symbol_diff
musehub_proposal_breakage
musehub_list_releases
musehub_search_repos
musehub_list_domains
musehub_get_domain
musehub_get_domain_insights
musehub_get_view
musehub_whoami
musehub_get_prompt
musehub_list_symbols
musehub_get_symbol
musehub_symbol_impact
musehub_symbol_clones
musehub_intel_index_status
musehub_intel_health_score
musehub_intel_hotspots
musehub_intel_dead
musehub_intel_blast_risk
musehub_coord_swarm
musehub_coord_reservations
musehub_coord_check_conflicts
musehub_coord_tasks
musehub_cross_repo_impact
musehub_workspace_intel
}
class MUSEHUB_CLI_TOOLS {
<<list of MCPToolDef — 4 tools>>
muse_pull
muse_remote
muse_push
muse_config
}
class MUSEHUB_WRITE_TOOLS {
<<list of MCPToolDef — 21 tools>>
musehub_create_repo
musehub_create_issue
musehub_update_issue
musehub_create_issue_comment
musehub_create_proposal
musehub_merge_proposal
musehub_create_proposal_comment
musehub_submit_proposal_review
musehub_create_release
musehub_create_label
musehub_publish_domain
musehub_agent_notify
musehub_agent_broadcast
musehub_coord_claim_task
musehub_coord_complete_task
musehub_coord_fail_task
musehub_coord_extend_reservation
musehub_coord_reserve
musehub_coord_release
musehub_coord_enqueue
}
class MUSEHUB_ELICITATION_TOOLS {
<<list of MCPToolDef — 2 tools — MCP 2025-11-25>>
musehub_review_proposal_interactive
musehub_create_release_interactive
}
class MCPDispatcher {
+handle_request(raw, user_id, session)
+handle_batch(raw, user_id, session)
}
MCPDispatcher ..> MUSEHUB_READ_TOOLS : routes read calls
MCPDispatcher ..> MUSEHUB_CLI_TOOLS : routes Muse VCS calls
MCPDispatcher ..> MUSEHUB_WRITE_TOOLS : routes write calls (MSign auth required)
MCPDispatcher ..> MUSEHUB_ELICITATION_TOOLS : routes interactive calls (session required)
Resource URI hierarchy
flowchart TD
root["musehub://"]
root --> trending["trending"]
root --> me["me"]
root --> repos["repos/{owner}/{slug}"]
root --> users["users/{username}"]
me --> notifications["me/notifications"]
me --> starred["me/starred"]
me --> feed["me/feed"]
repos --> branches["…/branches"]
repos --> commits["…/commits"]
commits --> commit["…/commits/{commit_id}"]
repos --> tree["…/tree/{ref}"]
repos --> blob["…/blob/{ref}/{path}"]
repos --> issues["…/issues"]
issues --> issue["…/issues/{number}"]
repos --> pulls["…/pulls"]
pulls --> pull["…/pulls/{number}"]
repos --> releases["…/releases"]
releases --> release["…/releases/{tag}"]
repos --> analysis["…/analysis/{ref}"]
repos --> timeline["…/timeline"]
Elicitation sequence (form mode)
sequenceDiagram
participant Agent
participant MCP as POST /mcp
participant Session as Session Store
participant Tool as Elicitation Tool
Agent->>MCP: POST initialize {capabilities: {elicitation: {form:{}, url:{}}}}
MCP-->>Agent: 200 OK, Mcp-Session-Id: abc123
Agent->>MCP: GET /mcp (Accept: text/event-stream, Mcp-Session-Id: abc123)
MCP-->>Agent: 200 text/event-stream (SSE channel open)
Agent->>MCP: POST tools/call musehub_review_proposal_interactive {repo_id, proposal_id}
Note over MCP: tool needs elicitation → SSE response
MCP->>Session: create_pending_elicitation("elicit-1")
MCP-->>Agent: 200 text/event-stream (POST SSE open)
MCP-->>Agent: SSE: elicitation/create {mode:"form", schema:{dimension_focus,review_depth,...}}
Note over Agent: Shows form UI to user
Agent->>MCP: POST {jsonrpc:"2.0", id:"elicit-1", result:{action:"accept", content:{dimension_focus:"harmonic",...}}}
MCP->>Session: resolve_elicitation("elicit-1", {action:"accept", content:...})
MCP-->>Agent: 202 Accepted
Note over Tool: Future resolved, tool continues
MCP-->>Agent: SSE: tools/call response {scores: {...}, recommendation: "APPROVE"}
Note over MCP: SSE stream closes