Skip to content
Conduit

mcp server

confluence-mcp

An enhanced Enterprise-grade Confluence MCP server.

flowgent-labs/confluence-mcpcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 26, 2026

confluence-mcp

Go MCP Prometheus OpenTelemetry OIDC Helm

The Enterprise-grade MCP server generated by mcpfather, specifically designed for AI to call Confluence Data Center APIs, generated from MCPFather — exposes 176 native tools. Each API operation becomes an AI-callable tool with typed schemas and customized aggregate virtual tools, auth forwarding, and observability built-in, and even use as regular CLI.

Quick Start

make

# Or with OpenTelemetry distributed tracing (gRPC or HTTP)
make build-with-otel-grpc   # OTLP gRPC exporter
make build-with-otel-http   # OTLP HTTP/protobuf exporter

Start in HTTP mode (example)

# Configure your upstream API
export MCP__UPSTREAM__DEFAULT__ENDPOINT=https://api.example.com
export MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN=your-token

./bin/confluence-mcp --transport http --port 8080 &
  • Inspection MCP Server Authentication (OAuth2.1).
export MCP__SERVER__AUTH__OIDC__ENABLED=true
export MCP__SERVER__AUTH__OIDC__ISSUER="https://keycloak.example.com/realms/master"
export MCP__SERVER__AUTH__OIDC__AUDIENCE="confluence-mcp"
./bin/confluence-mcp -v 10 --transport http --port 8080

# Obtain the OAuth2.1 metadata.
curl -s https://iam.example.com/realms/master/.well-known/openid-configuration

curl -s localhost:8080/.well-known/oauth-protected-resource
#{"resource":"confluence-mcp","authorization_servers":["https://keycloak.example.com/realms/master"],"bearer_methods_supported":["header"]}

Run in CLI mode (example)

./bin/confluence-mcp -v 1 -t cli list
./bin/confluence-mcp -v 1 -t cli <tool-name> [OPTIONS]

Request body (--body)

Use --body to send a JSON request body to the upstream API. Query/path parameters are passed as regular --key value flags.

# JSON body
./bin/confluence-mcp -v 1 -t cli uploadScanReport --scanId 12345 \
  --body '{"note":"quarterly"}'

File uploads (fileRef URL)

For file upload tools, pass file fields as normal tool arguments. Values starting with @file:///, @https://, or @http:// are fileRef URLs: the server downloads the file to the TFS temp cache and forwards it to upstream. Other multipart fields are passed as regular --key value flags.

# Local file, for the conventional multipart field named "file"
./bin/confluence-mcp -v 1 -t cli uploadScanReport --scanId 12345 \
  --file /tmp/report.pdf

# Remote URL (server downloads, then forwards to upstream)
./bin/confluence-mcp -v 1 -t cli uploadScanReport --scanId 12345 \
  --file @https://cdn.example.com/reports/q1.pdf

# Named file field
./bin/confluence-mcp -v 1 -t cli configSaml \
  --identityProviderXml @file:///tmp/idp.xml \
  --samlConfiguration '{"enabled":true}'

The same flag syntax works in HTTP mode via mcpclient.sh:

./mcpclient.sh call uploadScanReport --scanId 12345 \
  --file /tmp/report.pdf

Options

FlagDefaultDescription
-t, --transportstdiostdio / http / cli
-p, --port8080HTTP server port
--metrics-port0Override mgmt port (0 = use config)
-v, --verbose0Log verbosity (0–10)
-V, --version—Print version and exit
--print-default-config—Print default config.yaml to stdout

Authentication

Auth is split into two independent layers — neither shares credentials with the other:

LayerConfig YAML pathEnv var prefixRole
Serverserver.auth.oidcMCP__SERVER__AUTH__OIDC__*Validates AI agent bearer tokens (inbound)
Upstream OIDCupstream.default.auth.oidcMCP__UPSTREAM__DEFAULT__AUTH__OIDC__*Server's own OIDC client_credentials for upstream APIs
Upstream Staticupstream.default.auth.staticMCP__UPSTREAM__DEFAULT__AUTH__STATIC__*Server's own static token/cookie for upstream APIs

Server (inbound) — validates bearer tokens presented by AI agents (MCP clients). Only applies to --transport http; stdio has no network boundary. Standard OIDC JWT bearer validation per RFC 9728 / MCP Authorization spec.

