Quickstart
From zero to a running job in five minutes, end-to-end.
This walks you (or the AI agent driving your editor) from a fresh checkout to a job that returns a result.
0. Prerequisites
- A Puras project. Create one in the dashboard, then create an API key — it's shown once in the format
puras_live_<prefix8>.<secret32>. The dot between prefix and secret is load-bearing; never strip it. - The MCP server installed and registered:
bash
cd mcp && pip install -e . claude mcp add purasbackend purasbackend-mcp
1. Configure the MCP
In Claude Code, call configure once. The credentials are written to ~/.purasbackend/config.json (chmod 600).
configure(
api_base="https://puras-api.fly.dev",
api_key="puras_live_AbCdEfGh.SecretSecretSecretSecretSecre32",
project_id="<your-project-uuid>",
)
2. Lay out a project
A project is a directory with a skills/ folder. Every immediate child of skills/ that contains a skill.yaml is auto-discovered as a skill — there is no root manifest.
my-project/
skills/
hello/
skill.yaml
SKILL.md # system prompt — agentic entrypoint
echo/
skill.yaml
main.py # deterministic entrypoint
skills/hello/skill.yaml (agentic — entrypoint is a .md file):
description: Answer the user's question briefly.
entrypoint: SKILL.md
input_schema:
type: object
properties:
prompt: { type: string }
required: [prompt]
output_schema:
type: object
properties:
answer: { type: string }
required: [answer]
skills/hello/SKILL.md:
You are a helpful assistant. Answer the user's question briefly.
When you are done, call the `set_output` tool with `{ "answer": "<your reply>" }`.
skills/echo/skill.yaml (deterministic — entrypoint is <file>.py:<func>):
description: Echo the input back unchanged.
entrypoint: main.py:run
input_schema:
type: object
properties:
text: { type: string }
required: [text]
output_schema:
type: object
properties:
echoed: { type: string }
required: [echoed]
skills/echo/main.py:
def run(inputs: dict) -> dict:
return {"echoed": inputs["text"]}
Skill names must match ^[a-z0-9][a-z0-9_-]*$. The directory name is the skill name — skills/hello/ registers a skill called hello.
3. Push the bundle
From Claude Code:
push(project_dir="/abs/path/to/my-project", notes="first cut", activate=true)
This zips the directory (excluding .git, .venv, node_modules, …), uploads it as a new deployment, and makes it the active one. In-flight jobs keep running on the previous deployment.
4. Submit a job
One endpoint, one body shape, regardless of whether the skill is agentic or deterministic:
# async — fire-and-forget, returns {id, status:"queued"} immediately
curl -X POST $API/v1/jobs -H "Authorization: Bearer $KEY" \
-d '{"skill":"hello","inputs":{"prompt":"hi"}}'
# sync — block until done (or up to `timeout` seconds)
curl -X POST "$API/v1/jobs?wait=true&timeout=30" -H "Authorization: Bearer $KEY" \
-d '{"skill":"echo","inputs":{"text":"hi"}}'
# stream — SSE of every tool call / model response as the worker emits it
curl -N -X POST "$API/v1/jobs?stream=true" -H "Authorization: Bearer $KEY" \
-d '{"skill":"hello","inputs":{"prompt":"hi"}}'
The worker reads the skill's skill.yaml and dispatches to the agent loop (.md entrypoint) or the deterministic runner (.py:func entrypoint) automatically.
From the MCP convenience wrappers:
submit_job(skill="echo", inputs={"text": "hi"}, wait=true, timeout=10)
submit_job(skill="hello", inputs={"prompt": "What is Puras?"})
5. Observe
list_jobs(limit=10)
get_job(job_id="...")
tail_job(job_id="...", max_seconds=60) # streams events until terminal
Status transitions: queued → running → succeeded | failed | cancelled.
What you've got now
- A project with one agentic skill and one deterministic skill.
- A live deployment you can roll back via
list_deployments+activate_deployment. - Jobs you can submit from any HTTP client with the same API key (the MCP is a convenience, not a requirement).
Next: example-project for a complete starter you can copy as the shape of a real project, inputs-and-drive for passing files into jobs, concepts for the deeper model, sdk-media for image/video/TTS inside skills, mcp-tools for the full tool list.