Connects Jira to AI agents for seamless issue tracking management.

Install

mkdir -p .claude/skills/integration-jira && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16251" && unzip -o skill.zip -d .claude/skills/integration-jira && rm skill.zip

Installs to .claude/skills/integration-jira

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Connect Jira (Atlassian Cloud) to a self-hosted Hermes Agent over SSH so the agent can search, create, and update issues. Wires Atlassian's official remote MCP server (Rovo) with a static API token. Idempotent and rollback-safe. Works from Claude Code, Codex, Cursor, Hermes itself, and Gemini CLI.
298 charsno explicit “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Connect Jira (Atlassian Cloud) to a self-hosted Hermes Agent over SSH
  • Register the Hermes Agent with Atlassian's remote MCP server (Rovo)
  • Store Atlassian API tokens securely on the VPS
  • Reload the Hermes gateway for configuration changes
  • Verify Jira integration through logs and smoke tests

How it works

The skill connects Jira to a Hermes agent on a VPS via SSH by securely storing the API token, registering the agent with Atlassian's MCP server, and reloading the gateway. It includes idempotency checks and dry runs.

Inputs & outputs

You give it
VPS IP/hostname, SSH user, Atlassian email, Jira API token, confirmation of org-admin toggle for Rovo MCP
You get back
Jira (Atlassian Cloud) connected to Hermes Agent, verified MCP registration

When to use integration-jira

  • Creating Jira tickets
  • Searching issue backlogs
  • Updating ticket statuses

About this skill

/integration-jira — connect Jira to a remote Hermes (SSH-first)

You are the engineer connecting Jira (Atlassian Cloud) to a self-hosted Hermes agent on the user's VPS. You (the AI agent — Hermes, Claude Code, Codex, Cursor, Gemini, any of them) work over SSH as root against the VPS. The user only does the things a machine cannot: minting the Atlassian API token, and (one time, org-wide) flipping the admin-console toggle that enables API-token auth for the Rovo MCP Server.

Everything else — token storage, MCP registration, gateway reload, verification — runs on the VPS via SSH, idempotently.

Honest auth picture (verified 2026-06): Atlassian ships a hosted remote MCP at https://mcp.atlassian.com/v1/mcp. It accepts two header shapes for headless use:

CredentialHeaderAccess
Personal API token (recommended)Authorization: Basic <base64(email:token)>Full — read and write (create/update issues)
Service-account API keyAuthorization: Bearer <api_key>Read-only tools

Default to Basic unless the user explicitly wants read-only. A common silent failure is sending a personal token as Bearer — it authenticates but exposes only read tools, so writes appear "missing." This is Atlassian Cloud only; Jira Data Center / Server is not served by the remote MCP endpoint (see Pitfalls). The legacy SSE transport https://mcp.atlassian.com/v1/sse is deprecated after 2026-06-30 — use /v1/mcp.


Before you start — gather (ask once, in one batch)

VariableWhatWhere to get it
$VPS_IPIP/hostname of the VPS running HermesUser's hosting dashboard
$VPS_USERSSH user (typically root)User's hosting dashboard
$ATLASSIAN_EMAILEmail of the Atlassian account the agent acts asThe user's Atlassian account
$JIRA_TOKENAtlassian API token (opaque string)https://id.atlassian.com/manage-profile/security/api-tokens → Create API token
Org-admin toggleAPI-token auth enabled for Rovo MCPAtlassian Administration → Settings → Rovo MCP Server

The MCP server runs within that user's Jira permissions — pick the right account.

Confirm SSH access before doing anything:

ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes \
    "$VPS_USER@$VPS_IP" "echo ok" 2>&1 | grep -q '^ok$' \
  || { echo "ABORT: SSH to $VPS_USER@$VPS_IP failed. Run /setup-ssh-keys first."; exit 1; }

Step 1 — verify Hermes is reachable on the VPS

ssh "$VPS_USER@$VPS_IP" '
  set -e
  if command -v hermes >/dev/null 2>&1; then
    hermes --version
  elif docker ps --format "{{.Names}}" | grep -q hermes; then
    AGENT=$(docker ps --filter name=hermes --format "{{.Names}}" | head -1)
    docker exec "$AGENT" hermes --version
  else
    echo "FAIL: hermes not found on host or in container"; exit 1
  fi
' || { echo "ABORT: Hermes is not installed/running. Run /hermes-install first."; exit 1; }

Expected: 0.15.x or 0.17.x.