Upstream (outbound) — credentials the MCP server uses to call upstream APIs. Token priority (first available wins):

  1. OIDC client_credentials grant (upstream.default.auth.oidc.*)
  2. Static web token (upstream.default.auth.static.web_token)

The AI agent's inbound token is never forwarded upstream (MCP spec: Token Passthrough Prohibition). Cookie-based auth is also available via upstream.default.auth.static.cookie_token.

Configuration

Create ~/.confluence-mcp/config.yaml (run --print-default-config for a full template):

# ---- Server (inbound) ----
# Validates bearer tokens presented by MCP clients (AI agents).
# Resource Server role per RFC 9728 / MCP Authorization spec.
# Only enforced on the http transport; stdio has no network boundary.
server:
  # HTTP server timeouts in seconds. 0 = disabled.
  # write_timeout_seconds must be 0 for SSE (Streamable HTTP) transport.
  read_timeout_seconds: 30
  write_timeout_seconds: 0
  idle_timeout_seconds: 120
  auth:
    oidc:
      enabled: false
      issuer: ""            # e.g. https://idp.example.com/realms/myrealm
      jwks_uri: ""          # optional override (auto-discovered from issuer if empty)
      audience: ""          # expected JWT "aud" claim; also published as the RFC 9728 protected-resource identifier
      # When true, validated JWT claims (sub, email) are forwarded upstream
      # as X-MCP-Client-Token-Sub and X-MCP-Client-Token-Email headers.
      enable_client_token_claim_forward: true
      # Additional JWT claims to forward as X-MCP-Client-Token-<Header-Name> headers.
      # e.g. ["given_name", "family_name", "preferred_username"]
      # additional_client_token_claim_forward: []
  # ---- Temporary File System (TFS) Data Plane ----
  # Built-in REST API for binary file transfer, separate from the
  # JSON-RPC 2.0 control plane at /mcp.
  # Files stored under ~/.<service-name>/tfs/{download,upload}/
  tfs:
    enabled: true
    # Empty means auto-detect from the inbound /mcp request Host/X-Forwarded-* headers.
    base_uri: ""
    # Download URLs are one-shot: after a successful GET from /_/tfs/download/{id},
    # the temporary file is immediately removed. Files that are never downloaded
    # are removed by the background clean job after this TTL.
    clean-job-ttl-seconds: "5m"

logging:
  level: 0
  auth_verbose: false

# ---- Upstream (outbound) ----
# Credentials the server uses to call upstream APIs.
# The two auth layers are independent — the inbound token is never reused outbound
# (see MCP Authorization spec: Token Passthrough Prohibition).
upstream:
  default:
    endpoint: ""               # upstream API base URL (e.g. https://api.example.com)
    enable_mcp_session_forward: true
    auth:
      oidc:
        enabled: true
        issuer: https://idp.example.com/realms/myrealm
        client_id: my-client
        client_secret: "${MCP__UPSTREAM__DEFAULT__AUTH__OIDC__CLIENT_SECRET}"
        scopes: openid
        # token_url: ""   # auto-discovered from issuer /.well-known

      # Static credentials for legacy / simple APIs
      static:
        web_token: "${MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN}"   # or set cookie_token

# Reusable policies selected by HTTP-node `spec.pool` and `spec.retry`.
# Omitted references use pool limits 32/32/32, request_timeout 0s, and 0 retries.
middleware:
  http_client_pool:
    large:
      max_idle_conns: 128          # reusable idle connections across all upstream hosts
      max_idle_conns_per_host: 32  # reusable idle connections retained per upstream host
      max_conns_per_host: 64       # hard cap: active + dialing + idle connections per host
      dial_timeout: 10s            # TCP connection establishment timeout
      request_timeout: 60s         # complete attempt, including response-body reads
    medium:
      max_idle_conns: 64
      max_idle_conns_per_host: 16
      max_conns_per_host: 32
      dial_timeout: 5s
      request_timeout: 30s
    small:
      max_idle_conns: 16
      max_idle_conns_per_host: 4
      max_conns_per_host: 8
      dial_timeout: 3s
      request_timeout: 15s
  retry:
    reliable:
      max_retries: 4               # extra attempts after the first request
      max_elapsed_time: 30s        # hard budget for all attempts and backoff
    standard:
      max_retries: 2
      max_elapsed_time: 15s
    besteffort:
      max_retries: 0               # no automatic retry; max_elapsed_time is unnecessary

# QoS-style names communicate retry intent without promising application success.

