Atlassian MCP Server
by jaigouk
README.md
# 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
```bash
cp env.example .env
```
Edit `.env`:
```bash
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
```bash
docker-compose up -d
```
### 4. Authenticate
```bash
open http://localhost:8084/auth/login
```
Click "Accept" when Atlassian asks for permission.
### 5. Connect Your IDE
**Cursor** — edit `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"atlassian": {
"url": "http://localhost:8084/mcp",
"type": "http"
}
}
}
```
**Claude Code** — edit `~/.claude/claude_desktop_config.json`:
```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 boundaries** — `import-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
```bash
npm install
npm run build
npm run dev # development mode with auto-reload
npm start # production build
```
### Tests
```bash
npm test # Run all 416 tests
npm run test:watch # Watch mode
npm run test:coverage # With coverage report
```
### Code Quality
```bash
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`)
```bash
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
```bash
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
```bash
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
- [Jira REST API v3](https://developer.atlassian.com/cloud/jira/platform/rest/v3/)
- [Confluence REST API v2](https://developer.atlassian.com/cloud/confluence/rest/v2/)
- [MCP Protocol](https://modelcontextprotocol.io/)
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues