AgentStack
SKILL verified MIT Self-run

Atlassian Rest Ops

skill-bm629-agent-skills-atlassian-rest-ops · by bm629

>

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-bm629-agent-skills-atlassian-rest-ops

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Atlassian Rest Ops? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

atlassian-rest-ops

Overview

This skill lets an agent perform any Confluence Cloud (v2) or Jira Cloud (v3) operation by calling the REST API directly with curl — no SDK, no pip dependency. The REST API is the complete API surface, including writes such as creating a Confluence page. The agent consumes the credentials the caller injected, looks up an endpoint in a bundled OpenAPI spec via an endpoint index + a $ref-resolver, constructs the curl, and parses the JSON. Confluence and Jira differ on several axes (base URL, pagination, errors, rich-text), so this skill carries per-API patterns rather than one generic shape.

When to activate

  • ✅ Performing a Confluence Cloud v2 operation (create/get/update/search pages, spaces, attachments, …).
  • ✅ Performing a Jira Cloud v3 operation (create/search/transition issues, comments, …).
  • ✅ A write or operation you need done programmatically against the Atlassian REST API (e.g. creating a Confluence page).

Do NOT activate when:

  • The target is Atlassian Server / Data Center (this skill is Cloud + API-token only).
  • You only need credential setup — credentials are provided by the caller; this skill does not provision or resolve them (see references/credentials.md for the contract it consumes).

Workflow

Step 1 — Receive the injected credentials

The caller has already resolved the account and injected what this operation needs — consume it; do not look for a record yourself. You receive from context:

  • base_url and email (and the capability the account acts under) — as context values, not read from a file.
  • The token, by an ordered load rule the context carries the variable NAME for. Resolve that name as: the project-level .env value if that file exists and defines the var, else the environment variable of that name — project .env is tried first (that is how a project .env overrides a global env var). The token value is never in the context prose — only its variable name; curl reads the value from the environment. The project root is supplied by the context; perform no scope resolution or directory walk to find the .env, and it is project .env, not .envrc.

Then bridge these into the example scripts' fixed vars ATLASSIAN_EMAIL / ATLASSIAN_BASE_URL / ATLASSIAN_API_TOKEN (same bridge as before; only the inputs now come from context). Full contract + the bridge: [references/credentials.md](references/credentials.md).

Step 2 — Find the endpoint

Scan [assets/endpoint-index.md](assets/) (one line per operation: METHOD path — summary (operationId)) for the operation you need. Never load a full spec into context — they are multi-MB.

Step 3 — Resolve the call shape

Run the resolver: python3 scripts/endpoint.py . It dereferences that one operation from the bundled OpenAPI spec ($ref-resolved) and prints the method, path, params, request/response schema, and a curl skeleton. (scripts/endpoint.py + its validation are added during augmentation; see Progressive disclosure.)

Step 4 — Construct + run the curl

Apply the per-API patterns from [references/patterns.md](references/patterns.md):

  • Auth (both): curl -u "$email:$" (HTTP Basic).
  • Base URL: Confluence → /wiki/api/v2/; Jira → / (paths already include /rest/api/3/…).
  • Rich-text bodies (the easy-to-get-wrong part) — see [references/rich-text.md](references/rich-text.md): Jira uses ADF as a raw JSON object; Confluence uses {representation, value} where atlas_doc_format means the ADF JSON stringified and storage means an XHTML string. If your source is Markdown (e.g. a formatted comment), convert it to ADF with python3 scripts/md_to_adf.py in a curl -u argument; the subprocess reads it from the environment. The token lives only in .env (gitignored).
  • Resolve before constructing. Build a request body/params from the $ref-resolved schema (Step 3) or the verified rich-text formats — never from a guessed/remembered field set.
  • Per-API, not generic. Apply Confluence vs Jira patterns correctly (base URL, pagination, rich-text, errors) — they differ.
  • Rich-text: Jira ADF = raw object; Confluence atlas_doc_format = stringified ADF in value. Do not mix them.
  • This skill never writes credentials. Credentials are provided by the caller; this skill never provisions or resolves them.

Preferences (override-able):

  • Prefer the newer Jira issue search GET /rest/api/3/search/jql (nextPageToken) over the legacy /search (startAt).
  • Request only needed fields (fields= on Jira, body-format= on Confluence) to keep responses small.