native_tools:
  expose:
    register_all_tools_by_default: true   # expose all native tools
    # includes: [Tool1, Tool2]            # or whitelist specific tools
    # excludes: [Tool3]                   # hide noisy tools

All values can be set via MCP__-prefixed environment variables (e.g. MCP__UPSTREAM__DEFAULT__AUTH__OIDC__CLIENT_ID).

Management — Metrics, Tracing, Pprof

mgmt:
  enabled: true
  host: 0.0.0.0
  port: 9991

  otel:
    enabled: false
    endpoint: localhost:4317
    protocol: grpc
    sample_rate: 1.0

  metrics:
    enabled: true
    prometheus: true
    export_interval: 30s

  pprof:
    enabled: false
    server_bind: 0.0.0.0:6669
./bin/confluence-mcp --transport http --port 8080
curl http://localhost:9991/metrics    # Prometheus endpoint
curl http://localhost:9991/health     # health check

Trace spans are named mcp.tool.<name>. W3C traceparent is propagated to upstream calls.

Available Tools (176)

ToolDescription
AddAdd a category to a space - Adds a category the description of a given {@link Space} identified by spaceKey. Example request URI to add space category 'testCategory' to space with space key TEST: https://example.com/confluence/rest/api/space/TEST/category/testCategory
AddContentWatcherAdd content watcher - Create a new watcher for the given user and content id. User is optional. If not specified, currently logged-in user will be used. Otherwise, it can be specified by either user key or username. When a user is specified and is different from the logged-in user, the logged-in user needs to be a Confluence administrator. Example request URI(s): http://example.com/confluence/rest/api/user/watch/content/131213 http://example.com/confluence/rest/api/user/watch/content/131213?username=jblogs http://example.com/confluence/rest/api/user/watch/content/131213?key=ff8080815a58e24c015a58e263710000
AddLabelsAdd Labels - Adds a list of labels to the specified content. The body is the json representation of the list.
AddSpaceWatchAdd space watcher - Create a new watcher for the given user and space key. User is optional. If not specified, currently logged-in user will be used. Otherwise, it can be specified by either user key or username. When a user is specified and is different from the logged-in user, the logged-in user needs to be a Confluence administrator. Example request URI(s): http://example.com/confluence/rest/api/user/watch/space/SPACEKEY http://example.com/confluence/rest/api/user/watch/space/SPACEKEY?username=jblogs http://example.com/confluence/rest/api/user/watch/space/SPACEKEY?key=ff8080815a58e24c015a58e263710000 http://example.com/confluence/rest/api/user/watch/space/SPACEKEY?contentType=blogpost
ArchiveArchive space - Archive the given Space identified by spaceKey. This method is idempotent i.e., if the Space is already archived then no action will be taken.
ByOperationGet all restrictions by Operation - Returns info about all restrictions by operation.
CancelAllQueuedJobsCancel all queued jobs - Cancels all queued jobs. Does not affect jobs that are being processed at the moment.
CancelJobCancel job - Cancels the job. If the job is already cancelled or failed, the method will do nothing.
ChangePasswordChange password - Change the password for the user identified by the username. Validation rules : - The new password should not be null or blank.
ChangePassword1Change password - Change the password for the current user. Validation Rules: - New password supplied cannot be null or blank Example request URI(s): http://example.com/confluence/rest/api/user/current/password
ChildrenGet children of content - Returns a map of the direct children of a piece of Content. Content can have multiple types of children. For example, a Page can have children that are also Pages, but it can also have Comments and Attachments. The types of the children returned is specified by the expand query parameter in the request. This parameter can include expands for multiple child types. If no types are included in the expand parameter, the map returned will just list the child types that are available to be expanded for the content referenced by the id path parameter.
ChildrenOfTypeGet children of content by type - Returns the direct children of a piece of Content, limited to a single child type.The types of the children returned is specified by the "type" path parameter in the request.
CommentsOfContentGet comments of content - Returns the comments of a piece of Content. Example request URI(s): - http://example.com/confluence/rest/api/content/1234/child/comment - http://example.com/confluence/rest/api/content/1234/child/comment?expand=body.view - http://example.com/confluence/rest/api/content/1234/child/comment?start=20&limit=10 - http://example.com/confluence/rest/api/content/1234/child/comment?location=footer&location=inline&location=resolved - http://example.com/confluence/rest/api/content/1234/child/comment?expand=extensions.inlineProperties,extensions.resolution
ContentsGet contents in space - Returns the content in this given space. Example request URI: http://example.com/confluence/rest/api/space/TEST/content?expand=history
ContentsWithTypeGet trash contents of space - Returns the trash contents in this given space. Example request URI: http://example.com/confluence/rest/api/space/TEST/trash?limit=100&cursor=content:false:612345
…161 more tools not shown

Virtual Tools

Compose native tools via a declarative pipeline DSL:

virtual_tools:
  - name: MyVirtualTool
    description: Chain multiple native tools together
    input_schema:
      type: object
      properties:
        appId: { type: string }
      required: [appId]
    pipeline:
      - id: getApp
        kind: call
        spec: { tool: GetApplication, args: { applicationId: "$input.appId" } }
      - id: appName
        kind: jq
        spec: { from: "$getApp", expr: .name }
      - id: done
        kind: return
        spec: { from: "$appName" }

Pipeline kinds: call, jq, foreach, emit, return.

Agent Integration

OpenCode

  • ~/.config/opencode/opencode.json:
{
  "mcp": {
    "confluence-mcp": {
      "type": "local",
      "command": ["bash", "-c", "/path/to/confluence-mcp"],
      "args": ["--transport", "stdio"],
      "env": {
        "MCP__UPSTREAM__DEFAULT__ENDPOINT": "https://api.example.com",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN": "your-token",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN_FILE": "/path/to/fallback/.credentials"
      },
      "enabled": true
    }
  }
}

Claude Code

  • ~/.claude.json:
{
  "mcpServers": {
    "confluence-mcp": {
      "command": "/path/to/confluence-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "MCP__UPSTREAM__DEFAULT__ENDPOINT": "https://api.example.com",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN": "your-token",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN_FILE": "/path/to/fallback/.credentials"
      }
    }
  }
}

Codex CLI

  • ~/.codex/config.toml:
[mcp_servers.confluence-mcp]
url = "http://localhost:8080/mcp"
web_token_env_var = "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN"

Cursor

  • ~/.cursor/mcp.json:
{
  "mcpServers": {
    "confluence-mcp": {
      "command": "/path/to/confluence-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "MCP__UPSTREAM__DEFAULT__ENDPOINT": "https://api.example.com",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN": "your-token",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN_FILE": "/path/to/fallback/.credentials"
      }
    }
  }
}

OpenCode (Remote)

  • ~/.config/opencode/opencode.json:
{
  "mcp": {
    "confluence-mcp": {
      "type": "remote",
      "url": "http://localhost:8080/mcp",
      "env": {
        "MCP__UPSTREAM__DEFAULT__ENDPOINT": "https://api.example.com",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN": "your-token",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN_FILE": "/path/to/fallback/.credentials"
      }
    }
  }
}

Claude Code (Remote)

  • ~/.claude.json (User MCPs):
{
  "mcpServers": {
    "confluence-mcp": {
      "url": "http://localhost:8080/mcp",
      "env": {
        "MCP__UPSTREAM__DEFAULT__ENDPOINT": "https://api.example.com",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN": "your-token",
        "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN_FILE": "/path/to/fallback/.credentials"
      }
    }
  }
}

Codex CLI (Remote)

  • ~/.codex/config.toml:
[mcp_servers.confluence-mcp]
url = "http://localhost:8080/mcp"
web_token_env_var = "MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN"

