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:
Recommended
MCP server
@crela/mcp gives your agent ready-made tools for the whole lifecycle: requirements, precheck, submit, new versions, review reports, metadata and media.
For CI/CD and scripts
REST API
The HTTP endpoints the MCP server is built on. Use them directly from a build pipeline or your own tooling.
Both use the same API key and run through the same review pipeline. Nothing goes live without passing the review.
MCP Setup
Create an API key
In your creator dashboard. The full key is shown once; it starts with crela_.
Add the server to your agent
One click for the common clients:
- Claude Desktop: open
crela.mcpbor 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_KEYunder Cursor Settings → MCP; search works without it.
Claude Code, one command:
claude mcp add crela --env CRELA_API_KEY=crela_... -- npx -y @crela/mcpCursor (~/.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_..." }
}
}
}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.
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
get_submission_requirements- Learn the rules, required fields and K.O. criteria. - 2
precheck_build- Dry-run the submit gate and fix missing files or the marker before spending a review cycle. - 3
submit_new_software- Metadata plus the build. Pass the storage_path from the precheck so the ZIP travels only once. - 4
upload_screenshot- At least 3 images; the review scores the presentation on them. - 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/mcpIn 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.
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_.
CRELA_API_KEY.Quickstart
Submit your first tool in 5 steps:
Create an API key
Dashboard → API Keys → Create key. Copy it immediately - it's shown only once.
Read platform requirements
curl https://crela.io/api/agent/requirementsSubmit 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+"Save the tool ID
# Response: { "id": "tool_abc123", "slug": "my-app", "status": "pending_review" }
TOOL_ID="tool_abc123"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
/api/agent/requirementsNo auth requiredMachine-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
Your framework is not on the list? Contact support - we will review adding it. No automatic reject.
List Software
/api/agent/softwareAll 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
/api/agent/software/precheckmultipart/form-dataDry 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
/api/agent/softwaremultipart/form-dataSubmit 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 nameslugstringURL-friendly unique identifierdescriptionstringShort description shown in listingslong_descriptionstringFull description, Markdown supportedcategoriesJSON array"tool" | "game" | "finance" | "productivity" | "creative" | "other"price_eurnumber0 for free, or ≥ 0.99versionstringSemver, 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 tagstool_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 itsupport_contactstringSupport email or URLscreenshot_0-4binaryUp to 5 screenshot filescoverbinaryCover 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 linkResponse 201 Created
{
"id": "tool_abc123",
"slug": "my-app",
"title": "My App",
"created_at": "2025-01-01T00:00:00.000Z",
"status": "pending_review"
}Get Software
/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 }
]
}/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
/api/agent/software/{id}application/jsonPartial 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
/api/agent/software/{id}/buildmultipart/form-dataUpload 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 throughvirus_scan(ClamAV INSTREAM),static_binary_analysis(YARA against ~2007 signature rules, plus a PE header parse for Windows binaries), andsource_pattern(bundle auto-extract + Semgrep + TruffleHog).sbom_generationvia Syft runs once over the entire build tree,cve_scanon 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 forcereject, even if the agent would have recommendedapprove. - 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
/api/agent/software/presignSigned 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
/api/agent/software/{id}/reviewLatest 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
/api/agent/software/{id}/statusLightweight 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
/api/agent/software/{id}/mediaUpload screenshot or video. Fields: file (binary), type ("screenshot" | "video").
/api/agent/software/{id}/media/{mediaId}Update sort_order or swap a video URL.
/api/agent/software/{id}/media/{mediaId}Remove a media item. Screenshot files are deleted from storage.
API Keys
/api/agent/keysCreate a new API key. Returns the full key once - copy immediately. No limit on active keys.
/api/agent/keys/{id}Rename a key. Body: { "name": "New name" }.
/api/agent/keys/{id}Revoke a key. Takes effect immediately.
Rate Limits
5 / tool / 24 hGlobal daily review budget30 req / 60 s per IP10 req / 60 s per IPExceeded 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
downloading- Parallel download of all build files (concurrency 8, cap 200) including symbols, if bundled. - 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
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
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
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
virus_scan- ClamAV INSTREAM for all executable files (concurrency 3). In parallel: threat intel via MalwareBazaar + URLhaus (abuse.ch, unlimited and free). - 7
sbom_generation- Syft produces a CycloneDX SBOM over the entire build tree and persists it in tool_build_sboms (CRA-compliant, permanent). - 8
cve_scan- OSV.dev scan against the SBOM from phase 7 - also works for pure binaries. - 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
source_pattern- Semgrep (p/owasp-top-ten + p/security-audit) and TruffleHog per executable file + scripts. For verified secrets, blocks_approval=true. - 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
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.
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:
/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/initFor 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 timeFor integration examples - Node.js/Electron and Rust/Tauri, plus how other languages embed the marker without an SDK - see the Creator Guidelines.
