Developer Docs

Publish from your coding agent

Connect Claude Code, Claude Desktop, Cursor or any other MCP client to the Crela MCP server. Your agent prepares the listing, checks the build, submits it and reacts to review feedback - you only set the price and confirm.

Overview

There are two ways to work with Crela programmatically:

Both use the same API key and run through the same review pipeline. Nothing goes live without passing the review.

MCP Setup

1

Create an API key

In your creator dashboard. The full key is shown once; it starts with crela_.

2

Add the server to your agent

One click for the common clients:

  • Claude Desktop: open crela.mcpb or drag it into Settings → Extensions. If your system asks which app should open it, choose Claude. Claude asks for your API key and keeps it in your system keychain.
  • VS Code: asks for your API key as a password field during installation.
  • Cursor: installs with an empty key. Paste your key into CRELA_API_KEY under Cursor Settings → MCP; search works without it.

Claude Code, one command:

claude mcp add crela --env CRELA_API_KEY=crela_... -- npx -y @crela/mcp

Cursor (~/.cursor/mcp.json), Claude Desktop without the extension (claude_desktop_config.json) and most other clients take the same JSON block:

{
  "mcpServers": {
    "crela": {
      "command": "npx",
      "args": ["-y", "@crela/mcp"],
      "env": { "CRELA_API_KEY": "crela_..." }
    }
  }
}
3

Ask your agent

Open your project and say something like "Publish this tool to Crela for 9.99 EUR". The agent reads the requirements, prepares the listing and shows you the draft before it submits.

Security: The key belongs in the MCP client config, never in the chat and never in source control. Prefer the user-level config over a project file that gets committed.

The discovery tools work without a key. CRELA_BASE_URL is optional and defaults to https://crela.io. The server runs locally over stdio and needs Node.js 18 or newer.

MCP Tools

Every key-authenticated API action has exactly one MCP tool. Tool inputs mirror the server-side rules, so invalid values are rejected before anything is uploaded.

Discovery (no API key)

search_softwareSearch approved marketplace software by query, category, language and sort order.
get_softwareFull public detail of one listing, looked up by slug.
get_submission_requirementsMachine-readable submission rules, K.O. criteria and live thresholds. Call it before every submission.

Publish (needs CRELA_API_KEY)

list_my_softwareEvery tool you own with id, slug, review status, unlisted flag, price and sales count.
precheck_buildDry run of the submit gate on a build ZIP: framework detection, bundle completeness, SDK marker and file limit. Returns a storage_path you can reuse.
preview_markerCompute the SDK marker (KO-10) for a planned slug, to embed in a paid build before the first submission.
get_sdk_markerFetch the SDK marker of an existing tool before building a new paid version.
submit_new_softwareCreate a brand-new listing from a build ZIP plus metadata and start its review.
update_softwareShip a new build of an existing tool (presign, direct upload, finalize). channel "demo" publishes a demo without touching the live listing.

Review (needs CRELA_API_KEY)

check_review_statusLightweight review progress, current sub-step and remaining update quota.
get_review_reportFull review report: pass or fail, rejection reasons and the findings to fix.

Manage listings (needs CRELA_API_KEY)

get_my_software_detailsFull metadata and media list (with ids) of one of your tools, in any status.
set_metadataChange metadata without a new build: texts, price, sales, trials, devices, tags, privacy policy, unlisted.
upload_screenshotUpload a screenshot or logo from a local file (JPG, PNG, WebP or GIF, max 5 MB).
update_mediaChange the sort order of a media item or the URL of a video entry.
delete_mediaRemove a screenshot, logo or video entry from a listing.
delete_softwarePermanently delete a tool that was never sold. Sold tools are unlisted instead.

Publish Workflow

First submission

  1. 1

    get_submission_requirements - Learn the rules, required fields and K.O. criteria.

  2. 2

    precheck_build - Dry-run the submit gate and fix missing files or the marker before spending a review cycle.

  3. 3

    submit_new_software - Metadata plus the build. Pass the storage_path from the precheck so the ZIP travels only once.

  4. 4

    upload_screenshot - At least 3 images; the review scores the presentation on them.

  5. 5

    check_review_status - Poll until the review completes, then read get_review_report, fix the findings and resubmit.

