Skip to content

jaigouk/atlassian-mcp

Repository files navigation

Atlassian MCP Server

Search Jira and Confluence directly from your IDE — no browser needed.

Status: 416 tests passing | Hexagonal Architecture (DDD) | Jira v3 + Confluence v2


What Does This Do?

Talk to your AI assistant and get Atlassian data:

You: "What tickets are assigned to me?"
AI:  Shows your Jira tickets

You: "Find our deployment documentation"
AI:  Shows Confluence pages about deployment

Works with Cursor, Claude Code, or any MCP-compatible client.


Quick Start

1. Get Atlassian OAuth Credentials

  1. Go to https://developer.atlassian.com/console/myapps/
  2. Click Create > OAuth 2.0 integration
  3. Name it: MCP Server
  4. Callback URL: http://localhost:8084/auth/callback
  5. Add permissions:
    • Jira: read:jira-work, read:jira-user
    • Confluence: read:confluence-content.all, search:confluence, read:confluence-space.summary
  6. Copy your Client ID and Client Secret

2. Configure

cp env.example .env

Edit .env:

ATLASSIAN_SITE=yourcompany.atlassian.net   # no https://
OAUTH_CLIENT_ID=your_client_id
OAUTH_CLIENT_SECRET=your_client_secret

# Generate these:
TOKEN_ENCRYPTION_KEY=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
REDIS_PASSWORD=$(node -e "console.log(require('crypto').randomBytes(16).toString('hex'))")

3. Start

docker-compose up -d

4. Authenticate

open http://localhost:8084/auth/login

Click "Accept" when Atlassian asks for permission.

5. Connect Your IDE

Cursor — edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "atlassian": {
      "url": "http://localhost:8084/mcp",
      "type": "http"
    }
  }
}

Claude Code — edit ~/.claude/claude_desktop_config.json:

{
  "mcpServers": {
    "atlassian": {
      "url": "http://localhost:8084/mcp"
    }
  }
}

Restart your IDE after adding the config.

6. Test It

  • "What Jira tickets are assigned to me?"
  • "Find deployment documentation in Confluence"
  • "Show me ticket ENG-123"

Available Tools

Tool Description
search_jira Search Jira with JQL filters
get_jira_ticket Get full ticket details
list_my_tickets List your assigned tickets
search_confluence Search Confluence with CQL
get_confluence_page Get full page content

Architecture

                              MCP Protocol (HTTP)
  IDE / AI Client ──────────── http://localhost:8084/mcp
                                        │
  ┌─────────────────────────────────────┼─────────────────────────────┐
  │  Atlassian MCP Server               │                             │
  │                                     │                             │
  │  ┌──────────────┐   ┌───────────────┼────────────┐                │
  │  │ Domain       │   │ Application   │            │                │
  │  │              │   │               ▼            │                │
  │  │ Models       │◄──│ Use Cases (5)              │                │
  │  │ Services     │   │ Ports (interfaces)         │                │
  │  │ Value Objects│   │ DTOs (Zod validated)       │                │
  │  └──────────────┘   └──────────────┬─────────────┘                │
  │                                    │                              │
  │  ┌─────────────────────────────────┼────────────────────────────┐ │
  │  │ Infrastructure                  │                            │ │
  │  │                                 ▼                            │ │
  │  │ Adapters:  JiraRestAdapter, ConfluenceRestAdapter            │ │
  │  │ Auth:      OAuthAdapter, RedisTokenAdapter                   │ │
  │  │ Cache:     RedisCacheAdapter                                 │ │
  │  │ MCP:       McpToolRouter, toolDefinitions                    │ │
  │  │ Server:    Express routes, middleware                        │ │
  │  └──────┬──────────────┬───────────────────┬────────────────────┘ │
  └─────────┼──────────────┼───────────────────┼──────────────────────┘
            │              │                   │
   ┌────────▼────────┐ ┌──▼────────────┐ ┌────▼──────┐
   │ Jira REST API   │ │ Confluence    │ │ Redis     │
   │ v3 (search/JQL) │ │ v1 (search)   │ │ Cache +   │
   │                 │ │ v2 (pages)    │ │ Tokens    │
   └─────────────────┘ └───────────────┘ └───────────┘

Key design decisions:

  • Hexagonal / DDD — Domain has zero infrastructure imports. Application layer defines port interfaces. Infrastructure implements adapters.
  • Strangler Fig migration — Confluence v1 /content/{id} migrated to v2 /pages/{id}. v1 search (/content/search) stays (not deprecated).
  • ESLint enforced layer boundariesimport-x/no-restricted-paths prevents domain from importing infrastructure.
  • Composition Root — All wiring in compositionRoot.ts. Use cases receive ports via constructor injection.

Project Structure

src/
  domain/           # Models, value objects, domain services (zero deps)
  application/      # Use cases, ports (interfaces), DTOs
  infrastructure/   # Adapters (Atlassian, auth, cache, MCP, logging)
  server/           # Express routes, middleware, MCP setup
  services/         # REST clients, OAuth, token storage, cache
  common/           # Config, logger, shared errors
  compositionRoot.ts
  index.ts
tests/              # Mirrors src/ structure, 416 tests

Development

Run Without Docker

npm install
npm run build
npm run dev       # development mode with auto-reload
npm start         # production build

Tests

npm test                  # Run all 416 tests
npm run test:watch        # Watch mode
npm run test:coverage     # With coverage report

Code Quality

npm run lint              # ESLint with DDD boundary checks
npm run typecheck         # TypeScript strict mode
npm run validate          # All checks (lint + typecheck + test)

Configuration

Required (.env)

ATLASSIAN_SITE=yourcompany.atlassian.net    # no https://
OAUTH_CLIENT_ID=your_client_id
OAUTH_CLIENT_SECRET=your_client_secret
TOKEN_ENCRYPTION_KEY=<64-char hex string>   # node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
REDIS_PASSWORD=<random string>              # node -e "console.log(require('crypto').randomBytes(16).toString('hex'))"

Optional

PORT=8084                 # Server port
LOG_LEVEL=info            # error | warn | info | debug
CACHE_TTL=3600            # Cache TTL in seconds (default: 1 hour)
ENABLE_CACHE=true         # Redis caching

Docker Commands

docker-compose up -d                      # Start all services
docker-compose stop                       # Stop
docker-compose logs -f atlassian-mcp      # View logs
docker-compose build && docker-compose up -d  # Rebuild after code changes

Security

  • OAuth 2.1 tokens encrypted at rest via TOKEN_ENCRYPTION_KEY
  • Automatic token refresh on expiry
  • Redis authenticated with REDIS_PASSWORD (--requirepass)
  • Ports bound to 127.0.0.1 only (localhost)
  • Non-root container user (atlassian:1001)
  • Multi-stage Docker build (no build tools in production image)
  • No curl in production image (healthcheck uses Node.js native fetch)
  • .dockerignore excludes .env, .git, node_modules
  • All Atlassian permissions respected (read-only scopes)
  • Never commit .env to git

Troubleshooting

"Not authenticated" — Visit http://localhost:8084/auth/login and re-authorize.

Tools don't appear in IDE — Fully quit and restart your IDE (not just reload).

Server not starting — Check docker-compose logs -f atlassian-mcp and verify .env is configured.

Health check — Visit http://localhost:8084/health or http://localhost:8084/ready.


API References

About

MCP server for Jira and Confluence integration. Hexagonal/DDD architecture with OAuth 2.0, Redis caching, and Confluence v2 API support.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors