# Confluence MCP Server

A Model Context Protocol (MCP) server for Confluence integration built with Rust.

## Features

- **List Spaces** - Get all accessible Confluence spaces
- **Get Page** - Fetch page by ID or title
- **Create Page** - Create new pages in any space
- **Update Page** - Modify existing pages with version tracking
- **Delete Page** - Remove pages
- **Search Pages** - Search using CQL (Confluence Query Language)
- **Get Page Children** - List child pages
- **Get Space Pages** - List all pages in a space
- **Add Labels** - Tag pages with labels
- **Get Labels** - Retrieve page labels
- **Read Page Outline** - Get page headings/structure (TOC)
- **Read Page Section** - Read a specific section by heading name
- **Read Page Offset** - Paginated reading with character offsets
- **List Page Attachments** - List all attachments on a page
- **Get Attachment URL** - Get a direct download URL for an attachment
- **Get Attachment Base64** - Fetch attachment data as base64
- **Get Page Storage Format** - Get raw Confluence storage XML/HTML
- **Update Release Table Cell** - Update a specific cell in a table
- **Find & Replace in Page** - Find and replace text/patterns in a page
- **Insert Table Row** - Insert a new row into a table

## Supported Confluence Versions

- ✅ Confluence Cloud (API v2)
- ✅ Confluence Server/Data Center (API v1)

The server auto-detects your Confluence type based on the host URL.

## Setup

### Prerequisites

- [Rust](https://rustup.rs/) (1.70 or later)

### 1. Configure environment variables

Create a `.env` file in the project root with your Confluence credentials:

```env
# Your Confluence instance URL
CONFLUENCE_HOST=https://your-domain.atlassian.net

# For Confluence Cloud: Your Atlassian account email
CONFLUENCE_EMAIL=your-email@example.com

# For Confluence Cloud: API token (get from https://id.atlassian.com/manage-profile/security/api-tokens)
# For Confluence Server/DC: Personal Access Token
CONFLUENCE_API_TOKEN=your-api-token
```

### 2. Build the server

```bash
cargo build --release
```

The compiled binary is at `target/release/mcp-confluence`.

## Usage

### Run directly

```bash
cargo run --release
```

Or run the binary directly:

```bash
./target/release/mcp-confluence
```

### Configure in VS Code

Add to your `.vscode/mcp.json`:

```json
{
  "servers": {
    "confluence": {
      "type": "stdio",
      "command": "/path/to/mcp-confluence/target/release/mcp-confluence",
      "env": {
        "CONFLUENCE_HOST": "https://your-domain.atlassian.net",
        "CONFLUENCE_EMAIL": "your-email@example.com",
        "CONFLUENCE_API_TOKEN": "your-api-token"
      }
    }
  }
}
```

### Test with MCP Inspector

```bash
npx @modelcontextprotocol/inspector ./target/release/mcp-confluence
```

## Available Tools

### `list_spaces`
List all accessible Confluence spaces.
- `limit` (optional): Maximum number of spaces to return
- `type` (optional): Filter by space type (global, personal)

### `get_page`
Fetch a Confluence page by ID or title.
- `pageId` (optional): The page ID
- `spaceKey` (optional): The space key (required if using title)
- `title` (optional): The page title
- `includeBody` (optional): Whether to include page content

### `get_page_full`

This tool does the same as `get_page` but returns XML-formatted content. It is useful when you need to work with unformatted content.

### `create_page`
Create a new Confluence page.
- `spaceKey`: The space key
- `title`: Page title
- `content`: HTML/storage format content
- `parentPageId` (optional): Parent page ID for nested pages

### `update_page`
Update an existing page.
- `pageId`: The page ID
- `title` (optional): New title
- `content`: New content
- `versionComment` (optional): Version comment

### `delete_page`
Delete a Confluence page.
- `pageId`: The page ID

### `search_pages`
Search using CQL (Confluence Query Language).
- `cql`: CQL query string
- `limit` (optional): Max results

**Example CQL queries:**
- `space = "DEV" AND title ~ "API"` - Pages in DEV space with "API" in title
- `type = page AND lastModified > now("-7d")` - Pages modified in last 7 days
- `label = "documentation"` - Pages with specific label

### `get_page_children`
Get child pages of a page.
- `pageId`: Parent page ID
- `limit` (optional): Max results

### `get_space_pages`
Get all pages in a space.
- `spaceKey`: The space key
- `limit` (optional): Max results
- `status` (optional): Page status (current, archived, draft)

### `add_labels`
Add labels to a page.
- `pageId`: The page ID
- `labels`: Array of label names

### `get_labels`
Get labels from a page.
- `pageId`: The page ID

### `read_page_outline`
Get the outline/structure of a page (headings only). Use this first to understand large pages before reading specific sections.
- `pageId`: The page ID

### `read_page_section`
Read a specific section of a page by heading name. Use after `read_page_outline` to read content from specific sections of large pages.
- `pageId`: The page ID
- `headingText`: The heading text to find (partial match supported)
- `headingLevel` (optional): Specific heading level (1-6) to match

### `read_page_offset`
Read a page starting from a specific character offset. Use this to continue reading a truncated page.
- `pageId`: The page ID
- `offset` (optional): Character offset to start reading from (default: 0)
- `length` (optional): Number of characters to read (default: 30000)

### `list_page_attachments`
List all attachments (images, files) on a page with metadata.
- `pageId`: The page ID
- `mediaType` (optional): Filter by media type (e.g., `image/png`, `application/pdf`)

### `get_attachment_url`
Get the direct download URL for an attachment.
- `pageId`: The page ID containing the attachment
- `filename`: The filename of the attachment

### `get_attachment_base64`
Fetch an attachment and return it as base64-encoded data. Useful for images with vision-capable models.
- `pageId`: The page ID containing the attachment
- `filename`: The filename of the attachment
- `maxSizeKB` (optional): Maximum file size in KB to fetch (default: 500)

### `get_page_storage_format`
Get the raw Confluence storage format (XML/HTML) of a page. Essential for making precise edits to complex pages with tables, macros, etc.
- `pageId`: The page ID
- `section` (optional): Extract only a section containing this text

### `update_release_table_cell`
Update a specific cell in a Confluence table. Finds a row by identifier and updates a specific column.
- `pageId`: The page ID containing the table
- `rowIdentifier`: Text to identify the row (e.g., a date, feature name, or SDLC number)
- `columnIdentifier`: Text to identify the column header
- `newContent`: New HTML/storage format content for the cell
- `replaceMode` (optional): `replace` (default), `append`, or `prepend`

### `find_replace_in_page`
Find and replace text/patterns in a page's storage format.
- `pageId`: The page ID to update
- `findPattern`: The text or regex pattern to find
- `replaceWith`: The replacement text/content
- `isRegex` (optional): Whether `findPattern` is a regex (default: false)
- `globalReplace` (optional): Replace all occurrences (default: false)

### `insert_table_row`
Insert a new row into a Confluence table.
- `pageId`: The page ID containing the table
- `tableIdentifier`: Text to identify the table (e.g., a column header)
- `afterRowIdentifier` (optional): Insert after the row containing this text (default: end of table)
- `rowContent`: Complete `<tr>...</tr>` HTML for the new row

## Development

```bash
# Build (debug)
cargo build

# Run tests
cargo test

# Run integration tests (requires Confluence credentials)
cargo test --test mcp_integration -- --ignored
```

## Environment Variables Reference

| Variable | Required | Description |
|----------|----------|-------------|
| `CONFLUENCE_HOST` | Yes | Confluence instance URL |
| `CONFLUENCE_EMAIL` | Cloud only | Atlassian account email |
| `CONFLUENCE_API_TOKEN` | Yes | API token or PAT |
| `CONFLUENCE_API_VERSION` | No | Override API version (1 or 2) |
| `CONFLUENCE_USE_BEARER` | No | Force Bearer auth (for Server/DC) |
| `CONFLUENCE_MAX_CONTENT_LENGTH` | No | Max content length before truncation (default: 30000, 0 to disable) |

## License

ISC
