puras

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):

yaml
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:

markdown
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>):

yaml
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:

python
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:

bash
# 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.