lacuna-music — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited lacuna-music (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generate AI music programmatically through the Lacuna Music API.
Activate when the user wants to:
"lofi piano, 70 bpm", "synthwave, retro drums")Three packages, same underlying API. Pick the first that fits the user's environment:
| When the user is using… | Use |
|---|---|
| Claude Code, Claude Desktop, Cursor, Zed, or another MCP client | lacuna-mcp |
| A Node / TypeScript script or backend | lacuna-sdk |
| Their shell, a CI job, a one-off prompt | lacuna-toolkit |
lacuna-mcp (preferred for AI agents)claude mcp add lacuna -- npx -y lacuna-mcpSet LACUNA_API_KEY in the MCP env block. After adding, three tools become available: generate_music, get_generation, wait_for_generation. Call generate_music then wait_for_generation to receive the final audio_url.
lacuna-sdkimport Lacuna from 'lacuna-sdk'
const lacuna = new Lacuna({ apiKey: process.env.LACUNA_API_KEY })
const task = await lacuna.music.generations.create({
style: 'lofi piano, 70 bpm, mellow',
title: 'Study session',
instrumental: true,
})
const finished = await lacuna.music.generations.waitFor(task.id)
console.log(finished.tracks[0]?.audio_url)lacuna-toolkitnpx lacuna-toolkit music generate \
--style "synthwave, retro drums, 110 bpm" \
--title "Neon Drive" \
--instrumental \
--wait \
--output jsonGet a key at lacuna.fm/profile/api. It begins with lyr_live_ and is shown once at creation. Pass it via LACUNA_API_KEY env var.
Music API access requires a Pro plan or above. Lower tiers receive 403 permission_error / tier_insufficient — do not retry; tell the user to upgrade.
| Field | Required | Models | Notes |
|---|---|---|---|
style | yes | all | Free-text style description, up to 1000 chars. |
title | yes | all | Track title. |
lyrics | yes if not instrumental | all | Plain text, up to 5000 chars. Use [Verse] / [Chorus] markers. |
instrumental | no | all | true skips lyrics. |
model | no | all | aether (default), echo, or nocturne. See model table below. |
vocal_gender | no | aether | 'm' or 'f' — lead vocal hint. |
negative_tags | no | aether | Style tags to avoid. |
style_weight | no | aether | 0–1. |
weirdness_constraint | no | aether | 0–1. |
audio_weight | no | aether | 0–1. |
duration | no | echo | Target track length in seconds, 5–240. Default 60. |
The API rejects model-incompatible fields with 400 invalid_param (e.g. passing duration with model: 'aether').
| Codename | Best for | Notes |
|---|---|---|
aether | Default. General-purpose, supports vocals + advanced weight knobs. | Only model that supports extend / cover / replace operations. |
echo | Short clips, BGM stingers, fast iteration with controllable length. | Use duration (5–240s). No vocal-gender / weight knobs. |
nocturne | High-quality vocals and emotional expression — quality over speed. | Style description carries vocal/BPM hints; no separate knobs. |
create returns immediately with a task in pending status.waitFor (SDK) / --wait (CLI) / wait_for_generation (MCP) polls until ready or failed.ready, task.tracks[] contains one or more renders, each with audio_url, duration, title, lyrics, image_url, tags.failed, inspect task.error — credits are refunded automatically.For production workflows, prefer the job.completed webhook over polling. See the SDK webhook docs for verification helpers.
402 insufficient_credits, do not retry — tell the user to top up.audio_urlaudio_url is a CDN URL valid for roughly 24 hours. If the output needs to persist (e.g., the user is embedding it into a long-lived asset), copy the bytes to durable storage immediately rather than referencing the CDN URL.
LACUNA_API_KEY.audio_url is permanent — see above.403 tier_insufficient or 402 insufficient_credits — these are user-action errors.503 model_unavailable, the requested model is temporarily circuit-broken (error.model names which one). Switch to a different model and retry; do not loop on the same one. The SDK does not auto-fallback because each model has a different credit cost.lacuna-sdklacuna-toolkitlacuna-mcp~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.