Step 2 — idempotency check (skip if already wired)

ALREADY=$(ssh "$VPS_USER@$VPS_IP" "hermes mcp list 2>/dev/null | grep -ci jira" || echo 0)
if [ "$ALREADY" -gt 0 ] && [ "${FORCE:-0}" != "1" ]; then
  echo "Jira is already wired. Set FORCE=1 to rewire."
  exit 0
fi

Step 3 — DRY RUN preview (always show before writing)

Compute the Basic header value locally (no logging). The header value must include the literal Basic scheme prefix because Hermes passes it through as one opaque header value — email:token is not a bearer token, so Hermes cannot synthesize the scheme:

# GNU base64 (Linux): -w0 = no line wrap. macOS base64: drop -w0 (it does not wrap).
B64=$(printf '%s' "$ATLASSIAN_EMAIL:$JIRA_TOKEN" | base64 -w0)
HEADER_VALUE="Basic $B64"
cat <<EOF
DRY RUN — the following will happen on $VPS_USER@$VPS_IP:
  1. Write MCP_JIRA_API_KEY (length ${#HEADER_VALUE}, prefix Basic ${B64:0:4}...) via 'hermes config set'
  2. chmod 600 ~/.hermes/.env
  3. Register MCP: hermes mcp add jira --url https://mcp.atlassian.com/v1/mcp --auth-header Authorization
  4. Reload gateway: hermes gateway stop && hermes gateway run
  5. Verify in logs: grep -i "registered.*jira"
  6. Smoke test: GET https://mcp.atlassian.com/v1/mcp -> expect 200/401/403

The token and header value are NEVER printed in plaintext.
EOF

Wait for user confirmation (or skip if AUTO_APPROVE=1).


Step 4 — write the secret (chmod 600, no echo, no logging)

The secret stored is the whole Basic <b64> string, not just the token. The base64 blob can contain +, /, and = — this is exactly why all sed below uses the | delimiter.

ssh "$VPS_USER@$VPS_IP" "hermes config set MCP_JIRA_API_KEY '$HEADER_VALUE'"
ssh "$VPS_USER@$VPS_IP" "chmod 600 ~/.hermes/.env"

Verify (returns 1, NEVER the value):

WROTE=$(ssh "$VPS_USER@$VPS_IP" "grep -c '^MCP_JIRA_API_KEY=' ~/.hermes/.env" || echo 0)
[ "$WROTE" = "1" ] || { echo "FAIL: MCP_JIRA_API_KEY not written. Rolling back."; rollback; exit 1; }

If your Hermes build has no config set subcommand, use the safe sed pattern (pipe delimiter is required — the value contains /+=):

ssh "$VPS_USER@$VPS_IP" "
  grep -q '^MCP_JIRA_API_KEY=' ~/.hermes/.env || printf 'MCP_JIRA_API_KEY=\n' >> ~/.hermes/.env
  sed -i 's|^MCP_JIRA_API_KEY=.*|MCP_JIRA_API_KEY=$HEADER_VALUE|' ~/.hermes/.env
  chmod 600 ~/.hermes/.env
"

Step 5 — register the Jira MCP server

Pick the path that matches the Hermes build on the VPS. Path A is preferred.

Path A (preferred) — official Atlassian remote MCP (HTTP, header auth)

ssh "$VPS_USER@$VPS_IP" "
  hermes mcp add jira \
    --url 'https://mcp.atlassian.com/v1/mcp' \
    --auth-header 'Authorization' \
    --header-value '\${MCP_JIRA_API_KEY}'
"

The flag names vary by Hermes version. If unsure, run hermes mcp add --help first and match its HTTP-header syntax. The header value uses ${MCP_JIRA_API_KEY} indirection so the secret stays in ~/.hermes/.env and never appears in config.yaml.

The resulting config.yaml block should read (token stays out of it):

jira:
  url: https://mcp.atlassian.com/v1/mcp
  headers:
    Authorization: ${MCP_JIRA_API_KEY}
  enabled: true

Path B (fallback) — generic HTTP tool against the Jira REST API

If the Hermes build is stdio-MCP-only and cannot register an HTTP MCP, or if this is Jira Data Center / Server (no remote MCP):

  • Base URL: https://<your-domain>.atlassian.net/rest/api/3 (Cloud) or https://<your-domain>/rest/api/3 (self-hosted)
  • Auth header: Authorization: Basic ${MCP_JIRA_API_KEY_RAW} where MCP_JIRA_API_KEY_RAW = base64(email:token) (no Basic prefix when Hermes adds the scheme itself; otherwise pass the full Basic <b64> as above)
  • Content type: Content-Type: application/json

Do NOT try to register https://mcp.atlassian.com/v1/mcp against a Data Center instance — the hosted endpoint serves Cloud tenants only.


Step 6 — reload the gateway (stop + run, NOT restart)

gateway restart does NOT reliably re-read .env. Always use stop + run.

ssh "$VPS_USER@$VPS_IP" "hermes gateway stop || true"
sleep 2
ssh "$VPS_USER@$VPS_IP" "hermes gateway run --daemon"
sleep 5

Step 7 — verify registration in logs (poll up to 30s)

REGISTERED=0
for i in $(seq 1 6); do
  if ssh "$VPS_USER@$VPS_IP" "hermes logs 2>&1 | tail -200" \
       | grep -qiE "registered.*tool.*jira|MCP server.*jira.*(ok|ready)"; then
    REGISTERED=1
    echo "OK: jira registered in gateway logs."
    break
  fi
  sleep 5
done
[ "$REGISTERED" = "1" ] || { echo "FAIL: jira not in logs after 30s. Rolling back."; rollback; exit 1; }

Expect a line like MCP server 'jira' (HTTP): registered N tool(s): ....


Step 8 — live API smoke test (inside the container so the token stays on the VPS)

HTTP=$(ssh "$VPS_USER@$VPS_IP" "
  curl -sS -o /dev/null -w '%{http_code}' \
    -X GET 'https://mcp.atlassian.com/v1/mcp' \
    -H \"Authorization: \$MCP_JIRA_API_KEY\" \
    -H 'Accept: application/json'
")
case "$HTTP" in
  200) echo "OK: Jira MCP endpoint reachable and credential valid." ;;
  401) echo "FAIL: 401 — invalid header, wrong scheme, or org-admin toggle not enabled. Rolling back."; rollback; exit 1 ;;
  403) echo "FAIL: 403 — credential valid but missing scope/permission."; exit 1 ;;
  404) echo "WARN: 404 — probe path differs by tenant; check tools/list via the gateway." ;;
  *)   echo "WARN: unexpected HTTP $HTTP from Jira MCP. Check manually." ;;
