> ## Documentation Index
> Fetch the complete documentation index at: https://beige.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Confluence Tool

{/* Run: pnpm run docs:sync-toolkit */}

Interact with Atlassian Confluence via the [`confluence-cli`](https://github.com/pchuri/confluence-cli) binary installed on the gateway host. Agents pass confluence arguments directly; the tool enforces two independent, optional permission layers before executing anything.

## Installation

Install this tool individually:

```bash theme={null}
beige tools install github:matthias-hausberger/beige-toolkit/tools/confluence
```

Or install all tools from the toolkit:

```bash theme={null}
# From npm
beige tools install npm:@matthias-hausberger/beige-toolkit

# From GitHub
beige tools install github:matthias-hausberger/beige-toolkit
```

## Configuration

| Key                    | Default      | Description                                                                                                                                       |
| ---------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowCommands`        | all commands | If set, only these command paths are permitted. Prefix matching: `"create"` covers `create-child`. Omit to allow all (subject to `denyCommands`). |
| `denyCommands`         | *(none)*     | Command paths that are always blocked, even if in `allowCommands`. Deny beats allow. Prefix matching applies.                                     |
| `allowReadSpaces`      | all spaces   | If set, read operations are only permitted for pages/spaces in this list. Space keys matched case-insensitively.                                  |
| `allowWriteSpaces`     | all spaces   | If set, write operations are only permitted for pages/spaces in this list. Space keys matched case-insensitively.                                 |
| `requireSpaceOnSearch` | `false`      | When `true`, `search` calls without a `--space` flag are rejected. Forces agents to always scope searches. CQL in query strings is NOT enforced.  |
| `timeout`              | `30`         | Timeout in seconds for each confluence invocation (including internal `info` lookups for space resolution).                                       |
| `profile`              | *(none)*     | Default profile name. Prepended as `--profile <value>` to every call when `--profile` is not already in the agent's args.                         |

By default, all commands are permitted and all spaces are accessible — both permission layers are fully open until explicitly configured.

## Prerequisites

| Requirement      | Details                                                                                           |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| `confluence-cli` | Must be installed on the gateway host ([install guide](https://github.com/pchuri/confluence-cli)) |
| Authentication   | Run `confluence init` on the gateway host to set up credentials                                   |

## Permission Model

There are two independent, optional permission layers. Either, both, or neither can be configured. They compose: a call must pass **both** layers to proceed.

```
Agent call
    │
    ▼
┌─────────────────────────┐
│  Layer 1: command-level │  denyCommands / allowCommands
│  (subcommand name only) │  → fast, no API calls
└────────────┬────────────┘
             │ allowed
             ▼
┌─────────────────────────┐
│  Layer 2: space-level   │  allowReadSpaces / allowWriteSpaces
│  (which space/page)     │  → Tier 1 free, Tier 2 one info call
└────────────┬────────────┘
             │ allowed
             ▼
         Execute
```

### Layer 1 — Command-Level

Controls which subcommands the agent may run. Command paths use the leading subcommand tokens (e.g. `read`, `search`, `create`, `profile list`).

**Prefix matching:** `"create"` blocks both `create` and `create-child`. `"profile"` blocks all profile subcommands.

**Precedence:** deny beats allow.

### Layer 2 — Space-Level

Controls which Confluence **spaces** the agent may read from and write to. Completely skipped when neither `allowReadSpaces` nor `allowWriteSpaces` is configured.

| Kind                       | Commands                                                                                                                                                  |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **READ**                   | `read`, `info`, `children`, `attachments`, `comments`, `property-list`, `property-get`, `export`, `edit`, `find`, `search`                                |
| **WRITE**                  | `create`, `create-child`, `update`, `delete`, `move`, `copy-tree`, `attachment-upload`, `attachment-delete`, `comment`, `property-set`, `property-delete` |
| **AGNOSTIC** (always pass) | `spaces`, `stats`, `profile`, `init`, `comment-delete`                                                                                                    |

#### Space Resolution

* **Static (free):** `create` parses the space key from args, `search --space` uses the flag, URLs have the space key in the path
* **Dynamic (one API call):** Commands with numeric page IDs trigger a `confluence info` lookup (results are cached)

#### ⚠️ CQL Disclaimer

The `search` command accepts free-text queries that may contain CQL expressions. **This tool only inspects the `--space` flag.** CQL in the query string is NOT parsed or enforced. Use `requireSpaceOnSearch: true` to force explicit `--space` usage.

#### ⚠️ comment-delete Disclaimer

`comment-delete <commentId>` takes a comment ID, not a page ID. Space enforcement cannot be applied. Use `denyCommands: ["comment-delete"]` to block it entirely if needed.

## Config Examples

**Read-only agent, all spaces:**

```json5 theme={null}
{
  tools: {
    confluence: {
      config: {
        denyCommands: ["create", "create-child", "update", "delete", "move", "copy-tree",
                       "attachment-upload", "attachment-delete", "comment", "comment-delete",
                       "property-set", "property-delete"],
      },
    },
  },
}
```

**Read-only agent, scoped to DOCS and TEAM spaces:**

```json5 theme={null}
{
  tools: {
    confluence: {
      config: {
        denyCommands: ["create", "create-child", "update", "delete", "move", "copy-tree",
                       "attachment-upload", "attachment-delete", "comment", "comment-delete",
                       "property-set", "property-delete"],
        allowReadSpaces: ["DOCS", "TEAM"],
        requireSpaceOnSearch: true,
      },
    },
  },
}
```

**Documentation bot (reads anywhere, writes only to DRAFTS):**

```json5 theme={null}
{
  tools: {
    confluence: {
      config: {
        allowWriteSpaces: ["DRAFTS"],
      },
    },
  },
}
```

**Write-safe agent (all reads allowed; only non-destructive writes):**

```json5 theme={null}
{
  tools: {
    confluence: {
      config: {
        denyCommands: ["delete", "move", "attachment-delete", "comment-delete", "property-delete"],
      },
    },
  },
}
```

**Full access, always use the production profile:**

```json5 theme={null}
{
  tools: {
    confluence: {
      config: {
        profile: "production",
      },
    },
  },
}
```

### Per-Agent Configuration (pluginConfigs)

Use beige's `pluginConfigs` to give different agents different Confluence permissions:

```json5 theme={null}
tools: {
  confluence: {
    config: {
      // Baseline: read-only, all spaces
      denyCommands: ["create", "create-child", "update", "delete", "move", "copy-tree",
                     "attachment-upload", "attachment-delete", "comment",
                     "property-set", "property-delete"],
      profile: "production",
    },
  },
},

agents: {
  // Research agent — read-only, scoped to specific spaces
  researcher: {
    tools: ["confluence"],
    pluginConfigs: {
      confluence: {
        allowReadSpaces: ["DOCS", "TEAM"],
        requireSpaceOnSearch: true,
      },
    },
  },

  // Documentation bot — can also write, but only to DRAFTS
  docbot: {
    tools: ["confluence"],
    pluginConfigs: {
      confluence: {
        denyCommands: [],              // override: remove all command denials
        allowWriteSpaces: ["DRAFTS"],  // added: restrict writes to DRAFTS
      },
    },
  },

  // Default agent — uses baseline config (read-only, all spaces)
  assistant: {
    tools: ["confluence"],
  },
},
```

## Available Commands

### Read / Search

`read`, `info`, `search`, `spaces`, `find`, `children`

### Create / Update / Delete

`create`, `create-child`, `copy-tree`, `update`, `move`, `delete`, `edit`

### Attachments

`attachments`, `attachment-upload`, `attachment-delete`

### Comments

`comments`, `comment`, `comment-delete`

### Content Properties

`property-list`, `property-get`, `property-set`, `property-delete`

### Export / Profiles

`export`, `edit`, `profile list`, `profile use`, `profile add`, `profile remove`, `stats`

## Error Reference

| Error                                                        | Cause                                            |
| ------------------------------------------------------------ | ------------------------------------------------ |
| `confluence not found on PATH`                               | Binary not installed or not on gateway's PATH    |
| `Permission denied: command 'X' is blocked by denyCommands`  | Command matched a deny entry                     |
| `Permission denied: command 'X' is not in allowCommands`     | allowCommands is set and command not listed      |
| `Permission denied: space 'X' is not in allowReadSpaces`     | Page/space not in the read allowlist             |
| `Permission denied: space 'X' is not in allowWriteSpaces`    | Page/space not in the write allowlist            |
| `Permission denied: search without --space is not permitted` | requireSpaceOnSearch enabled and --space missing |

## Implementation Details

* **Target**: Gateway (runs on the host, not in the sandbox)
* **Dependency**: `confluence-cli` binary
* **Stateless**: Each invocation spawns a fresh process (except cached space lookups)