Shipping analytics or telemetry? Set privacy_policy and name the service in it - KO-09 rejects builds that contact a tracker the policy does not mention.

New versions

Ship a new build with update_software (software id, build ZIP, version, os, arch). Versions are semver. A release build goes through the review again; channel: "demo" publishes a demo without touching the live listing. Paid tools embed the SDK marker from get_sdk_marker first (see Copy Protection). Lost a software id? list_my_software returns all of them.

Search Connector

Just want your assistant to find software on Crela? Add the hosted connector by URL. There is nothing to install and no API key - it works in the browser, on your phone and on the desktop.

https://crela.io/mcp

In Claude: Settings → Connectors → Add custom connector, then paste the URL. Other assistants that support remote MCP servers take the same URL.

It offers search_software and get_software, each result with a link to its Crela page, where you buy it. Publishing needs the local server from MCP Setup, because it reads your build files and uses your API key.

REST API

The MCP server is a thin client over these endpoints. Use them directly from CI/CD or your own scripts.

Base URL: https://crela.ioJSON responses unless noted (multipart for file uploads)

Authentication

All endpoints except GET /api/agent/requirements require a Bearer token.

Authorization: Bearer crela_<your-api-key>

Create keys in your creator dashboard. The full key is shown once on creation. Keys have the prefix crela_.

Security: Never commit your API key to source control. Use an environment variable: CRELA_API_KEY.

Quickstart

Submit your first tool in 5 steps:

1

Create an API key

Dashboard → API Keys → Create key. Copy it immediately - it's shown only once.

2

Read platform requirements

curl https://crela.io/api/agent/requirements
3

Submit software

# framework / entrypoint / install_type / platforms / license are
# detected by the server from the build ZIP. You only send marketing content
# plus the ZIP.
curl -X POST https://crela.io/api/agent/software \
  -H "Authorization: Bearer $CRELA_API_KEY" \
  -F "file=@dist/myapp-build.zip" \
  -F "title=My App" \
  -F "slug=my-app" \
  -F "description=A short description" \
  -F "long_description=Full markdown description" \
  -F 'categories=["tool"]' \
  -F "price_eur=0" \
  -F "version=1.0.0" \
  -F "system_requirements=Windows 10+"
4

Save the tool ID

# Response: { "id": "tool_abc123", "slug": "my-app", "status": "pending_review" }
TOOL_ID="tool_abc123"
5

Poll the review

# Repeat every 30 s until review_job_status != "running"
curl https://crela.io/api/agent/software/$TOOL_ID/review \
  -H "Authorization: Bearer $CRELA_API_KEY"

API Reference

Get Requirements

GET/api/agent/requirementsNo auth required

Machine-readable schema with submission constraints, K.O. criteria, quality guidelines, and content rules. Fetch before every submission.

{
  "schema_version": "1",
  "submission": { /* required/optional fields, types, constraints */ },
  "ko_rules": [ /* 12 hard-rejection rules (KO-01..KO-12) */ ],
  "quality_guidelines": { /* 5 scored evaluation categories */ },
  "content_rules": { /* allowed/blocked URLs */ }
}

Build format: portable builds only

Crela accepts portable builds only - no setup wizard, no installer. Primary support: Windows; Linux builds (AppImage/ELF) are accepted, macOS support is in progress.

Definition

Portable means: after extraction from the ZIP archive, the program runs without a setup wizard, without writing registry entries, without requiring administrator rights, and without a global installation in Program Files.

Rule: scripts must be compiled in

If the program logic resides in script files that an interpreter would have to load at runtime, those files must be compiled into the executable (AutoHotkey via Ahk2Exe, AutoIt via Aut2Exe, Python via PyInstaller). An interpreter plus loose script files is not accepted - this applies to all frameworks.

Allowed formats

  • ZIP archive with EXE and dependencies (folder portable, Windows)
  • Single EXE (PyInstaller onefile, Go static, Rust static)
  • .NET single-file self-contained (AOT or JIT)
  • Java fat JAR or JLink bundle
  • Electron / asar as ZIP
  • Tauri bundle as ZIP (Windows)
  • AppImage (Linux - recommended, because the frontend is extracted alongside)
  • Linux ELF + companion files as ZIP (limited - for Tauri or Electron builds the embedded frontend is brotli-compressed, so the pipeline cannot inspect it)

