# @phoenix-erp/mcp

MCP server for Phoenix ERP — AI-powered documentation with **dev-guide** and **user-guide** collections. Provides full-text fuzzy search, 7 tools, 5 prompts, and MCP resources.

## Features

- **Two knowledge collections**: `dev-guide` and `user-guide` (embedded at build; optional YouTrack refresh from General hierarchy)
- **Hybrid search**: lexical (MiniSearch, fuzzy, prefix) + semantic (embeddings) with RRF fusion
- **7 tools**: `search_docs`, `get_section`, `list_documents`, `list_sections`, `get_code_examples`, `get_architecture`, `get_file_map`
- **5 prompts**: `onboard_developer`, `implement_feature`, `review_code`, `explain_feature`, `support_answer`
- **Resources**: `erp://docs`, `erp://dev-guide/{slug}`, `erp://user-guide/{slug}`
- **Transports**: stdio (primary) and HTTP

## Authentication

**PHX_MCP_TOKEN is required** — the MCP will not work without it.

**Quick start:** Run `pnpm run generate-token` to auto-generate a token and add it to `.env`.

Then add it to your MCP config (see examples below) or set it in your environment.

## Installation

### From npm (after publishing)

```bash
npx -y @phoenix-erp/mcp
```

### IDE configuration

#### Cursor

Add to `.cursor/mcp.json` (project or user). **PHX_MCP_TOKEN is required** in `env`:

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "command": "npx",
      "args": ["-y", "@phoenix-erp/mcp"],
      "env": {
        "PHX_MCP_TOKEN": "your-phx-mcp-token"
      }
    }
  }
}
```

#### VS Code (MCP extension)

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "command": "npx",
      "args": ["-y", "@phoenix-erp/mcp"],
      "env": {
        "PHX_MCP_TOKEN": "your-phx-mcp-token"
      }
    }
  }
}
```

#### Claude Code

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "command": "npx",
      "args": ["-y", "@phoenix-erp/mcp"]
    }
  }
}
```

#### Windsurf

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "command": "npx",
      "args": ["-y", "@phoenix-erp/mcp"]
    }
  }
}
```

#### Zed

Add the same `mcpServers` block to your MCP config file.

## Tools

| Tool | Description | Parameters |
|------|-------------|------------|
| `search_docs` | Hybrid search (lexical + semantic) across ERP docs | `query`, `category?`, `limit?`, `fuzzy?`, `mode?` (`lexical` \| `semantic` \| `hybrid`) |
| `get_section` | Get a section by document slug and path | `document`, `section_path` |
| `list_documents` | List all docs, optionally by category | `category?` |
| `list_sections` | Table of contents for a document | `document`, `max_depth?` |
| `get_code_examples` | Find code examples by topic | `query`, `language?`, `category?` |
| `get_architecture` | Architecture info, mermaid diagrams | `topic` |
| `get_file_map` | File structure for a module | `document`, `section?` |

## Prompts

| Prompt | Description | Args |
|--------|-------------|------|
| `onboard_developer` | Step-by-step setup (clone, env, Docker) plus module brief | `module` |
| `implement_feature` | Implementation guide | `feature_description` |
| `review_code` | Code review checklist | `code_context` |
| `explain_feature` | User-facing feature explanation | `feature_name` |
| `support_answer` | Draft support response | `user_question` |

**Using prompts in Cursor**: Open the Prompts panel (via `@` or the prompts menu) and select the prompt (e.g. "Onboard Developer"), then fill in the argument (e.g. `module: backup`). Or ask in chat: *"Use the onboard_developer prompt with module backup"* — the AI should invoke the MCP prompt to get the full env templates and docker-compose content.

## Resources

| URI | Description |
|-----|-------------|
| `erp://docs` | List of all documents |
| `erp://dev-guide/{slug}` | Full dev-guide document |
| `erp://user-guide/{slug}` | Full user-guide document |

## Adding Documentation

1. **Dev-guide**: Drop `.md` files into `knowledge/dev-guides/`
2. **User-guide**: Drop `.md` files into `knowledge/user-guides/`
3. Run `pnpm run build` to embed docs into the bundle

**Note**: `build` and `build:docs` require `YOUTRACK_TOKEN` — setup templates (dev-server .env, core .env, docker-compose) are fetched from YouTrack articles INT-A-223, INT-A-224, INT-A-225.

## YouTrack Integration - General Article Sync

Articles are fetched from the **General** root article (INT-A-7) and its child folders `dev-guide` and `user-guide`. Both collections can be refreshed from YouTrack at runtime or synced to disk.

**Hierarchy**: General (INT-A-7) > dev-guide | user-guide > articles

**Runtime refresh** (when `YOUTRACK_TOKEN` is set):

- At server startup, fetches articles from YouTrack and merges them into the in-memory knowledge base
- Replaces embedded docs for both dev-guide and user-guide when YouTrack provides matching articles

**Sync to disk**:

```bash
YOUTRACK_TOKEN=perm:xxx pnpm run sync:youtrack
```

This writes articles to `knowledge/dev-guides/` and `knowledge/user-guides/`. Run `pnpm run build` afterward to embed and re-index.

| Env var | Default | Purpose |
| ------- | ------- | ------- |
| `YOUTRACK_TOKEN` | (required) | Bearer token for YouTrack API (required for build/sync) |
| `YOUTRACK_BASE_URL` | `https://phx-erp.youtrack.cloud` | YouTrack instance URL |
| `YOUTRACK_ROOT_ARTICLE` | `INT-A-7` | Root article idReadable (General) |
| `YOUTRACK_DEV_GUIDE_KEY` | `dev-guide` | Parent folder identifier (summary match) |
| `YOUTRACK_USER_GUIDE_KEY` | `user-guide` | Same for user-guide |
| `YOUTRACK_DEV_SERVER_ENV_ARTICLE` | `INT-A-223` | Article for dev-server .env template (onboard_developer) |
| `YOUTRACK_CORE_ENV_ARTICLE` | `INT-A-224` | Article for core .env template |
| `YOUTRACK_DOCKER_COMPOSE_ARTICLE` | `INT-A-225` | Article for docker-compose.yaml template |

Example MCP config:

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "command": "npx",
      "args": ["-y", "@phoenix-erp/mcp"],
      "env": {
        "PHX_MCP_TOKEN": "your-phx-mcp-token",
        "YOUTRACK_TOKEN": "perm:your-token"
      }
    }
  }
}
```

## Semantic Search

Search uses **hybrid retrieval** by default: lexical (MiniSearch) + semantic (embeddings) with Reciprocal Rank Fusion.

- **Default (Option A)**: Xenova/all-MiniLM-L6-v2 for embeddings. Pre-computed at build time, no API keys.
- **Option B**: Set `OPENAI_API_KEY` or `COHERE_API_KEY` to use that API for query embedding. Requires building with `EMBED_WITH_OPENAI=1` or `EMBED_WITH_COHERE=1` for matching document embeddings.

| Env var | When | Purpose |
|---------|------|---------|
| `EMBEDDING_PROVIDER` | Runtime | Override: `xenova` \| `openai` \| `cohere` |
| `OPENAI_API_KEY` | Runtime | Use OpenAI for query embedding |
| `COHERE_API_KEY` | Runtime | Use Cohere for query embedding |
| `EMBED_WITH_OPENAI` | Build | `1` = also compute OpenAI doc embeddings |
| `EMBED_WITH_COHERE` | Build | `1` = also compute Cohere doc embeddings |

## HTTP Mode

Run the server over HTTP instead of stdio:

```bash
PHX_MCP_TOKEN=your-token npx -y @phoenix-erp/mcp --http
```

- Default port: `3100` (override with `PHX_MCP_PORT`)
- MCP endpoint: `http://localhost:3100/mcp`
- Health check: `http://localhost:3100/health`

**Client config** (Cursor `streamableHttp` with Bearer token):

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "type": "streamableHttp",
      "url": "http://localhost:3100/mcp",
      "headers": {
        "Authorization": "Bearer your-phx-mcp-token"
      }
    }
  }
}
```

## Development

```bash
pnpm install
pnpm run generate-token  # Generate PHX_MCP_TOKEN and add to .env
pnpm run build:docs      # Generate embedded-docs.ts + embedded-embeddings.ts
pnpm run build           # Build dist/
pnpm run dev             # Run stdio mode via tsx (requires PHX_MCP_TOKEN in env)
pnpm run dev:http        # Run HTTP mode via tsx
pnpm run sync:youtrack   # Export YouTrack articles to knowledge/dev-guides/ and knowledge/user-guides/
```

### Local Cursor config

Before publishing, use a local config:

```json
{
  "mcpServers": {
    "phoenix-erp": {
      "command": "node",
      "args": ["dist/index.js"],
      "cwd": "/path/to/phx-mcp",
      "env": {
        "PHX_MCP_TOKEN": "your-phx-mcp-token",
        "YOUTRACK_TOKEN": "perm:..."
      }
    }
  }
}
```

## Publishing

**Automated (recommended):**

```bash
pnpm run publish:script        # bump patch (default)
pnpm run publish:patch        # same
pnpm run publish:minor        # bump minor
pnpm run publish:major        # bump major
```

The script runs tests, syncs YouTrack articles, builds, bumps the version, and publishes. Git working directory must be clean. **YOUTRACK_TOKEN is required** for publish (set in `.env` or pass inline).

```bash
pnpm run publish:script
```

Or with inline token: `YOUTRACK_TOKEN=perm:xxx pnpm run publish:script`

**Manual:**

```bash
pnpm version patch
pnpm publish
```
