Skip to main content
Glama

loopclub-mcp

Jam with Claude. An MCP server that turns a described beat into a loopclub link — ready to audition and rent on-chain. It is a pure encoder over loopgen: it holds no keys, talks to no chain, and signs nothing. Your Claude does the musical thinking and calls build_loop; the server bit-packs it and returns a ?jam= deep link. You open the link, audition the loop free, and rent the cells yourself in the app.

 you (to your Claude):  "dark techno — four-on-the-floor kick, off-beat hats, a low C2 synth drone"
        │
        ▼  Claude calls build_loop({ tracks: [...] })
 loopclub-mcp  →  loopgen.encode → toLink → ?jam= link + ASCII grid
        │
        ▼  Claude replies with the link
 you click  →  loopclub opens with the loop pre-loaded  →  "Rent these cells"  →  one signature

Install

Claude Code:

claude mcp add loopclub -- npx -y loopclub-mcp

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "loopclub": { "command": "npx", "args": ["-y", "loopclub-mcp"] }
  }
}

Set LOOPCLUB_ORIGIN to point links at a specific deployment (defaults to https://app.loopclub.xyz — the app subdomain that handles ?jam= links; the apex loopclub.xyz is the landing page and ignores the param):

{ "mcpServers": { "loopclub": {
  "command": "npx", "args": ["-y", "loopclub-mcp"],
  "env": { "LOOPCLUB_ORIGIN": "https://app.loopclub.xyz" }
}}}

Related MCP server: DAW MIDI Generator MCP

Remote (hosted) — add it on claude.ai with no install

The same server runs over MCP's Streamable HTTP transport so claude.ai (Pro/Max) users can add it as a custom connector by URL — no local tooling:

Settings → Connectors → Add custom connector → https://<host>/mcp

The deployed host is mcp.<your-tunnel-domain> (the branded mcp.loopclub.xyz needs loopclub.xyz's DNS moved to Cloudflare — see deploy/). Exact deploy steps for the VPS are in deploy/ (systemd user unit + Cloudflare tunnel rule).

Run it yourself:

npm run build
npm run start:http          # listens on 127.0.0.1:8787 (POST /mcp), front with a proxy

It binds to localhost only and is meant to sit behind a TLS-terminating reverse proxy / Cloudflare tunnel (see deploy/). It is no-auth by design — the server holds no keys, signs nothing, and is a pure stateless encoder, so there is nothing to steal. The risks of a public endpoint are abuse / DoS, not data loss; those are bounded both in-process (body cap, input bounds, host/origin allowlist, rate limit, stateless JSON mode) and at the edge (Cloudflare WAF). Full threat model: SECURITY.md.

Config (env, all optional):

var

default

purpose

PORT

8787

listen port

MCP_BIND_HOST

127.0.0.1

bind address — keep on localhost behind a proxy

MCP_ALLOWED_HOSTS

mcp.loopclub.xyz,localhost,127.0.0.1

Host-header allowlist (DNS-rebind defense)

MCP_ALLOWED_ORIGINS

https://app.loopclub.xyz,https://loopclub.xyz

Origin allowlist (absent Origin = allowed; foreign = 403)

MCP_MAX_BODY_BYTES

65536

request body cap

MCP_RATE_MAX / MCP_RATE_WINDOW_MS

120 / 60000

coarse per-IP rate limit (Cloudflare is primary)

LOOPCLUB_ORIGIN

https://app.loopclub.xyz

origin baked into emitted ?jam= links

What it exposes

Tools

  • build_loop({ tracks, name? }) → { deepLink, asciiGrid, cellCount, instruments, note }. The core. tracks mirror a loopgen LoopSpec: drum tracks carry lit steps (0–15); the synth track carries notes ({ step, pitch }, pitch as MIDI or a name like "C3").

  • describe_loop({ link } | { pattern, synthData? }) → a per-track summary + the ASCII grid. Reads a ?jam= link a user pasted, or raw wire bigints.

Resources (so Claude generates good loops, not random cells)

  • loopclub://vocabulary — the grid rules, pitch range, and how to be musical.

  • loopclub://genres — worked example loops (house, techno, boom-bap, dnb) as ASCII + spec, for few-shot grounding.

  • loopclub://how-it-works — the free-audition / paid-press lifecycle.

Prompt

  • jam({ genre?, bpm? }) — a one-click entry point that tells Claude to read the resources, build something idiomatic and in-key, and return the link.

Design boundary (deliberate)

  • No signing, no keys, no wallet, no chain reads. The server only produces links; the user signs rent in the app. This is why session keys / PR #6 are irrelevant here.

  • Stateless. Same spec in → same link out. Restartable, trivially scalable if hosted later (a remote Streamable-HTTP build is a fast-follow).

  • The musical engine is entirely loopgen; this package is ~3 small files of glue (schemas → handlers → server).

Develop

npm install          # pulls loopclub-loopgen from npm
npm test             # vitest — handler logic + loopgen round-trip
node scripts/smoke.mjs   # end-to-end: spawns the server, drives real JSON-RPC
npm run build        # tsc → dist/ (bin: loopclub-mcp)

loopgen — the musical codec this server encodes with — is published separately as loopclub-loopgen and developed in the loopclub monorepo. A change to the on-chain wire format means a new loopgen release and a bump here.

Available Tools

2 tools
build_loopBuild a loopclub loopA

Turn a described beat into a loopclub link. Returns a ?jam= deep link, an ASCII grid preview, the lit-cell count, and the instruments used. The user opens the link to audition the loop free and rent the cells in-app. Read loopclub://vocabulary and loopclub://genres first for idiomatic loops.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNooptional label, used in the share copy
tracksYesthe loop, as a list of tracks

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does well: it discloses the return contents (deep link, ASCII grid, lit-cell count, instruments), the free-audition/paid-rent model, and a prerequisite read order. It does not mention auth, rate limits, or whether built loops persist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences: purpose first, return values second, downstream workflow third, prerequisite last. Every sentence carries information an agent needs, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Because there is no output schema, the description must cover returns and it does, naming each returned field. Missing are failure modes, auth/persistence behavior for a no-annotation tool, but the core is complete enough to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so instrument/steps/notes/pitch semantics are fully documented in the schema. The description adds no parameter-level meaning beyond that, which is the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('turn a described beat into a loopclub link') and enumerates the concrete artifacts returned. It does not name or differentiate itself from the sibling describe_loop, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear workflow context: the link is opened to audition free and rent cells in-app, and it explicitly directs the agent to read loopclub://vocabulary and loopclub://genres first. No when-not or alternative-vs-describe_loop guidance, so not a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_loopDescribe a loopclub loopA

Read a loop back: pass a ?jam= link (or raw pattern/synthData bigints) and get a human-readable, per-track summary plus the ASCII grid. Use it to inspect a loop a user pasted, or to verify what you just built.

ParametersJSON Schema
NameRequiredDescriptionDefault
linkNoa loopclub ?jam= link or just the jam param
patternNoalternatively, the raw pattern as a hex/decimal bigint
synthDataNothe raw synthData bigint (paired with `pattern`)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that this is a read operation, describes the accepted input forms (link or raw bigints), and states the output shape. It doesn't cover error cases or parameter interactions, but for a simple read tool this is solid context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with zero waste. The core purpose is front-loaded, followed immediately by the two usage scenarios, which is ideal structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with no output schema, the description provides enough: it explains inputs, output format, and use cases. The only minor gap is not specifying behavior when no parameters are provided or when inputs conflict, but that's non-critical.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description largely restates that information ('?jam= link (or raw pattern/synthData bigints)') without adding new semantics, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read a loop back') and resource (loop), and makes the contrast with the sibling build_loop explicit ('verify what you just built'). It also specifies the return format (per-track summary plus ASCII grid), so an agent can distinguish it instantly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives two clear use cases: inspect a pasted loop, or verify a just-built loop. This implies the when and is tied to the sibling, but it does not name alternatives explicitly or state when not to use it, keeping it just below the top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedbuild_loop
    • First observeddescribe_loop

TDQS

A4.2/5.0

Scored across 2 tools

Disambiguation5/5

build_loop creates a loop from a described beat, while describe_loop reads an existing loop back. The two operations are exact opposites with no overlapping purpose, making misselection very unlikely.

Naming Consistency5/5

Both names follow a strict snake_case verb_noun pattern and share the same noun stem (loop). This is highly predictable and consistent.

Tool Count3/5

Two tools is thin for a loop-building service, even if create/read are the core operations. It sits at the borderline of feeling under-scoped rather than clearly appropriate.

Completeness4/5

The server covers the main lifecycle of constructing a loop and inspecting it, which matches the stated purpose of generating and verifying ?jam= links. Minor gaps like updating, deleting, or listing loops are not present, but loops may be treated as immutable links.

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    Connects Claude AI to Ableton Live through the Model Context Protocol, enabling prompt-assisted music production with track creation, instrument loading, clip editing, and session control. Allows users to create complete musical arrangements by describing what they want in natural language.
    37
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language control over Ableton Live for generating musical patterns, melodies, and full song arrangements. It also provides tools for sample searching and mixing assistance through an OSC-based connection with Claude Desktop.
    1
    MIT