Automatically rejected

  • NSIS installers (e.g. *Setup.exe, *-installer.exe)
  • InnoSetup (*Setup.exe)
  • MSI and MSIX
  • WiX-generated installers
  • Self-extracting setup wrappers - even if the result would be portable
  • macOS .dmg images
  • macOS .pkg packages (XAR)
  • Linux .deb packages
  • Linux .rpm packages

Supported frameworks

Electron / asarC++ / Qt native.NET (WPF, WinForms, single-file AOT, .NET Framework)Python (PyInstaller onedir or onefile)Java (fat JAR, JLink bundle)Go (statically linked single EXE)Rust (statically linked single EXE, incl. Tauri)NW.jsFlutter (Windows Desktop)wxWidgets / GTK nativePascal / Lazarus / DelphiAutoIt / AutoHotkey (compiled via Ahk2Exe/Aut2Exe only, no setup wrapper - interpreter + script file is rejected)

Your framework is not on the list? Contact support - we will review adding it. No automatic reject.

List Software

GET/api/agent/software

All tools you own with id, slug, status, version, price, unlisted flag and sales count, newest first. Optional query: status filter and limit (1 to 100, default 50).

Precheck Build

POST/api/agent/software/precheckmultipart/form-data

Dry run of the submit gate: framework detection, bundle completeness, SDK marker (KO-10) and file limit. Creates no listing and starts no review. Send file or a storage_path from Presign Upload, plus slug and price_eur; framework, entrypoint and platforms are optional overrides. The upload stays available, so the same storage_path can go straight into submit or a build update.

Submit Software

POST/api/agent/softwaremultipart/form-data

Submit a new software listing.

Required fields

filebinaryBuild artifacts ZIP (.zip only). Max 2 GB, max 200 executable files. The server detects framework / entrypoint / install_type / platforms from it.
titlestringDisplay name
slugstringURL-friendly unique identifier
descriptionstringShort description shown in listings
long_descriptionstringFull description, Markdown supported
categoriesJSON array"tool" | "game" | "finance" | "productivity" | "creative" | "other"
price_eurnumber0 for free, or ≥ 0.99
versionstringSemver, e.g. "1.0.0"
system_requirementsstringe.g. "Windows 10+, 4 GB RAM"

Auto-detected fields (the server reads them from the ZIP, optional creator override possible)

frameworkstringelectron / tauri / dotnet / java / python / native. Detected from app.asar / *.jar / BSJB magic / PyInstaller cookie / Tauri bundle pattern.
entrypointstringPath to the main file in the ZIP. Prioritizes *-setup.exe / .msi / .AppImage / .dmg, otherwise the only .exe without a _lib suffix. On ambiguity the API returns 400 with a candidate list.
install_typestringinstaller / executable / script / zip / other. Detected from ZIP contents.
platformsJSON array"windows" / "macos" / "linux" / "cross". Detected from the PE / Mach-O / ELF magic of the binaries.
licensestringDefault: "Crela Standard EULA v1" (Steam model, same license for all tools).
symbolsin the ZIP.pdb / .dSYM/* / .debug files are detected in the build ZIP, stored separately under symbols/<sha> and automatically deleted after 30 days (GDPR). For framework=native they are REQUIRED in the ZIP, otherwise the build is rejected with a clear error message.

Conditional fields

macos_notarized"1"|"0"Required "1" when the server finds Mach-O binaries in the ZIP. The creator notarizes via an Apple Developer account; the pipeline verifies with spctl --assess (Steam model).
requires_system_rights"1"|"0"Default "0". Apps with a driver/service/UAC prompt are rejected in phase 1.

Optional fields

tagsJSON arrayAdditional discovery tags
tool_languagestringUI language code of the software, e.g. "de" (not the programming language)
privacy_policystringPrivacy policy text, not a link - KO-09 checks telemetry providers against it
support_contactstringSupport email or URL
screenshot_0-4binaryUp to 5 screenshot files
coverbinaryCover image for marketplace cards (falls back to first screenshot if omitted)
launcher_coverbinarySeparate cover image for the launcher tile (optional, defaults to cover)
video_urlstringYouTube or Vimeo link

Response 201 Created

{
  "id": "tool_abc123",
  "slug": "my-app",
  "title": "My App",
  "created_at": "2025-01-01T00:00:00.000Z",
  "status": "pending_review"
}

Get Software

GET/api/agent/software/{id}

Fetch full metadata and media list for a tool you own, in any status.

{
  "tool": {
    "id": "tool_abc123",
    "slug": "my-app",
    "title": "My App",
    "status": "approved",
    "version": "1.0.0"
    /* ... all metadata fields */
  },
  "media": [
    { "id": "m1", "type": "screenshot", "url": "https://...", "sort_order": 0 }
  ]
}
DELETE/api/agent/software/{id}

Permanently delete a tool including builds and media. Only possible if it was never sold; otherwise 409 - unlist it with PATCH { "unlisted": true } instead, buyers keep their access.

Update Metadata

PATCH/api/agent/software/{id}application/json

Partial update of metadata. Changing brand fields (title, description, categories) on an approved tool automatically queues a re-review.

Patchable: title · description · long_description · categories · tags · price_eur · sale_price_eur · sale_ends_at · max_devices · system_requirements · license · tool_language · platforms · install_type · privacy_policy · support_contact · drm_mode · video_url · framework · requires_system_rights · unlisted · trial_enabled · trial_days

// Request body (any subset)
{ "description": "Updated short description", "price_eur": 4.99 }

// Response
{
  "ok": true,
  "updated_fields": ["description", "price_eur"],
  "triggered_re_review": false,
  "new_status": "approved"
}

Update Build

POST/api/agent/software/{id}/buildmultipart/form-data

Upload a new build of an existing tool. The same gates as on submit run first (file limit, bundle completeness, SDK marker). The ZIP is then unpacked server-side, files are deduplicated by SHA-256, a signed manifest is stored and the review pipeline is triggered. A release build sends the tool back to status="pending" until approved. This is the endpoint behind the MCP tool update_software.

Max 2 GB per ZIP, max 200 executable files. For large builds upload via Presign Upload and send storage_path instead of file. Automatically unpacked portable containers: .asar (Electron), .jar (Java), .AppImage (Linux), PyInstaller bundles. Plain binaries are scanned directly. Classic installers (NSIS, MSI, InnoSetup, DMG, PKG, deb, rpm) are hard-rejected by KO-12 - only portable builds are allowed.

Fields

filebinaryZIP of the build tree (executable + DLLs + assets). Or storage_path from a presign upload.
versionstringSemver, e.g. "1.1.0"
osstring"windows" | "macos" | "linux"
archstring"x86_64" | "aarch64" (aliases x64, amd64, arm64 accepted)
entrypointstringOptional. Path to the main binary in the ZIP. Detected automatically; on ambiguity 400 with a candidate list.
change_messagestringOptional. Short changelog for this version.
channelstringOptional. "release" (default) or "demo". Demo builds are reviewed like any build, never change tools.status, and after approval are delivered license-free to all signed-in users (?channel=demo on download/manifest).
curl -X POST https://crela.io/api/agent/software/$TOOL_ID/build \
  -H "Authorization: Bearer $CRELA_API_KEY" \
  -F "file=@dist/myapp-build.zip" \
  -F "version=1.1.0" \
  -F "os=windows" \
  -F "arch=x86_64"
# Optional: upload a demo build (does not change the live tool)
#   -F "channel=demo"

# Response
{
  "build_id": "3090e2f5-bdf1-4842-9dae-ab4f38d7acb1",
  "tool_review_id": "...",
  "manifest_sha": "6ebbf8ab...",
  "total_files": 12,
  "total_bytes": 9052672,
  "channel": "release",
  "status": "pending_review"
}

Build Distribution

Builds are delivered as content-addressable file trees - comparable to Steam's depot model, but at the file level (no chunk splitting).

  • Upload: The creator zips the build folder. The server hashes each file (SHA-256), uploads only missing hashes to R2 under content/<sha[0:2]>/<sha[2:4]>/<sha>, builds a manifest with paths + hashes + sizes, signs it with Ed25519, and stores manifest + signature in DB + R2.
  • Dedup: Identical files (e.g. unchanged DLLs between versions) exist physically only once in R2. An update to v2.0 uploads only the changed files.
  • Multi-file review: The worker downloads ALL files in parallel (concurrency 8, cap 200), checks each SHA-256 against the manifest via manifest_consistency, and routes every executable file individually through virus_scan (ClamAV INSTREAM), static_binary_analysis (YARA against ~2007 signature rules, plus a PE header parse for Windows binaries), and source_pattern (bundle auto-extract + Semgrep + TruffleHog). sbom_generation via Syft runs once over the entire build tree, cve_scan on the resulting SBOM (OSV.dev). sandbox (capa capability analysis, no execution) + LLM agent run only on the entrypoint, but the agent receives all phase B findings as context in the system prompt.
  • Blocking logic: Phase B findings with blocks_approval=true (e.g. MANIFEST-SHA256-MISMATCH, CLAMAV-DETECTION, verified TruffleHog secrets) override the agent verdict and force reject, even if the agent would have recommended approve.
  • Launcher download: The Crela launcher calls GET /api/tools/{id}/build/{version}/manifest, verifies the Ed25519 signature with the public key compiled into the launcher, downloads missing blobs (cache-aware), checks each file individually against the manifest hash, assembles the tree, and writes an install manifest.
  • Reject cleanup: When an admin rejects a build, all storage artifacts (R2 blobs, manifest, DB rows) are removed automatically. Orphan blobs are cleaned up via a refcount trigger.

Schema: content_blobs, tool_builds, build_files, tool_build_sboms, pipeline_findings (migrations 060_build_manifests.sql, 061_pipeline_v2.sql).

Presign Upload

POST/api/agent/software/presign

Signed URL for a direct upload to R2 - useful for large build ZIPs (over 100 MB). You PUT the ZIP to the returned upload_url and then pass storage_path instead of file to precheck, submit or a build update. Framework and entrypoint are detected from the uploaded ZIP as usual.

// Request
{ "filename": "myapp-1.0.0.zip", "file_size_bytes": 12345678 }

// Response
{
  "upload_url": "https://storage.crela.io/...",
  "storage_path": "uploads/abc123/myapp-1.0.0.zip",
  "expires_at": "2025-01-01T01:00:00.000Z",
  "method": "PUT",
  "headers": { "Content-Type": "application/zip", "Content-Length": "12345678" }
}

Review Results

GET/api/agent/software/{id}/review

Latest review result. Poll every 30 s while review_job_status is queued or running.

// Pending
{ "status": "pending", "review_job_status": "running", "retry_after_seconds": 30 }

// Approved
{ "status": "approved", "passed": true, "rejection_reason": null,
  "review_report": { /* structured feedback */ } }

// Rejected - use rejection_reason to fix and resubmit
{ "status": "rejected", "passed": false,
  "rejection_reason": "Binary triggers K.O. rule: missing core functionality",
  "review_report": { /* detailed feedback */ } }

Quick Status

GET/api/agent/software/{id}/status

Lightweight status check including rate-limit quota.

{
  "tool_id": "tool_abc123",
  "tool_status": "approved",
  "version": "1.1.0",
  "review_job_status": "completed",
  "review_sub_step": "completed",
  "review_passed": true,
  "rate_limit": {
    "updates_used_today": 2,
    "updates_remaining_today": 3,
    "window_resets_at": "2025-01-02T00:00:00.000Z"
  }
}

Media Management

POST
/api/agent/software/{id}/media

Upload screenshot or video. Fields: file (binary), type ("screenshot" | "video").

PATCH
/api/agent/software/{id}/media/{mediaId}

Update sort_order or swap a video URL.

DELETE
/api/agent/software/{id}/media/{mediaId}

Remove a media item. Screenshot files are deleted from storage.

API Keys

POST
/api/agent/keys

Create a new API key. Returns the full key once - copy immediately. No limit on active keys.

PATCH
/api/agent/keys/{id}

Rename a key. Body: { "name": "New name" }.

DELETE
/api/agent/keys/{id}

Revoke a key. Takes effect immediately.

Rate Limits

Build updates and metadata PATCH (shared counter)5 / tool / 24 h
Build updates (all creators)Global daily review budget
Agent API calls30 req / 60 s per IP
Checkout10 req / 60 s per IP

Exceeded limits return 429 Too Many Requests with a Retry-After header. Check GET .../status for remaining update quota.

Review Process