Gotchas

  • Rich-text mismatch. Sending a raw ADF object to Confluence atlas_doc_format (instead of a stringified one), or a stringified blob to Jira (instead of a raw object), is the most common failure. Confluence value is always a string.
  • Base-URL difference. Confluence paths are relative to …/wiki/api/v2; Jira paths already include /rest/api/3. Don't double-prefix or drop /wiki.
  • $ref chains. The request body is rarely inline in the spec — it $refs a schema (which may $ref further). Use the resolver (Step 3); a raw grep of the spec won't give you the full shape.
  • Legacy vs new Jira search. GET /rest/api/3/search is being deprecated for GET /rest/api/3/search/jql; pagination differs (startAt vs nextPageToken).
  • Rate limits. Jira returns HTTP 429 with a Retry-After; honor it. Confluence may return 413 on oversized bodies.
  • Confluence delete is two-stage (verified live, applies to pages, blogposts, and other content). DELETE /pages/{id} (or /blogposts/{id}) only trashes it (returns 204, but GET still returns it with status: trashed). To remove permanently, call DELETE //{id}?purge=true — which only works once trashed (purge-without-trash is a no-op). A plain delete is not full removal.
  • Jira /search/jql rejects unbounded JQL (verified live). Ordering-only or empty JQL → 400 ErrorCollection ("Unbounded JQL queries are not allowed here"). Always include a search restriction (e.g. project = X, created >= -30d).

Anti-patterns

  • Guessing the body. Don't hand-write a request body from memory of "what Jira issues look like" — resolve the schema; field requirements change per project/screen.
  • Echoing the token. Never echo $TOKEN, never paste it into a command you print, never write its value into any file. Reference the env var inside curl only.
  • Loading the whole spec. Don't cat/read the multi-MB OpenAPI JSON into context — scan the index, resolve one op.
  • One-size-fits-all. Don't apply Jira's pagination/errors/ADF to Confluence or vice-versa.
  • SDK creep. Don't reach for atlassian-python-api / pip installcurl + the resolver cover every endpoint.

Output

This skill produces API side effects (the requested Confluence/Jira operation) and returns the parsed JSON response to the calling agent. It writes no files of its own (it only consumes the caller-injected credentials). For write operations it reports the created/updated resource (id, key, URL); for reads it returns the result set, following pagination as needed. The abstract consumer is the calling agent (or a sub-agent) that needs the operation performed; secrets never enter that output.

Related

  • [references/credentials.md](references/credentials.md) — the credential contract this skill consumes (caller-injected fields + the ordered token-load rule + the bridge into the fixed vars).
  • The REST-direct + bundled-OpenAPI-spec pattern generalizes to other API providers.

Progressive disclosure

Heavy content lives in subfolders, loaded only on demand:

  • [references/patterns.md](references/patterns.md) — per-API patterns: auth, base URL, pagination (Confluence cursor vs Jira offset/token), response envelopes, errors, rate limits, expand. Load in Steps 4–5.
  • [references/rich-text.md](references/rich-text.md) — ADF (Jira, raw object) and Confluence body representations (storage / atlas_doc_format, value-as-string) with worked examples + the cross-API gotcha. Load when building a request body.
  • [references/credentials.md](references/credentials.md) — the credential contract this skill consumes: caller-injected fields, the ordered token-load rule, the bridge into the fixed vars, honest-secret handling. Load in Step 1.
  • [references/sources.md](references/sources.md) — provenance (Atlassian official docs + the bundled spec versions).

Added during augmentation (Phase 2.C), referenced above:

  • assets/confluence-v2.json, assets/jira-v3.json — the bundled OpenAPI specs (authoritative; queried, never loaded wholesale).
  • assets/endpoint-index.md — one line per operation, for discovery (Step 2).
  • scripts/endpoint.py + scripts/endpoint.py.validation.md — the python3 $ref-resolver (Step 3).
  • scripts/.sh + .validation.md — the four validated example curls (create Confluence page, Confluence list, Jira create issue, Jira search).
  • scripts/md_to_adf.py + .validation.md — a stdlib Markdown -> ADF converter. Pipe a Markdown comment/description through it to post it as native ADF (headings, bold, code, links, lists, GFM tables render instead of showing raw ##/|): python3 scripts/md_to_adf.py the ADF object for the Jira {"body": ...}`.

Standalone usage (optional, not required)

This is a convenience for a human running the skill by hand outside agent-flow — it is not a dependency of the skill. The skill's normative contract is caller-injection (Step 1); this appendix is only the manual-operator bridge.

To run by hand, populate the three fixed vars yourself from a .service-accounts.yaml record + its .env token, then run the scripts. An example record:

accounts:
  - name: atlassian-work
    provider: atlassian
    base_url: https://workco.atlassian.net
    email: me@workco.com
    token_env: ATLASSIAN_WORK_API_TOKEN     # the var holding the token value; value lives in .env (gitignored)
set -a; source .env; set +a                 # loads $ATLASSIAN_WORK_API_TOKEN, never prints it
export ATLASSIAN_EMAIL="me@workco.com"
export ATLASSIAN_BASE_URL="https://workco.atlassian.net"
export ATLASSIAN_API_TOKEN="$ATLASSIAN_WORK_API_TOKEN"
bash scripts/create-confluence-page.sh  ""

Get an API token at id.atlassian.com → Security → "Create API token". The value is referenced by name only, never printed.

Body budget

  • description ≤ 1,024 chars (agentskills.io cap).
  • Body ≤ ~500 lines / 5,000 tokens — kept in context every turn; per-API detail lives in references/.
  • assets/*.json are large (queried on disk, never loaded into context).

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.