Outlook Semantic MCP - Local Development — Unique AI Documentation

Outlook Semantic MCP - Local Development

This guide walks through setting up the Outlook Semantic MCP Server for local development and testing.

Prerequisites

Requirement Version Purpose
Node.js 20+ Runtime
pnpm 9+ Package manager
Docker 24+ Run PostgreSQL and RabbitMQ
Azure CLI Latest Configure Entra app registration
MCP Inspector Latest MCP Client for testing

A public reverse proxy, recommended:

Quick Start

# Clone and install
git clone git@github.com:Unique-AG/connectors.git
cd services/outlook-semantic-mcp
pnpm install

# Configure environment (must come before docker compose — docker-compose.prod.yaml reads .env automatically)
cp .env.example .env
# Edit .env with your values (see below)

# Start infrastructure
docker compose -f docker-compose.prod.yaml up -d

# Run migrations
pnpm db:migrate

# Start development server
pnpm dev

The server starts at the configured port (default: 9542).

Infrastructure Setup

Docker Compose

The included docker-compose.prod.yaml provides PostgreSQL and RabbitMQ:

docker compose -f docker-compose.prod.yaml up -d
Service Credentials
PostgreSQL postgres:postgres
RabbitMQ rabbitmq:rabbitmq
RabbitMQ Management rabbitmq:rabbitmq

Microsoft Entra App Registration

You need a Microsoft Entra ID app registration for OAuth. See Authentication Setup for detailed instructions.

For local development, configure:

Setting Value
Redirect URI http://localhost:9542/auth/callback
Supported account types Your organization only

Environment Configuration

Create .env from the template:

cp .env.example .env

Required Variables

none

# Application
SELF_URL=http://localhost:9542
LOG_LEVEL=debug

# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/outlook_semantic_mcp

# RabbitMQ
AMQP_URL=amqp://rabbitmq:rabbitmq@localhost:5672

# Microsoft (from Entra app registration)
MICROSOFT_CLIENT_ID=<your-client-id>
MICROSOFT_CLIENT_SECRET=<your-client-secret>
MICROSOFT_WEBHOOK_SECRET=<generate-128-char-hex>
MICROSOFT_PUBLIC_WEBHOOK_URL=<your-tunnel-url>  # See webhook testing below

# Security (generate with: openssl rand -hex 32)
AUTH_HMAC_SECRET=<64-char-hex>
ENCRYPTION_KEY=<64-char-hex>

# Unique API (for local testing, use external mode)
UNIQUE_SERVICE_AUTH_MODE=external
UNIQUE_INGESTION_SERVICE_BASE_URL=http://localhost:8091
UNIQUE_SCOPE_MANAGEMENT_SERVICE_BASE_URL=http://localhost:8092
UNIQUE_ZITADEL_CLIENT_ID=<zitadel-client-id>
UNIQUE_ZITADEL_CLIENT_SECRET=<zitadel-client-secret>
UNIQUE_ZITADEL_OAUTH_TOKEN_URL=https://your-zitadel.zitadel.cloud/oauth/v2/token
UNIQUE_ZITADEL_PROJECT_ID=<zitadel-project-id>

Note on Unique API URLs: The http://localhost:8091 and http://localhost:8092 values assume a locally-running proxy that forwards to the Unique ingestion and scope management services. Replace these with your actual https://*.unique.app service URLs when testing against a real Unique tenant.

Generating Secrets

See Configuration — Required Secrets for the full format reference. Quick generation:

# For MICROSOFT_WEBHOOK_SECRET (128 chars)
openssl rand -hex 64

# For AUTH_HMAC_SECRET and ENCRYPTION_KEY (64 chars each)
openssl rand -hex 32

Webhook Testing

Microsoft Graph webhooks require a publicly accessible HTTPS endpoint. For local development, use Azure Dev Tunnels or any other HTTPS tunnel solution (e.g., ngrok, Cloudflare Tunnel):

Setup Dev Tunnel

# Install (macOS)
brew install azure-dev-tunnels

# Login
devtunnel user login

# Create persistent tunnel
devtunnel create outlook-semantic-mcp --allow-anonymous

# Start tunnel
devtunnel port create outlook-semantic-mcp -p 9542
devtunnel host outlook-semantic-mcp

Configure Environment

Set MICROSOFT_PUBLIC_WEBHOOK_URL to your tunnel URL:

MICROSOFT_PUBLIC_WEBHOOK_URL=https://abc123.devtunnels.ms

Microsoft Graph appends /mail-subscription/notification and /mail-subscription/lifecycle to this URL when delivering webhook events. It must be publicly reachable by Microsoft, which is why you need a tunnel URL locally instead of http://localhost:9542.

Development Workflow

Available Scripts

Script Description
pnpm dev Start with hot reload
pnpm build Build for production
pnpm debug Start with Node.js debugger
pnpm test Run unit tests
pnpm test:watch Run tests in watch mode
pnpm test:coverage Run tests with coverage
pnpm test:e2e Run end-to-end tests
pnpm test:e2e:watch Run end-to-end tests in watch mode
pnpm db:generate Generate migrations from schema changes
pnpm db:migrate Apply pending migrations
pnpm db:check Check migration consistency
pnpm style Check code style (Biome)
pnpm style:fix Fix code style issues
pnpm check-types TypeScript type checking

Testing the OAuth Flow

  1. Start the dev server: pnpm dev

  2. Open http://localhost:9542/.well-known/oauth-authorization-server

  3. You should see the OAuth metadata JSON

  4. Connect with MCP Inspector or another MCP client that supports OAuth

  5. After connecting, use verify_inbox_connection to check subscription status

Debugging

Common Issues

OAuth redirect mismatch:

Webhook not received:

Database connection error:

Emails not appearing in search: