# Teamlandkarte MCP Server — Copilot Instructions ## Project Overview This is a Python 3.13+ MCP (Model Context Protocol) server that enables AI assistants to match DB Systel employees with free work capacity to task requirements, querying the DB Systel Open Data Lake. - **Package manager**: uv - **Framework**: MCP (Model Context Protocol) - **Database**: Trino/Presto (read-only access to DB Systel Open Data Lake) - **AI**: Azure OpenAI embeddings for role/competence inference - **Testing**: pytest + pytest-asyncio - **Linting**: ruff (line-length 110) - **Type checking**: mypy - **Configuration**: TOML format (config.toml), credentials via .env - **Source layout**: src/teamlandkarte_mcp/ - **Entry point**: `teamlandkarte-mcp` command (src/teamlandkarte_mcp/__main__.py) ## Commands - **Run server**: `uv run teamlandkarte-mcp --config config.toml` - **Run tests**: `uv run pytest` - **Lint**: `uv run ruff check src/ tests/` - **Format**: `uv run ruff format src/ tests/` - **Type check**: `uv run mypy src/` - **Install deps**: `uv sync` ## Project Structure ``` src/teamlandkarte_mcp/ ├── __main__.py # CLI entry point ├── mcp_server.py # MCP server + tool definitions ├── config.py # Configuration management (TOML) ├── models.py # Data models ├── logging_config.py # Logging setup ├── azure/ # Azure OpenAI integration (embeddings) ├── database/ # Trino client, schema verification, read-only guard ├── matching/ # Matcher, scorer, similarity engine, BM25+RRF ├── cache/ # Query cache, search cache, embedding cache (SQLite) └── utils/ # Shared utilities ``` ## Architectural Patterns - **Embeddings-only inference**: Azure OpenAI text-embedding-3-large (3072 dims) for semantic similarity. No chat/LLM unless `use_auto_tagging = true`. - **Table-first Markdown output**: All MCP tool outputs use Markdown tables. - **Confirmation gate**: Hard gate before matching runs (show → ask → confirm). - **Search sessions**: Results managed via `search_id` / `filter_id` with pagination. - **Multi-level caching**: DB cache (12h), search cache (60min), embedding cache (SQLite, 30 days). - **Read-only database**: Never write to Trino. Schema verification at startup. ## Security Rules 1. Credentials in env vars only — never in config.toml, code, or outputs. 2. Read-only DB — never attempt writes to Trino. 3. Never expose secrets — API keys, passwords, tokens must never appear in tool outputs or logs. 4. `.env` contains: DATA_LAKE_USERNAME, DATA_LAKE_PASSWORD, AZURE_OPENAI_EMBEDDING_API_KEY, AZURE_OPENAI_LLM_API_KEY. ## Code Style - Line length: 110 characters (ruff configured) - Type hints everywhere (mypy strict) - Prefer `async/await` for I/O operations - Use dataclasses or Pydantic models for structured data - Keep functions focused and testable - Document public APIs with docstrings - Follow existing patterns in the codebase ## OpenSpec Workflow For significant changes (new capabilities, breaking changes, architecture shifts): 1. Check existing specs: `openspec spec list --long` 2. Create a proposal in `openspec/changes//` 3. Validate: `openspec validate --strict` 4. Get approval before implementing Read `openspec/AGENTS.md` for full workflow details.