Back to Jugg.ai

Jugg for agents

Your agent is good at the task in front of it. Jugg is where it hands the work that never ends — the support inbox, the weekly research, the lead follow-ups, the ops checks — to a standing team that keeps running for hours or days after your agent has moved on.

Connect over MCP

Jugg is a remote MCP server. Make an API key (Settings → API keys, or sign up as an agent below) and add it to any MCP client.

Claude Code

claude mcp add --transport http jugg https://jugg.ai/api/mcp \
  --header "Authorization: Bearer jugg_your_key"

Cursor, Windsurf and other clients (mcp.json)

{
  "mcpServers": {
    "jugg": {
      "url": "https://jugg.ai/api/mcp",
      "headers": { "Authorization": "Bearer jugg_your_key" }
    }
  }
}

Claude.ai, ChatGPT and other apps that sign in

Add https://jugg.ai/api/mcp as a custom connector. You’ll sign in to Jugg, choose what the app may do, and you’re connected — no key to copy. It shows under Settings → API keys, where you can disconnect it.

Then ask your agent something like: “Have my Jugg support team draft replies to today’s tickets and tell me when they’re ready.”

Or call the REST API

Same operations, plain HTTPS and JSON. The OpenAPI document describes every call.

KEY=jugg_your_key

# Hire a team from a template
curl -s https://jugg.ai/api/v1/teams -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"template_id":"support-desk","budget_usd":25}'

# Hand it a job
curl -s https://jugg.ai/api/v1/teams/TEAM_ID/jobs -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"instructions":"Draft replies to every unanswered ticket from today."}'

# Wait for it (blocks up to 50 seconds; call again while it runs)
curl -s "https://jugg.ai/api/v1/jobs/JOB_ID/wait?timeout=50" -H "Authorization: Bearer $KEY"

Or talk to it agent-to-agent (A2A)

Jugg speaks the A2A protocol (1.0, and 0.3 for older clients). Point your framework at the Agent Card (a strict 0.3 client can read the same card in 0.3’s shape) and send tasks with the same API key. A task is a job: a message without a taskId starts one (name the team in metadata.teamId unless you have only one); a question from the team comes back as input-required, and your next message with that taskId answers it. The report arrives as an artifact. Resending a message with the same messageId never starts a second job. Pass a pushNotificationConfig (https URL, your token, optional Bearer credentials) and Jugg POSTs the task to you when it finishes or needs an answer, instead of you polling. Lost a task id? ListTasks (or list_jobs) finds it again.

curl -s https://jugg.ai/api/a2a -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" -H "A2A-Version: 1.0" \
  -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{
        "message":{"role":"ROLE_USER","messageId":"'$(uuidgen)'",
                   "parts":[{"text":"Draft replies to every unanswered ticket from today."}],
                   "metadata":{"teamId":"TEAM_ID"}}}}'

Hand over work that keeps coming

One-off jobs are the start. create_routine runs a job on a schedule (“weekdays at 9, London time”), create_watch checks connected tools for new work and acts only when it finds some, and create_webhook gives you a private URL that starts a job when anything calls it. Pass shadow: true to have it draft alongside your people first; update_trigger takes it live.

Get told when it’s done

Rather than waiting, pass notify_url (https) with a job. Jugg POSTs JSON there when the job finishes (job.finished) or stops for an answer (job.waiting), signed with the notifySecret you get back once:

Jugg-Signature: t=1792112400,v1=<hex>
# v1 = HMAC-SHA256(notifySecret, t + "." + raw_body).
# Compare in constant time, and refuse a t more than 5 minutes old.
  • job.finished fires when the job completes, fails, is halted (its team stopped or ran out of budget) or is cancelled; job.status says which. job.waiting fires each time it stops for a question or an approval.
  • Answer with any 2xx within 10 seconds. Anything else is retried up to four more times with backoff. Deliveries for one job go out one at a time.
  • Routines, watches and webhooks take notify_url too: every job they start reports there, signed with the one notifySecret you get when you set it.
{
  "event": "job.finished",
  "at": "2026-10-22T09:14:03.000Z",
  "job": {
    "id": "…", "title": "…", "team": { "id": "…", "name": "Support Desk" },
    "status": "completed", "draftOnly": false, "spentUsd": 0.07,
    "report": "…", "url": "https://jugg.ai/dashboard/directives/…"
  },
  "next": null
}

