Trial Assets
Access Keys
REST API Reference
All endpoints except /api/setup/* require an API key on every request.
Authentication
Pass your API key in either of these request headers:
Authorization: Bearer <key> X-API-Key: <key>
API keys are stored as files in the configured access-keys folder of the GitHub repository. The file's trimmed contents are the key value. A missing or invalid key returns 401 or 403.
Setup
/api/setup/status
No auth required
Returns whether the application has been configured.
Response 200
{ "configured": true }
/api/setup
No auth required — one-time only
Writes the application configuration. Returns 409 if already configured.
Request body
{
"repoUrl": "https://github.com/owner/repo",
"pat": "ghp_…",
"trialAssetsPath": "trial-assets",
"accessKeysPath": "access-keys"
}
Response 201
{ "message": "Setup complete." }
Trial Assets
/api/trial-assets
Lists all files recursively under the configured trial-assets folder.
Response 200
{
"files": [
{ "path": "docs/guide.md", "size": 2048 },
{ "path": "firmware/device.bin","size": 524288 }
]
}
/api/trial-assets/download?path=<relative-path>
Downloads a file. Text files are served inline with their appropriate Content-Type; binary files are served as application/octet-stream with Content-Disposition: attachment.
Text extensions (served inline)
.json .jwt .text .md .csv .log .html .css .js .xml .py .svg .ts .sh .bash
Query parameters
| Parameter | Description |
|---|---|
path | Path relative to the trial-assets root, e.g. docs/guide.md |
/api/trial-assets?path=<relative-path>
Permanently deletes a file from the repository. The current blob SHA is fetched server-side immediately before deletion.
Query parameters
| Parameter | Description |
|---|---|
path | Path relative to the trial-assets root |
Response 200
{ "message": "Deleted: docs/guide.md" }
Access Keys
/api/access-keys
Lists all files in the flat access-keys folder (no subdirectories).
Response 200
{
"files": [
{ "name": "customer-acme.key", "size": 36 },
{ "name": "internal-dev.key", "size": 36 }
]
}
/api/access-keys/download?path=<filename>
Downloads the contents of an access key file as text/plain.
Query parameters
| Parameter | Description |
|---|---|
path | Plain filename, no path separators, e.g. customer-acme.key |
/api/access-keys
Creates a new access key file in the repository. Returns 409 if a file with that name already exists. The new key is usable immediately (auth cache is invalidated on success).
Request body
{
"filename": "customer-acme.key",
"value": "550e8400-e29b-41d4-a716-446655440000"
}
Response 201
{ "message": "Access key 'customer-acme.key' created successfully." }
Actions
/api/actions/generate-trial
Triggers the generate-trial-jwt GitHub Actions workflow via a repository_dispatch event, then polls for a new commit on the default branch to detect completion. Responds once a commit appears or after the 90-second timeout.
Request body
{
"customerName": "Acme-Corporation",
"trialPeriod": "1 month"
}
Allowed trialPeriod values
| UI value | Sent to action as |
|---|---|
| 1 week | 7 days |
| 1 month | 1 month |
| 3 months | 3 months |
| 6 months | 6 months |
| 1 year | 1 year |
Notes
The customerName field has any spaces replaced with - and all .jwt occurrences stripped before dispatch — the action is responsible for appending the .jwt extension to the generated file.
Response 200
{ "message": "Trial JWT generated successfully.", "conclusion": "success" }
Error responses
| Status | Meaning |
|---|---|
400 | Missing or invalid customerName / trialPeriod |
502 | GitHub rejected the dispatch or the workflow failed |
504 | No commit detected within 90 seconds |
MCP (Model Context Protocol)
CNE Trialer ships an MCP server so AI assistants can manage trial assets and access keys directly. Two transports are available.
node src/mcp/bin/stdio.js
No API key — process isolation
Primary transport for Claude Desktop and Claude Code. The process communicates over stdin/stdout. Add to your Claude config file:
{
"mcpServers": {
"cne-trialer": {
"command": "node",
"args": ["/absolute/path/to/cnetrialer/src/mcp/bin/stdio.js"]
}
}
}
/mcp
HTTP/SSE transport mounted on the running Express server. Protected by the same API key authentication as the REST API.
{
"mcpServers": {
"cne-trialer": {
"url": "http://localhost:3000/mcp",
"headers": { "Authorization": "Bearer <your-api-key>" }
}
}
}
Available tools
| Tool | Description |
|---|---|
check_setup_status | Returns whether the app has been configured |
list_trial_assets | Lists all trial asset files with path and size |
download_trial_asset | Downloads a trial asset; text inline, binary as base64 or URL |
delete_trial_asset | Permanently deletes a trial asset from the repository |
list_access_keys | Lists all access key filenames and sizes |
download_access_key | Downloads the value of an access key file |
create_access_key | Creates a new access key file in the repository |
generate_trial | Triggers the GitHub Action to generate a trial JWT |
Available prompts
| Prompt | Description |
|---|---|
generate_trial_guided | Guided flow — asks for missing inputs, confirms, then calls generate_trial |
audit_access_keys | Lists all keys in a table and offers to add a new one or view an existing value |
Resources
| URI template | Description |
|---|---|
cne://trial-assets/{path} | Read a trial asset by its relative path |
cne://access-keys/{filename} | Read an access key file by its plain filename |
Environment Variable Configuration
When CNE_REPO_URL and CNE_PAT are both present at startup, config.json is written from these values and the setup screen is bypassed. Setting only one of the two is an error that aborts startup.
| Variable | Required | Default | Description |
|---|---|---|---|
CNE_REPO_URL | With PAT | — | GitHub repo URL, e.g. https://github.com/owner/repo |
CNE_PAT | With URL | — | GitHub Personal Access Token |
CNE_TRIAL_ASSETS_PATH | No | trial-assets | Folder path within the repo for trial assets |
CNE_ACCESS_KEYS_PATH | No | access-keys | Folder path within the repo for access keys |
PORT | No | 3000 | Port the server listens on |
Docker Compose example
environment: - CNE_REPO_URL=https://github.com/owner/repo - CNE_PAT=ghp_… - CNE_TRIAL_ASSETS_PATH=trial-assets - CNE_ACCESS_KEYS_PATH=access-keys
Error Format
All error responses use the same JSON envelope:
{ "error": "Human-readable description." }
| Status | Meaning |
|---|---|
400 | Bad request — invalid parameters or payload |
401 | No API key provided |
403 | API key invalid |
404 | File or resource not found |
409 | Conflict — resource already exists |
413 | File exceeds GitHub API 100 MB limit |
502 | GitHub API error |
503 | Application not yet configured |
504 | Workflow completion timeout |