> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Jira

The io.b3os/jira pack: 10 actions with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.

`io.b3os/jira` 1.0.0 · `issue-tracking`, `project-management` · MIT

Work with Jira Cloud issues using your Atlassian email and API token: search with JQL, read an issue with its rendered description and comments, create issues, comment, move issues through workflow transitions, assign them, and look up projects and users. Uses the Jira Cloud REST API v3 on your &lt;site&gt;.atlassian.net (not Jira Data Center).

Every call's result carries `upstream_status` and `timing`: `validate_ms`, `inject_ms`, `render_ms`, `upstream_ms`, `map_ms` and `total_ms`. `upstream` is the service's time; the others are B3OS's own ([call actions](/actions/call)). The snippets below show no timing values, because a fixture records none.

## Connection

`jira`, type `basic`: Jira Cloud account.

Your Atlassian account email as the username and an API token (id.atlassian.com, Security, API tokens) as the password, plus your site name: acme for acme.atlassian.net. The token acts with your Jira permissions.

How to get one: [support.atlassian.com](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/).

Connection params (no secret): `site`.

The credential is sent only to `*.atlassian.net`.

Store the credential once as a [vault connection](/vault) for this pack and key, then name its id in a call's `connections`. Leave the key out and B3OS uses the project's newest connection for the pack and key without a `subject` ([connections](/actions/call#connections)).

Hosts it reaches: `*.atlassian.net`.

## Actions

| Action | Effect | MCP tool | Title |
|---|---|---|---|
| [`get-myself`](/actions/catalog/jira#jira-get-myself) | read | `jira__get-myself` | Get current user |
| [`search-issues`](/actions/catalog/jira#jira-search-issues) | read | `jira__search-issues` | Search issues (JQL) |
| [`get-issue`](/actions/catalog/jira#jira-get-issue) | read | `jira__get-issue` | Get issue |
| [`create-issue`](/actions/catalog/jira#jira-create-issue) | write | `jira__create-issue` | Create issue |
| [`add-comment`](/actions/catalog/jira#jira-add-comment) | write | `jira__add-comment` | Comment on issue |
| [`get-transitions`](/actions/catalog/jira#jira-get-transitions) | read | `jira__get-transitions` | Get transitions |
| [`transition-issue`](/actions/catalog/jira#jira-transition-issue) | write | `jira__transition-issue` | Transition issue |
| [`assign-issue`](/actions/catalog/jira#jira-assign-issue) | write | `jira__assign-issue` | Assign issue |
| [`find-users`](/actions/catalog/jira#jira-find-users) | read | `jira__find-users` | Find users |
| [`list-projects`](/actions/catalog/jira#jira-list-projects) | read | `jira__list-projects` | List projects |

get-myself

**Get current user.** Who the API token belongs to: account id, display name, email and time zone. A cheap way to check the connection and site.

Ref `io.b3os/jira/get-myself@1.0.0` · effect `read` · connection `jira` · MCP tool `jira__get-myself`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/get-myself@1",
          "input": {},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/get-myself@1",
      input: {},
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/get-myself@1",
        "input": {},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "jira__get-myself", "arguments": {}}
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__get-myself` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get current user (documented response shape, example values). From the bundle's `fixtures/get-myself.json`, not a live call.

```json
{
  "account_id": "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
  "display_name": "Mona Example",
  "email": "mona@acme.example",
  "time_zone": "America/Los_Angeles"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

search-issues

**Search issues (JQL).** Find issues with JQL, for example project = PROJ AND status != Done ORDER BY updated DESC, or assignee = currentUser() AND sprint in openSprints(). Returns key, summary, status, type, priority, assignee, labels and dates. Page with next_page_token while is_last is false.

Ref `io.b3os/jira/search-issues@1.0.0` · effect `read` · connection `jira` · MCP tool `jira__search-issues`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/search-issues@1",
          "input": {
            "jql": "project = SHOP AND statusCategory != Done ORDER BY updated DESC",
            "max_results": 1
          },
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/search-issues@1",
      input: {
        jql: "project = SHOP AND statusCategory != Done ORDER BY updated DESC",
        max_results: 1,
      },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/search-issues@1",
        "input": {
            "jql": "project = SHOP AND statusCategory != Done ORDER BY updated DESC",
            "max_results": 1,
        },
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "jira__search-issues",
        "arguments": {
          "jql": "project = SHOP AND statusCategory != Done ORDER BY updated DESC",
          "max_results": 1
        }
      }
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__search-issues` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Search issues (JQL) (documented response shape, example values). From the bundle's `fixtures/search-issues.json`, not a live call.

```json
{
  "issues": [
    {
      "key": "SHOP-42",
      "id": "10042",
      "summary": "Cart overflows on narrow screens",
      "status": "In Progress",
      "status_category": "indeterminate",
      "issue_type": "Bug",
      "priority": "High",
      "assignee": "Mona Example",
      "reporter": "Hubot Example",
      "labels": ["checkout"],
      "created": "2026-10-24T10:11:20.000-0700",
      "updated": "2026-10-25T09:02:41.000-0700",
      "url": "https://acme.atlassian.net/browse/SHOP-42"
    }
  ],
  "is_last": false,
  "next_page_token": "CAEaAggD"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

get-issue

**Get issue.** One issue by key with summary, status, type, priority, people, labels, the description rendered as HTML, and its latest comments (rendered as HTML).

Ref `io.b3os/jira/get-issue@1.0.0` · effect `read` · connection `jira` · MCP tool `jira__get-issue`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/get-issue@1",
          "input": {"key": "SHOP-42"},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/get-issue@1",
      input: { key: "SHOP-42" },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/get-issue@1",
        "input": {"key": "SHOP-42"},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "jira__get-issue", "arguments": {"key": "SHOP-42"}}
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__get-issue` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get issue (documented response shape, example values). From the bundle's `fixtures/get-issue.json`, not a live call.

```json
{
  "key": "SHOP-42",
  "id": "10042",
  "summary": "Cart overflows on narrow screens",
  "status": "In Progress",
  "status_category": "indeterminate",
  "issue_type": "Bug",
  "priority": "High",
  "assignee": "Mona Example",
  "reporter": "Hubot Example",
  "labels": ["checkout"],
  "created": "2026-10-24T10:11:20.000-0700",
  "updated": "2026-10-25T09:02:41.000-0700",
  "url": "https://acme.atlassian.net/browse/SHOP-42",
  "description_html": "<p>Steps: open the cart and resize to 375px.</p>",
  "comments": [
    {
      "author": "Hubot Example",
      "body_html": "<p>Reproduced on Safari 18.</p>",
      "created": "25/Oct/26 10:00 AM"
    }
  ]
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

create-issue

**Create issue.** Create an issue in a project with a summary, an issue type (Task, Bug, Story, ... as named in the project), an optional plain-text description, labels and assignee. Returns the new key and URL. Not idempotent.

Ref `io.b3os/jira/create-issue@1.0.0` · effect `write` · connection `jira` · MCP tool `jira__create-issue`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/create-issue@1",
          "input": {
            "project_key": "SHOP",
            "summary": "Flaky checkout test",
            "issue_type": "Bug",
            "description": "Seen three times this week.",
            "labels": ["ci"]
          },
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/create-issue@1",
      input: {
        project_key: "SHOP",
        summary: "Flaky checkout test",
        issue_type: "Bug",
        description: "Seen three times this week.",
        labels: ["ci"],
      },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/create-issue@1",
        "input": {
            "project_key": "SHOP",
            "summary": "Flaky checkout test",
            "issue_type": "Bug",
            "description": "Seen three times this week.",
            "labels": ["ci"],
        },
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "jira__create-issue",
        "arguments": {
          "project_key": "SHOP",
          "summary": "Flaky checkout test",
          "issue_type": "Bug",
          "description": "Seen three times this week.",
          "labels": ["ci"]
        }
      }
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__create-issue` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Create issue (documented response shape, example values). From the bundle's `fixtures/create-issue.json`, not a live call.

```json
{
  "key": "SHOP-43",
  "id": "10043",
  "url": "https://acme.atlassian.net/browse/SHOP-43"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

add-comment

**Comment on issue.** Add a plain-text comment to an issue (sent as one paragraph). Returns the comment id. Not idempotent.

Ref `io.b3os/jira/add-comment@1.0.0` · effect `write` · connection `jira` · MCP tool `jira__add-comment`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/add-comment@1",
          "input": {"key": "SHOP-42", "text": "Fixed in build 812."},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/add-comment@1",
      input: { key: "SHOP-42", text: "Fixed in build 812." },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/add-comment@1",
        "input": {"key": "SHOP-42", "text": "Fixed in build 812."},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "jira__add-comment",
        "arguments": {"key": "SHOP-42", "text": "Fixed in build 812."}
      }
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__add-comment` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Comment on issue (documented response shape, example values). From the bundle's `fixtures/add-comment.json`, not a live call.

```json
{"id": "10102", "created": "2026-10-26T08:00:00.000-0700"}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

get-transitions

**Get transitions.** The workflow transitions available on an issue right now (Start progress, Done, ...), with their ids and the status each leads to. transition-issue needs one of these ids.

Ref `io.b3os/jira/get-transitions@1.0.0` · effect `read` · connection `jira` · MCP tool `jira__get-transitions`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/get-transitions@1",
          "input": {"key": "SHOP-42"},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/get-transitions@1",
      input: { key: "SHOP-42" },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/get-transitions@1",
        "input": {"key": "SHOP-42"},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "jira__get-transitions", "arguments": {"key": "SHOP-42"}}
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__get-transitions` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get transitions (documented response shape, example values). From the bundle's `fixtures/get-transitions.json`, not a live call.

```json
{
  "transitions": [
    {
      "id": "21",
      "name": "In Progress",
      "to_status": "In Progress",
      "to_category": "indeterminate"
    },
    {
      "id": "31",
      "name": "Done",
      "to_status": "Done",
      "to_category": "done"
    }
  ]
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

transition-issue

**Transition issue.** Move an issue through its workflow with a transition id from get-transitions, for example to In Progress or Done. Fields the transition screen requires are not set by this action.

Ref `io.b3os/jira/transition-issue@1.0.0` · effect `write` · connection `jira` · MCP tool `jira__transition-issue`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/transition-issue@1",
          "input": {"key": "SHOP-42", "transition_id": "31"},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/transition-issue@1",
      input: { key: "SHOP-42", transition_id: "31" },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/transition-issue@1",
        "input": {"key": "SHOP-42", "transition_id": "31"},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "jira__transition-issue",
        "arguments": {"key": "SHOP-42", "transition_id": "31"}
      }
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__transition-issue` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Transition issue (documented response shape, example values). From the bundle's `fixtures/transition-issue.json`, not a live call.

```json
{"key": "SHOP-42", "transition_id": "31"}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

assign-issue

**Assign issue.** Assign an issue to a user by account id (find-users looks them up), or unassign it when account_id is omitted.

Ref `io.b3os/jira/assign-issue@1.0.0` · effect `write` · connection `jira` · MCP tool `jira__assign-issue`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/assign-issue@1",
          "input": {
            "key": "SHOP-42",
            "account_id": "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
          },
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/assign-issue@1",
      input: {
        key: "SHOP-42",
        account_id: "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
      },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/assign-issue@1",
        "input": {
            "key": "SHOP-42",
            "account_id": "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
        },
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "jira__assign-issue",
        "arguments": {
          "key": "SHOP-42",
          "account_id": "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__assign-issue` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Assign issue (documented response shape, example values). From the bundle's `fixtures/assign-issue.json`, not a live call.

```json
{
  "key": "SHOP-42",
  "account_id": "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

find-users

**Find users.** Find people by name or email fragment, with account ids for assign-issue and create-issue. Email is only shown where the user's privacy settings allow.

Ref `io.b3os/jira/find-users@1.0.0` · effect `read` · connection `jira` · MCP tool `jira__find-users`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/find-users@1",
          "input": {"query": "mona"},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/find-users@1",
      input: { query: "mona" },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/find-users@1",
        "input": {"query": "mona"},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "jira__find-users", "arguments": {"query": "mona"}}
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__find-users` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Find users (documented response shape, example values). From the bundle's `fixtures/find-users.json`, not a live call.

```json
{
  "users": [
    {
      "account_id": "712020:1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
      "display_name": "Mona Example",
      "email": "mona@acme.example",
      "active": true
    }
  ]
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |

list-projects

**List projects.** Projects visible to the user, optionally filtered by name or key: key, name, type (software, business, service_desk) and id. Page with start_at.

Ref `io.b3os/jira/list-projects@1.0.0` · effect `read` · connection `jira` · MCP tool `jira__list-projects`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/jira/list-projects@1",
          "input": {"max_results": 2},
          "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/jira/list-projects@1",
      input: { max_results: 2 },
      connections: { jira: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/jira/list-projects@1",
        "input": {"max_results": 2},
        "connections": {"jira": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "jira__list-projects", "arguments": {"max_results": 2}}
    }
    ```

    Expose the pack as tools with `--packs jira` on the local server or `?packs=jira` on the remote URL, and the agent calls `jira__list-projects` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List projects (documented response shape, example values). From the bundle's `fixtures/list-projects.json`, not a live call.

```json
{
  "projects": [
    {
      "id": "10000",
      "key": "SHOP",
      "name": "Storefront",
      "type": "software"
    },
    {
      "id": "10001",
      "key": "OPS",
      "name": "Operations",
      "type": "service_desk"
    }
  ],
  "total": 2,
  "is_last": true
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Jira rejected the email and API token. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Jira rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 400 | no | built from the service's response |