Skip to main content
Glama
README.md
# PurpleTrack β€” JiraMock

A self-hosted Jira clone designed for testing MCP (Model Context Protocol) integrations on Azure. Ships with a REST API, MCP server, and purple web frontend β€” all in Docker.

---

## πŸš€ Quick Start (Azure VM)

```bash
# 1. Clone the repo on your VM
git clone https://github.com/YOUR_ORG/jira-clone.git
cd jira-clone

# 2. Build and launch
docker compose up -d --build

# 3. Access
#   Frontend:  http://<VM_IP>:3000
#   API:       http://<VM_IP>:8000
#   API Docs:  http://<VM_IP>:8000/docs
```

> **Azure NSG**: Open inbound ports **3000** (frontend) and **8000** (API) in your Network Security Group.

---

## πŸ—οΈ Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               Docker Network            β”‚
β”‚                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Frontend β”‚    β”‚    Backend       β”‚  β”‚
β”‚  β”‚  nginx   │───▢│  FastAPI + JSON  β”‚  β”‚
β”‚  β”‚  :3000   β”‚    β”‚    DB  :8000     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                         β–²               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚               β”‚
β”‚  β”‚   MCP Server     β”‚β”€β”€β”€β”˜               β”‚
β”‚  β”‚  (stdio/Python)  β”‚                   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

---

## πŸ“‘ REST API

The API mirrors Jira's REST API v3 structure. All endpoints at `/rest/api/3/`.

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/rest/api/3/project` | List all projects |
| POST | `/rest/api/3/project` | Create project |
| GET | `/rest/api/3/project/{key}` | Get project |
| DELETE | `/rest/api/3/project/{key}` | Delete project |
| GET | `/rest/api/3/issue` | List/filter issues |
| POST | `/rest/api/3/issue` | Create issue |
| GET | `/rest/api/3/issue/{key}` | Get issue + comments |
| PUT | `/rest/api/3/issue/{key}` | Update issue |
| DELETE | `/rest/api/3/issue/{key}` | Delete issue |
| POST | `/rest/api/3/issue/{key}/transitions` | Move status |
| GET | `/rest/api/3/issue/{key}/comment` | List comments |
| POST | `/rest/api/3/issue/{key}/comment` | Add comment |
| GET | `/rest/api/3/search?jql=...` | JQL search |
| GET | `/rest/api/3/users` | List users |
| GET | `/rest/api/3/stats` | Dashboard stats |

Full interactive docs at `http://<host>:8000/docs`

---

## πŸ€– MCP Server

### Tools Available

| Tool | Description |
|------|-------------|
| `list_projects` | List all projects |
| `create_project` | Create a project |
| `get_project` | Get project details |
| `delete_project` | Delete a project |
| `list_issues` | List/filter issues |
| `create_issue` | Create an issue |
| `get_issue` | Get issue + comments |
| `update_issue` | Update issue fields |
| `delete_issue` | Delete an issue |
| `transition_issue` | Change issue status |
| `add_comment` | Comment on an issue |
| `list_comments` | List issue comments |
| `list_users` | List available users |
| `search_issues` | JQL search |
| `get_stats` | Dashboard statistics |

### Claude Desktop Config

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "jiramock": {
      "command": "docker",
      "args": [
        "exec", "-i", "jiramock-mcp",
        "python", "server.py"
      ],
      "env": {
        "JIRA_BASE_URL": "http://backend:8000"
      }
    }
  }
}
```

### Azure AI Foundry / HTTP MCP config

If your MCP client supports HTTP transport, point it at:
```
http://<VM_IP>:8000
```
and use the REST endpoints directly, or wrap the MCP server behind an SSE/HTTP proxy.

---

## πŸ“ Project Structure

```
jira-clone/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ main.py           # FastAPI application
β”‚   β”œβ”€β”€ requirements.txt
β”‚   └── Dockerfile
β”œβ”€β”€ mcp-server/
β”‚   β”œβ”€β”€ server.py         # MCP server (stdio transport)
β”‚   β”œβ”€β”€ requirements.txt
β”‚   └── Dockerfile
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ index.html        # Purple web UI
β”‚   └── Dockerfile
β”œβ”€β”€ nginx/
β”‚   └── default.conf      # Reverse proxy config
β”œβ”€β”€ docker-compose.yml
└── README.md
```

---

## πŸ”§ Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| `JIRA_BASE_URL` | `http://backend:8000` | MCP server β†’ backend URL |

Data is persisted in a Docker volume (`jiramock-data`) at `/data/db.json`.

---

## πŸ›‘ Management

```bash
# Stop
docker compose down

# Stop and wipe data
docker compose down -v

# Logs
docker compose logs -f backend
docker compose logs -f mcp-server

# Rebuild after changes
docker compose up -d --build
```

---

## πŸ” Migrating to Real Jira

When ready to swap to real Jira:
1. Replace `JIRA_BASE_URL` with your Jira instance URL
2. Add `JIRA_API_TOKEN` and `JIRA_USER` env vars to the MCP server
3. Update `server.py` to use basic auth: `httpx.AsyncClient(auth=(user, token))`

The MCP tool interface remains identical β€” no changes to your Claude prompts or Azure Foundry config.