Musicwire Documentation

Deterministic MusicXML validation, MuseScore rendering, and automated QC API. Pay per call in USDC via x402 on Base.

Live on Base Loading...

Quickstart

MCP Client Configuration

The easiest way to use Musicwire is through the musicwire-mcp package.

Installation

# Run directly
npx -y musicwire-mcp

# Or install globally
npm install -g musicwire-mcp

Claude Code Configuration

Add to .mcp.json in your project:

{
  "mcpServers": {
    "musicwire": {
      "command": "npx",
      "args": ["-y", "musicwire-mcp"],
      "env": {
        "MUSICWIRE_API_URL": "https://musicwire.5432wire.com"
      }
    }
  }
}

Before starting Claude Code, export your buyer key:

export MUSICWIRE_X402_PRIVATE_KEY='0x...'
claude

Cursor Configuration

Add to .cursor/mcp.json (project) or global MCP config:

{
  "mcpServers": {
    "musicwire": {
      "command": "npx",
      "args": ["-y", "musicwire-mcp"],
      "env": {
        "MUSICWIRE_API_URL": "https://musicwire.5432wire.com"
      }
    }
  }
}

Start Cursor from an environment with MUSICWIRE_X402_PRIVATE_KEY.

Environment Variables

Variable Required Description
MUSICWIRE_API_URL No API base URL. Defaults to http://127.0.0.1:8787.
MUSICWIRE_X402_PRIVATE_KEY For paid calls Throwaway buyer private key, funded on the network this deployment advertises. Also accepts X402_PRIVATE_KEY.
MUSICWIRE_MCP_PAYMENT_MODE No x402 (default) or stub for local testing.

Important: musicwire-mcp selects its payment network from the service manifest, so it always pays on the network the target deployment advertises. Fund the buyer key for that network and treat the private key as a secret.

Raw HTTP + x402 Flow

For direct API access without MCP, use the x402 payment flow:

Step 1: Discovery (Get Quote)

Send your request. You'll receive a 402 Payment Required with the exact quote.

curl -X POST https://musicwire.5432wire.com/v1/validate \
  -H 'content-type: application/json' \
  -H 'Idempotency-Key: agent-validate-001' \
  --data '{"musicxml":"<?xml version="1.0"?><score-partwise version="4.0">...</score-partwise>"}'

# Response: 402 Payment Required
# Headers include: Payment-Required: x402-exact (encoded JSON with network, asset address, amount)

The response body contains the full quote including:

  • x402Version - Protocol version
  • accepts - Payment requirements (network, asset, amount)
  • quote - Human-readable quote with currency and price
  • output_schema - Expected response structure

Step 2: Payment Authorization

Use an x402 buyer to sign and retry the request with payment authorization.

# Using awal CLI
npx awal x402 details https://musicwire.5432wire.com/v1/validate -X POST

# Inspect the quote, then pay
npx awal x402 pay https://musicwire.5432wire.com/v1/validate \
  -X POST \
  -d '{"musicxml":"..."}' \
  -h '{"content-type":"application/json","Idempotency-Key":"agent-validate-001"}' \
  --max-amount 100000 \
  --json

Or use x402curl (note: x402curl 0.2.0 signed retry does not currently complete with the CDP facilitator - use MCP client or raw HTTP flow):

X402_PRIVATE_KEY="$MAINNET_PRIVATE_KEY" x402curl \
  --x402-rpc-url https://mainnet.base.org \
  -X POST \
  -H 'content-type: application/json' \
  --data-binary @request.json \
  https://musicwire.5432wire.com/v1/validate

This snippet targets the hosted deployment, which settles on Base mainnet (eip155:8453) with real USDC, so the buyer key and the --x402-rpc-url must both be for that network. Against a local Base Sepolia deployment, use a throwaway testnet key with --x402-rpc-url https://sepolia.base.org and your local URL instead.

Step 3: Use the Response

On success, you receive a 200 response with validation results and payment receipt.

{
  "valid": true,
  "errors": [],
  "price_usd": "0.10",
  "payment": {
    "status": "settled"
  },
  "receipt": {
    "tx_hash": "0x...",
    "amount_usd": "0.10",
    "amount_atomic": "100000",
    "network": "eip155:8453",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "pay_to": "0x..."
  }
}

The literal values above are Base mainnet: eip155:8453 and the Base mainnet USDC contract. The network and pay_to fields are replaced with this deployment's live values when it can be reached; a Base Sepolia deployment returns eip155:84532 and the Sepolia USDC contract instead. Read GET /.well-known/x402 for the authoritative receiver.

Local Development (Stub Mode)

For zero-cost local development, use the stub payment profile:

Run Musicwire in Stub Mode

# Using Docker Compose (recommended)
ARTIFACT_SIGNING_SECRET='replace-with-a-long-random-secret' \
  docker compose up
# Or directly with Node
ARTIFACT_SIGNING_SECRET='replace-with-a-long-random-secret' \
  MUSICWIRE_PAYMENT_MODE=stub \
  npm start

The stub profile accepts any request without real payment.

Run MCP Server in Stub Mode

MUSICWIRE_API_URL='http://127.0.0.1:8787' \
MUSICWIRE_MCP_PAYMENT_MODE=stub \
npx -y musicwire-mcp

Stub mode works only with localhost, 127.0.0.1, or ::1.

Endpoint Reference

All endpoints are versioned under /v1/. The /manifest and /.well-known/x402 endpoints provide machine-readable service and payment information.

GET /v1/compose-guide

Free - Static MusicXML authoring guide with versioned prompts.

Query Parameters:

  • style - Optional: musical style (e.g., waltz, march)
  • key - Optional: key signature (e.g., C major, F major)
  • tempo - Optional: BPM value

Example:

curl 'http://localhost:8787/v1/compose-guide?style=waltz&key=F%20major&tempo=84'

POST /v1/validate

Loading... - Detailed MusicXML validation with line-level diagnostics.

Request Body:

{
  "musicxml": "<?xml version="1.0"?><score-partwise version="4.0">...</score-partwise>"
}

Accepts raw application/xml bytes or JSON with musicxml string.

Headers:

  • Idempotency-Key - Optional: indefinite replay only for the same verified payer and MusicXML request context
  • Payment-Signature - x402 payment authorization (auto-added by MCP client)

Response:

{
  "valid": true,
  "errors": [],
  "price_usd": "0.10",
  "payment": { "status": "settled" },
  "receipt": { ... }
}

On validation failure (422), includes errors array with line, measure, message, and fix_hint.

POST /v1/render

Loading... - Queue a MusicXML render with multiple output formats.

Request Body:

{
  "musicxml": "<?xml version="1.0"?><score-partwise version="4.0">...</score-partwise>",
  "formats": ["pdf", "mp3", "midi"],
  "constraints_check": {
    "tempo": 120,
    "duration_seconds": 60,
    "key_fifths": 0,
    "mode": "major"
  }
}

Headers:

  • Idempotency-Key - Strongly recommended: 24-hour replay only for the same verified payer and render request context
  • Payment-Signature - x402 payment authorization

Response (202 Accepted):

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued",
  "estimated_seconds": 30,
  "price_usd": "0.25",
  "payment": {
    "status": "verified_pending_qc",
    "capture_policy": "capture_only_after_qc_pass"
  },
  "poll_url": "/v1/jobs/550e8400-e29b-41d4-a716-446655440000"
}

Supported Formats:

mscz, pdf, svg, png, midi, mp3, wav. Always returns: musicxml, NOTICE.txt, receipt.json.

svg and png are page sets (multiple files for multi-page scores).

Note: Pricing is loading.... Solo pricing applies to 1 part; ensemble pricing applies when part count exceeds the boundary.

GET /v1/jobs/{id}

Loading... - Poll job status and retrieve artifacts.