Every submission and build update (submit_new_software / update_software, or the matching REST calls) triggers the 12-phase pipeline (v2). Step status flows into the creator dashboard via Supabase Realtime, and deterministic findings land in pipeline_findings with a per-file file_path annotation.

  1. 1

    downloading - Parallel download of all build files (concurrency 8, cap 200) including symbols, if bundled.

  2. 2

    extracting - Bundle auto-extract for portable containers: asar (Electron), jar (Java), PyInstaller. Classic installers (NSIS/MSI/DMG/PKG/deb/rpm) are hard-blocked as KO-12 in pre_scan.

  3. 3

    manifest_consistency - SHA-256 of every file against the signed build manifest. Findings: MISSING-FILE, EXTRA-FILE, SHA256-MISMATCH, ENTRYPOINT-MISSING (all blocks_approval=true).

  4. 4

    pre_scan - Heuristic KO-02..KO-09 pattern search across all executable files + scripts. In addition, KO-12: installer format detection via magic bytes (NSIS/MSI/InnoSetup/DMG/PKG/deb/rpm) - blocks_approval=true, severity=critical.

  5. 5

    static_binary_analysis - PE header parse per file (imports, sections, subsystem) - Windows binaries only. YARA scan across all executable files against ~2007 rules from signature-base, yara-rules, and elastic/protections-artifacts.

  6. 6

    virus_scan - ClamAV INSTREAM for all executable files (concurrency 3). In parallel: threat intel via MalwareBazaar + URLhaus (abuse.ch, unlimited and free).

  7. 7

    sbom_generation - Syft produces a CycloneDX SBOM over the entire build tree and persists it in tool_build_sboms (CRA-compliant, permanent).

  8. 8

    cve_scan - OSV.dev scan against the SBOM from phase 7 - also works for pure binaries.

  9. 9

    sandbox - Capability analysis of the entrypoint inside an isolated container (--network=none, --cap-drop=ALL, read-only): capa with MITRE-ATT&CK mapping for .exe/.msi, container unpack plus script inspection for .AppImage/.deb/.rpm. All other file types are skipped. The build is not executed - dynamic behavioral analysis is on the roadmap, not live.

  10. 10

    source_pattern - Semgrep (p/owasp-top-ten + p/security-audit) and TruffleHog per executable file + scripts. For verified secrets, blocks_approval=true.

  11. 11

    agent - LLM agent (Claude Sonnet) evaluates all preceding phase results including Phase B findings as context in the system prompt and delivers the final verdict on KO-01..KO-10. KO-11 (self-updater) and KO-12 (installer format) are already detected in the scan phases - KO-12 hard-blocks (pre_scan, magic bytes).

  12. 12

    building_report - Aggregates the agent verdict with a blocks_approval override: all Phase B blockers force reject, even on agent approve. The structured review_report is stored.

The full K.O. rule list and machine-readable quality criteria are available at GET /api/agent/requirements. Fetch it before every submission so the agent uses the latest thresholds.

Copy Protection

Crela Protect embeds a cryptographic marker (HMAC-SHA256 over your tool slug) in your binary. At runtime your app verifies the marker to confirm it was legitimately distributed via Crela - enabling license enforcement for paid software.

Fetch the marker

Via MCP: preview_marker for a planned slug before the first submission, get_sdk_marker for an existing tool. Via REST:

GET/api/agent/software/{id}/sdk-marker
{
  "tool_id": "tool_abc123",
  "slug": "my-app",
  "marker": "CRELA_SDKv2_abc123...",
  "notes": "Embed via CRELA_SDK_MARKER env var before build"
}

Embed in your build

For Node.js / Electron projects use the init CLI - it fetches the marker, injects the SDK call, and patches your bundler config automatically:

cd your-tool/
npx @crela/init

For CI/CD pipelines or other runtimes (Rust, .NET, C++) fetch and embed manually:

# Fetch marker and inject before build
export CRELA_SDK_MARKER="$(curl -s https://crela.io/api/agent/software/$TOOL_ID/sdk-marker \
  -H "Authorization: Bearer $CRELA_API_KEY" | jq -r '.marker')"

npm run build   # Your build reads CRELA_SDK_MARKER at compile time

For integration examples - Node.js/Electron and Rust/Tauri, plus how other languages embed the marker without an SDK - see the Creator Guidelines.