Cursor (Remote)

  • ~/.cursor/mcp.json:
{
  "mcpServers": {
    "confluence-mcp": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Deployment — Docker

Build

make build-image

Or manually:

docker build -t ghcr.io/<YOUR_ORG>/confluence-mcp:latest -f deploy/docker/Dockerfile .
docker push ghcr.io/<YOUR_ORG>/confluence-mcp:latest

Run

Pull the pre-built image from GitHub Container Registry:

docker pull ghcr.io/<YOUR_ORG>/confluence-mcp:latest

First generate a default config, then mount it when running:

  docker run --rm ghcr.io/<YOUR_ORG>/confluence-mcp:latest --print-default-config > ~/.confluence-mcp/config.yaml
  • Static web token
  docker run -d --name confluence-mcp \
    -p 8080:8080 -p 9991:9991 \
    -e MCP__UPSTREAM__DEFAULT__ENDPOINT="https://api.example.com" \
    -e MCP__UPSTREAM__DEFAULT__AUTH__STATIC__WEB_TOKEN="YOUR_WEB_TOKEN" \
    -v ~/.confluence-mcp:/home/mcp/.confluence-mcp \
    ghcr.io/<YOUR_ORG>/confluence-mcp:latest \
    --transport http --port 8080
  • OIDC upstream auth
  docker run -d --name confluence-mcp \
    -p 8080:8080 -p 9991:9991 \
    -e MCP__UPSTREAM__DEFAULT__ENDPOINT="https://api.example.com" \
    -e MCP__UPSTREAM__DEFAULT__AUTH__OIDC__ENABLED=true \
    -e MCP__UPSTREAM__DEFAULT__AUTH__OIDC__ISSUER="https://idp.example.com/realms/myrealm" \
    -e MCP__UPSTREAM__DEFAULT__AUTH__OIDC__CLIENT_ID="my-client" \
    -e MCP__UPSTREAM__DEFAULT__AUTH__OIDC__CLIENT_SECRET="YOUR_CLIENT_SECRET" \
    -v ~/.confluence-mcp:/home/mcp/.confluence-mcp \
    ghcr.io/<YOUR_ORG>/confluence-mcp:latest \
    --transport http --port 8080

Test with mcpclient.sh

After the container starts, use the bundled mcpclient.sh to verify.

Note: mcpclient.sh only supports upstream static token auth. If the server requires server OIDC authentication, use a real AI-agent MCP client instead.

# Point to the mapped host port (include /mcp path)
export MCP_SERVER_ENDPOINT=http://localhost:18080/mcp
# Call any tool (example: Add)
./mcpclient.sh call Add --param value
# List all available tools
./mcpclient.sh list-tools

Tip: Map the host config directory for persistent configuration: -v ~/.confluence-mcp:/home/mcp/.confluence-mcp

Deployment — Kubernetes (Helm)

First generate a default config, then mount it when running:

  docker run --rm ghcr.io/<YOUR_ORG>/confluence-mcp:latest --print-default-config > ~/.confluence-mcp/config.yaml
  • Static web token
  helm upgrade -i confluence-mcp deploy/helm \
    --set image.repository=ghcr.io/<YOUR_ORG>/confluence-mcp \
    --set image.tag=latest \
    --set secret.static.create=true \
    --set secret.static.webToken="YOUR_WEB_TOKEN" \
    --set config.upstream.default.endpoint="https://api.example.com"
  • OIDC authentication
  helm upgrade -i confluence-mcp deploy/helm \
    --set image.repository=ghcr.io/<YOUR_ORG>/confluence-mcp \
    --set image.tag=latest \
    --set secret.static.create=true \
    --set secret.static.oidcClientSecret="YOUR_OIDC_CLIENT_SECRET" \
    --set config.upstream.default.auth.oidc.enabled=true \
    --set config.upstream.default.auth.oidc.issuer="https://idp.example.com" \
    --set config.upstream.default.auth.oidc.client_id="my-client" \
    --set config.upstream.default.endpoint="https://api.example.com"

See deploy/helm/values.yaml for all configurable parameters.

Contributing

We welcome contributions! Here's how you can help:

  1. Fork the repository and create a feature branch
  2. Make your changes — add features, fix bugs, or improve documentation
  3. Add tests — every new feature or bug fix should include unit tests
  4. Run the test suite — make test must pass with no regressions
  5. Submit a Pull Request — describe what you changed and why

Development Setup

git clone https://github.com/<YOUR_ORG>/confluence-mcp.git
cd confluence-mcp
make build
make test-ut

Code Style

  • Follow standard Go conventions (go fmt, go vet)
  • Keep functions small and focused
  • Write clear commit messages

Please read CONTRIBUTING.md for detailed guidelines and our Code of Conduct.

License

This generated MCP server project is licensed under the Apache License 2.0 — see the LICENSE file for details.

The Apache-2.0 license is intentionally permissive for generated server output: commercial use, internal enterprise deployment, modification, redistribution, and proprietary integration are allowed subject to the Apache License 2.0 terms. This generated project is not subject to mcpfather's AGPL license obligations solely because it was generated by mcpfather.

Contact

For questions, suggestions, or support:

Acknowledgments

This MCP server was generated by MCPFather, an enterprise-grade OpenAPI-to-MCP code generator.

Built with these excellent open-source projects:

  • mcp-go — Go SDK for the Model Context Protocol
  • OpenTelemetry — observability framework for metrics and tracing
  • Prometheus — metrics collection and alerting
  • Viper — Go configuration management
  • go-jq — Pure Go implementation of jq
  • Keycloak — Open Source Identity and Access Management
↑↓ navigate openesc close