Response:

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "facts": {
    "partCount": 1,
    "tempo": 120,
    "key": { "fifths": 0, "mode": "major" },
    "scoreDurationSeconds": 60
  },
  "qc": {
    "status": "passed",
    "checks": ["validation", "renderer_exit", "artifacts_present", ...]
  },
  "payment": { "status": "settled" },
  "receipt": { ... },
  "expires_at": "2026-01-01T00:00:00.000Z",
  "artifacts": [
    {
      "name": "receipt.json",
      "sha256": "abc123...",
      "bytes": 1234,
      "url": "/v1/artifacts/.../receipt.json?expires=...&token=..."
    },
    { "name": "output.pdf", ... }
  ]
}

Poll until status is completed or failed_not_charged.

GET /v1/artifacts/{jobId}/{name}

Free - Download a signed artifact URL.

The signed API URL authorizes access, then responds with a 302 redirect to a short-lived, artifact-scoped presigned URL in the private S3 bucket. Clients must follow redirects to download the named binary artifact.

GET /manifest

Free - Machine-readable service manifest with all endpoints, pricing, and capabilities.

GET /.well-known/x402

Free - x402-specific payment configuration for automated client discovery.

GET /health

Free - Renderer readiness probe.

Payment Explainer

Mainnet and testnet

The network in force is the one this deployment advertises. Read it from GET /manifest and from the 402 quote itself; every payment requirement is issued for that network only.

  • Network: Base (eip155:8453)
  • Asset: USDC
  • Receiver: see GET /.well-known/x402
  • Payment Mode: x402 Exact via CDP Facilitator

The hosted deployment at musicwire.5432wire.com is pinned to Base mainnet (eip155:8453) and charges real USDC. Local and stub deployments default to Base Sepolia (eip155:84532) and charge test USDC. Never send mainnet funds to a test deployment.

Get test USDC for Base Sepolia runs from the Circle Base Sepolia faucet or the QuickNode Base Sepolia faucet.

How Payment Works

  1. Discovery: You send a request. Musicwire returns 402 Payment Required with the exact quote including network, asset, amount, and payment requirements.
  2. Authorization: Your x402 client reads the Payment-Required header, signs an EIP-3009 Exact authorization with your buyer wallet, and retries the identical request with Payment-Signature header.
  3. Verification: Musicwire verifies the authorization before starting any work.
  4. QC Pass: For paid endpoints (validate, render), Musicwire runs quality control on the result.
  5. Settlement: Only after QC passes, Musicwire settles the payment via the CDP facilitator and returns the receipt with transaction hash.

Important: A charge is structurally impossible until QC passes. Failed validation or rendering is failed_not_charged with no settlement.

Payment Statuses

Status Meaning
not_charged No payment was authorized or attempted
verified_pending_qc Authorization verified, waiting for QC result
settled Payment settled on-chain, transaction confirmed
settlement_pending Settlement in progress, will retry
failed_not_charged QC failed, no charge was made

Idempotency

Use the Idempotency-Key header to safely retry requests without double-charging.

  • POST /v1/render replays for 24 hours only when the same verified payer submits the same render request context with the same key.
  • POST /v1/validate replays indefinitely only when the same verified payer submits the same MusicXML request context with the same key.
  • Replay includes the original payment status and receipt
  • A key presented by a different payer never resolves another payer's result.

Best practice: Always use an idempotency key for paid requests.

Attribution

Each completed render includes NOTICE.txt containing:

  • MS Basic license text
  • FluidR3 font attribution
  • Michael Cowgill attribution
  • S. Christian Collins attribution

receipt.json includes:

  • Renderer version
  • Sound profile
  • Soundfont SHA-256
  • rendered_by: "Musicwire"
  • This repository URL

Customers own their compositions. Audio can be used commercially when the NOTICE travels with it.

Rate Limits & Retention

Rate Limiting

Default: 60 requests per minute per IP address.

Rate limited responses return 429 Too Many Requests.

Artifact Retention

Completed artifacts are retained for 30 days and then removed. Download what you need before then.

Artifact URLs are signed and expire with the job retention window.

Job records, payment status, and receipts are retained after an artifact expires, so payment proof always outlives the artifact it paid for.