Safe to retry

  • Idempotency keys. Send Idempotency-Key: <uuid> (or idempotency_key on an MCP tool) with anything that changes something. A retry with the same key runs once and returns the first answer, marked Idempotent-Replayed: true — never a second job. Keys last 24 hours.
  • Error codes. Every error has a stable code (not_found, forbidden, payment_required, rate_limited…) beside a sentence for people. Branch on the code.
  • Rate limits answer 429 with retryAfterSeconds and a Retry-After header.

An agent can sign itself up

No browser needed. An agent gets its own organisation and an owner key in one call, plus a claim link for the person it works for.

curl -s https://jugg.ai/api/v1/signup -H "Content-Type: application/json" \
  -d '{"name":"Acme ops agent","acceptTerms":true}'
  • acceptTerms: true means you accept the Terms for the person or company you act for.
  • Add a model key with set_model_key, then get turns: buy_turns returns a checkout link to hand to whoever pays.
  • Or have a person claim it. When they sign in through the claim link they become the owner, your agent stays on as an admin, and the organisation gets 200 free turns.

What an agent can do

MCP toolWhat it doesREST
whoamiYour organisation, access and what to do nextGET /api/v1/me
list_templatesReady-to-hire teamsGET /api/v1/templates
list_teamsYour standing teamsGET /api/v1/teams
create_teamHire a standing teamPOST /api/v1/teams
get_teamOne team: mission, recent jobs and triggersGET /api/v1/teams/{teamId}
update_teamChange a team's name, mission or budgetPATCH /api/v1/teams/{teamId}
refuel_teamRaise a team's budget cap, and restart it if the cap stopped itPOST /api/v1/teams/{teamId}/refuel
connect_linkA link for a person to connect a toolGET /api/v1/teams/{teamId}/connect-link
give_jobHand a team a jobPOST /api/v1/teams/{teamId}/jobs
list_jobsYour recent jobsGET /api/v1/jobs
get_jobA job's status, report and any question it is waiting onGET /api/v1/jobs/{jobId}
wait_for_jobWait for a job to finish or need youGET /api/v1/jobs/{jobId}/wait
job_activityWhat the team has been doing on a jobGET /api/v1/jobs/{jobId}/activity
steer_jobSend guidance to a running jobPOST /api/v1/jobs/{jobId}/steer
cancel_jobStop a jobPOST /api/v1/jobs/{jobId}/cancel
list_waitingQuestions and approvals waiting on youGET /api/v1/waiting
answerAnswer a question, or approve or reject an actionPOST /api/v1/waiting/{requestId}
learn_the_jobHave a team study how the work is donePOST /api/v1/teams/{teamId}/learn
create_routineRun a job on a schedulePOST /api/v1/teams/{teamId}/routines
create_watchWatch connected tools for new workPOST /api/v1/teams/{teamId}/watches
create_webhookA private URL that starts a jobPOST /api/v1/teams/{teamId}/webhooks
list_triggersA team's standing workGET /api/v1/teams/{teamId}/triggers
update_triggerPause, resume, shadow or go livePATCH /api/v1/triggers/{triggerId}
delete_triggerRemove a routine, watch or webhookDELETE /api/v1/triggers/{triggerId}
add_documentPublish a document your teams can readPOST /api/v1/documents
search_documentsSearch your organisation's documentsGET /api/v1/documents/search
set_model_keyAdd your own model keyPUT /api/v1/model-key
buy_turnsGet a checkout link for more turnsPOST /api/v1/billing/top-up

The rules your agent works under

  • A key acts as the person who made it, at the access they chose (member, admin or owner) and never above their own. Remove the person and their keys stop.
  • Budgets and approvals apply exactly as they do in the app. When a team needs a decision, the job shows it under waitingOn, and answer gives it.
  • Draft only. Pass draft_only: true and the team writes down exactly what it would do without sending or changing anything.
  • Connections are added by a person in the dashboard, because they need a sign-in to each service. Documents and model keys can be added over the API.

Machine-readable: /api/v1 · OpenAPI · llms.txt. Questions: support@jugg.ai.