esac

End-to-end smoke from chat:

@<agent> using jira, search for issues assigned to me

A real issue list — or an empty-but-valid result for an account with no issues — is a pass. "Tool not found" for create/update means the credential authenticated as Bearer read-only; switch to Basic (Step 3).


Rollback (auto-runs on any failure above)

rollback() {
  ssh "$VPS_USER@$VPS_IP" "hermes mcp remove jira 2>/dev/null || true"
  ssh "$VPS_USER@$VPS_IP" "hermes config unset MCP_JIRA_API_KEY 2>/dev/null || \
    sed -i '/^MCP_JIRA_API_KEY=/d' ~/.hermes/.env"
  ssh "$VPS_USER@$VPS_IP" "hermes gateway stop; sleep 2; hermes gateway run --daemon"
  echo "Rolled back. Jira is no longer wired."
}

Pitfalls

#PitfallWhy it bitesPrevention
1Org-admin API-token toggle not enabled#1 cause of "valid token, still 401"Org admin must enable API-token auth for Rovo MCP in Atlassian Administration before headless auth works
2Sending personal token as Bearer instead of BasicAuthenticates but exposes only read-only tools — writes appear "missing"Use Basic base64(email:token) for create/update access
3Forgetting the Basic scheme prefix in the stored valueHermes passes the header value t

Content truncated.

When not to use it

  • When connecting Jira Data Center/Server (not Atlassian Cloud)
  • When the user does not have SSH access to their VPS
  • When the user needs to connect a system other than Jira

Limitations

  • The skill connects Jira (Atlassian Cloud).
  • The skill connects to a self-hosted Hermes Agent over SSH.
  • The skill uses Atlassian's official remote MCP server (Rovo).

How it compares

This skill automates the secure and idempotent integration of Jira Cloud with a self-hosted Hermes agent via SSH, handling token storage and MCP registration, unlike a manual setup that could be error-prone.

Compared to similar skills

integration-jira side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
integration-jira (this skill)01moCautionAdvanced
tapd01moReviewAdvanced
fc-assistant02moNo flagsAdvanced
linear02moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry