Skip to main content
Glama
architecture.md54.2 kB
# Software Architecture Design: SSO MCP Server **Version**: 1.3 | **Date**: 2025-12-15 | **Status**: Draft **Prepared by**: Architecture Team | **Reviewed by**: Technical Lead --- ## Document Control | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0 | 2025-12-11 | Architecture Team | Initial architecture design | | 1.1 | 2025-12-11 | Architecture Team | Align with spec clarifications: token refresh in Auth Manager | | 1.2 | 2025-12-13 | Architecture Team | Add Process Query feature (003-process-query) | | 1.3 | 2025-12-15 | Architecture Team | Update title and overview to reflect multi-function server | **Related Documents**: - Ground Rules: `memory/ground-rules.md` - Feature Specifications: - `specs/001-mcp-sso-checklist/spec.md` - MCP SSO Checklist Server - `specs/003-process-query/spec.md` - Process Query feature - Implementation Plans: `specs/001-mcp-sso-checklist/design.md` (created after this document) --- ## Executive Summary **Purpose**: The SSO MCP Server is a local Model Context Protocol (MCP) server that provides development tools and resources to AI coding assistants (GitHub Copilot, Claude Code) with secure Azure Entra ID single sign-on authentication. Current capabilities include: - **Development Checklists**: Quality standards and verification items for code reviews, architecture, and design - **Process Documentation**: Step-by-step procedures for development workflows (deployments, incident response, code reviews) - **Extensible Design**: Architecture supports adding new resource types and tools The server enables developers to access organizational quality standards, development procedures, and other resources directly within their AI-assisted development workflow. **Scope**: This architecture covers the MCP server application, authentication flow, checklist and process document storage and retrieval, and integration with AI assistant clients. It does not cover the development of the checklists/processes themselves or the internal workings of the AI assistants. **Key Architectural Decisions**: - Single-process Python application following MCP specification for simplicity and portability - HTTP Streamable transport as the default MCP protocol for better network flexibility - OAuth 2.0 Authorization Code flow with PKCE for secure browser-based SSO authentication - Local file system storage for checklists and processes with YAML frontmatter metadata - Secure local token persistence for seamless session resumption - Shared architecture pattern for checklists and processes (parallel module design) **Target Audience**: Software architects, developers, DevOps engineers, and stakeholders involved in implementing and deploying the MCP server. --- ## Table of Contents 1. [Introduction](#1-introduction) 2. [Architectural Drivers](#2-architectural-drivers) 3. [System Context View](#3-system-context-view) 4. [Container View](#4-container-view) 5. [Component View](#5-component-view) 6. [Code View](#6-code-view) 7. [Deployment View](#7-deployment-view) 8. [Architecture Decisions](#8-architecture-decisions) 9. [Quality Attributes](#9-quality-attributes) 10. [Risks & Technical Debt](#10-risks--technical-debt) 11. [Appendices](#11-appendices) --- ## 1. Introduction ### 1.1 Purpose This document describes the software architecture for the SSO MCP Checklist Server. It provides a comprehensive view of the system's structure, components, and design decisions to guide development teams and stakeholders in building a secure, maintainable MCP server. ### 1.2 Scope **In Scope**: - MCP server implementation following the Model Context Protocol specification - Azure Entra ID OAuth 2.0 authentication flow with PKCE - Checklist storage, discovery, and retrieval mechanisms - Process document storage, discovery, search, and retrieval mechanisms - Integration configuration for VSCode GitHub Copilot and Claude Code - Local token persistence and session management **Out of Scope**: - Checklist/process content creation and management (read-only access) - Azure App Registration setup (assumed pre-configured) - AI assistant internal implementations - Multi-tenant or enterprise deployment scenarios ### 1.3 Architectural Approach This architecture follows a modular single-process application pattern optimized for local CLI execution with external service integration. **Key Principles**: 1. **Simplicity over complexity** - Single Python process, minimal dependencies 2. **Security by design** - OAuth 2.0 with PKCE, secure token storage 3. **Standards compliance** - Full MCP specification adherence 4. **Separation of concerns** - Distinct modules for auth, MCP, and checklist handling 5. **Developer experience** - Seamless authentication, minimal configuration ### 1.4 Definitions, Acronyms, and Abbreviations | Term | Definition | |------|------------| | MCP | Model Context Protocol - Anthropic's protocol for AI assistant tool integration | | HTTP Streamable | MCP transport protocol using HTTP with Server-Sent Events for streaming | | SSE | Server-Sent Events - HTTP-based protocol for server-to-client streaming | | SSO | Single Sign-On - Authentication allowing one login for multiple services | | PKCE | Proof Key for Code Exchange - OAuth 2.0 extension for public clients | | Azure Entra ID | Microsoft's cloud identity service (formerly Azure AD) | | Tool | MCP concept for a callable function exposed by an MCP server | | YAML Frontmatter | Metadata block at the start of a markdown file | | Process | A development procedure document containing steps, guidelines, or workflows | | Checklist | A quality standard document containing items to verify during development | --- ## 2. Architectural Drivers ### 2.1 Stakeholders and Concerns | Stakeholder | Role | Key Concerns | |-------------|------|--------------| | Developers | End users | Easy setup, seamless authentication, fast checklist access | | Security Team | Compliance | Secure authentication, no credential storage, audit capability | | Development Team | Implementation | Clean code, testability, maintainability | | Operations | Support | Easy troubleshooting, clear error messages | | Organization | Governance | Enforce quality standards through accessible checklists | ### 2.2 Business Goals 1. **BG-001**: Enable developers to access quality checklists within their AI assistant workflow 2. **BG-002**: Enforce organizational authentication for checklist and process access 3. **BG-003**: Minimize friction in developer daily workflow (< 30 second auth) 4. **BG-004**: Support both VSCode GitHub Copilot and Claude Code environments 5. **BG-005**: Enable developers to query development process documentation through AI assistants ### 2.3 Quality Attribute Requirements #### 2.3.1 Performance - **PE-001**: Server MUST start and be ready for authentication within 5 seconds - **PE-002**: Checklist retrieval MUST complete within 2 seconds - **PE-003**: List checklists operation MUST complete within 1 second - **PE-004**: Process retrieval MUST complete within 2 seconds - **PE-005**: List processes operation MUST complete within 1 second - **PE-006**: Process search MUST complete within 3 seconds for up to 100 process files #### 2.3.2 Scalability - **SC-001**: System is designed for single-user local operation (no multi-user scaling required) - **SC-002**: System MUST support unlimited number of checklist files - **SC-003**: System MUST support unlimited number of process files (recommended: up to 100 for optimal search performance) #### 2.3.3 Availability & Reliability - **AV-001**: System MUST maintain authenticated sessions for 8+ hours without re-authentication - **AV-002**: System MUST gracefully handle Azure Entra ID service unavailability - **AV-003**: System MUST recover session from persisted tokens on restart #### 2.3.4 Security - **SE-001**: System MUST authenticate users via Azure Entra ID OAuth 2.0 with PKCE - **SE-002**: System MUST NOT store user passwords - **SE-003**: System MUST securely persist authentication tokens locally - **SE-004**: System MUST handle token refresh automatically when less than 5 minutes remaining #### 2.3.5 Maintainability - **MA-001**: Code MUST follow project ground rules (clean code, test-first, code review) - **MA-002**: Code coverage MUST exceed 80% for critical authentication and MCP paths - **MA-003**: All public APIs MUST have clear documentation #### 2.3.6 Usability - **US-001**: Authentication flow MUST use familiar browser-based SSO experience - **US-002**: Error messages MUST provide actionable guidance - **US-003**: Configuration MUST be achievable within 5 minutes using documentation #### 2.3.7 Observability - **OB-001**: System MUST provide structured logging for troubleshooting - **OB-002**: System MUST log authentication events (success, failure, token refresh) - **OB-003**: System MUST log MCP tool invocations ### 2.4 Constraints **Technical Constraints**: - **TC-001**: MUST use Python with uv package manager as specified - **TC-002**: MUST implement latest stable MCP specification - **TC-003**: MUST use latest stable MCP Python library - **TC-004**: MUST run as local process (not remote server) **Organizational Constraints**: - **OC-001**: MUST follow project ground rules for code quality - **OC-002**: MUST use Azure Entra ID for authentication (organizational standard) **Business Constraints**: - **BC-001**: Read-only access to checklists (no editing capability) - **BC-002**: Single-tenant support (organization's Azure tenant only) ### 2.5 Assumptions and Dependencies **Assumptions**: - **AS-001**: Users have valid Azure Entra ID accounts in the organization's tenant - **AS-002**: Azure App Registration is pre-configured for this application - **AS-003**: Users have VSCode with GitHub Copilot or Claude Code installed - **AS-004**: Network connectivity to Azure authentication services is available **Dependencies**: - **DE-001**: Azure Entra ID for OAuth 2.0 authentication - **DE-002**: MCP Python SDK for protocol implementation - **DE-003**: MSAL (Microsoft Authentication Library) for Azure authentication - **DE-004**: Local file system for checklist storage and token persistence --- ## 3. System Context View ### 3.1 Context Diagram ```mermaid graph TB subgraph "Development Environment" Dev[Developer] VSCode[VSCode + GitHub Copilot] Claude[Claude Code] end subgraph "MCP Server" Server[SSO MCP Checklist Server] end subgraph "External Services" Azure[Azure Entra ID] end subgraph "Local Resources" Checklists[Checklist Files<br/>*.md] Processes[Process Files<br/>*.md] Tokens[Token Cache<br/>Encrypted] end Dev -->|Uses| VSCode Dev -->|Uses| Claude VSCode -->|MCP Protocol| Server Claude -->|MCP Protocol| Server Server -->|OAuth 2.0 + PKCE| Azure Server -->|Reads| Checklists Server -->|Reads| Processes Server -->|Persists/Reads| Tokens Dev -->|Browser SSO| Azure ``` ### 3.2 Context Description **System**: SSO MCP Checklist Server The SSO MCP Checklist Server acts as a bridge between AI coding assistants and organizational development checklists and process documentation. It authenticates developers via Azure Entra ID SSO and exposes checklist and process content through the Model Context Protocol, enabling AI assistants to provide contextual quality guidance and procedural information during development. **Users and External Systems**: | Actor/System | Type | Description | Interaction | |--------------|------|-------------|-------------| | Developer | User | Software developer using AI assistants | Authenticates via browser, uses checklists/processes via AI | | VSCode + GitHub Copilot | Client | AI coding assistant in VSCode | Invokes MCP tools to retrieve checklists and processes | | Claude Code | Client | Anthropic's CLI AI assistant | Invokes MCP tools to retrieve checklists and processes | | Azure Entra ID | External Service | Microsoft identity platform | Handles OAuth 2.0 authentication | | Checklist Files | Local Resource | Markdown files with YAML frontmatter | Stores checklist content and metadata | | Process Files | Local Resource | Markdown files with YAML frontmatter | Stores development process documentation | | Token Cache | Local Resource | Encrypted token storage | Persists authentication tokens | ### 3.3 System Responsibilities **What the system does**: - Authenticates users via Azure Entra ID SSO (browser-based OAuth 2.0 + PKCE) - Exposes MCP tools for checklist retrieval and discovery - Exposes MCP tools for process retrieval, listing, and search - Reads and parses checklist and process markdown files with YAML frontmatter - Maintains authenticated sessions with automatic token refresh - Persists tokens for seamless session resumption **What the system does NOT do** (delegated to external systems): - User credential storage (handled by Azure Entra ID) - AI response generation (handled by AI assistants) - Checklist/process content creation or editing (out of scope) - Multi-user access control (single-user local operation) --- ## 4. Container View ### 4.1 Container Diagram ```mermaid graph TB subgraph "AI Assistant Clients" Copilot[GitHub Copilot<br/>VSCode Extension] ClaudeCode[Claude Code<br/>CLI Tool] end subgraph "SSO MCP Checklist Server Process" MCPServer[MCP Server<br/>Python + mcp-python-sdk<br/>HTTP Streamable transport] AuthModule[Auth Module<br/>MSAL + OAuth 2.0] ChecklistModule[Checklist Module<br/>File Reader + YAML Parser] ProcessModule[Process Module<br/>File Reader + YAML Parser + Search] end subgraph "External" Azure[Azure Entra ID<br/>OAuth 2.0 Provider] Browser[System Browser<br/>SSO Login UI] end subgraph "Local Storage" ChecklistDir[Checklists Directory<br/>*.md files] ProcessDir[Processes Directory<br/>*.md files] TokenCache[Token Cache<br/>~/.sso-mcp-server/tokens] end Copilot -->|HTTP + SSE| MCPServer ClaudeCode -->|HTTP + SSE| MCPServer MCPServer --> AuthModule MCPServer --> ChecklistModule MCPServer --> ProcessModule AuthModule -->|HTTPS| Azure AuthModule -->|Opens| Browser AuthModule -->|Read/Write| TokenCache ChecklistModule -->|Read| ChecklistDir ProcessModule -->|Read| ProcessDir Browser -->|OAuth Redirect| AuthModule ``` ### 4.2 Container Descriptions #### Container 1: MCP Server - **Technology**: Python 3.11+, mcp-python-sdk (latest stable) - **Purpose**: Implements MCP protocol and coordinates authentication and checklist access - **Responsibilities**: - Handles MCP protocol communication via HTTP Streamable transport - Listens on configurable local port for HTTP requests - Supports Server-Sent Events (SSE) for streaming responses - Routes tool calls to appropriate handlers - Manages server lifecycle and initialization - Enforces authentication before tool execution - **Communication**: - Receives MCP messages from AI clients via HTTP POST requests - Sends MCP responses via HTTP with SSE for streaming - Delegates to Auth Module and Checklist Module #### Container 2: Auth Module - **Technology**: Python, MSAL (Microsoft Authentication Library) - **Purpose**: Handles Azure Entra ID OAuth 2.0 authentication with PKCE - **Responsibilities**: - Initiates browser-based OAuth 2.0 Authorization Code flow - Handles OAuth callback and token exchange - Manages token lifecycle (storage, refresh, validation) - Provides authentication status to MCP Server - **Communication**: - HTTPS requests to Azure Entra ID endpoints - Opens system browser for SSO login - Reads/writes encrypted token cache #### Container 3: Checklist Module - **Technology**: Python, PyYAML or frontmatter library - **Purpose**: Reads and parses checklist markdown files - **Responsibilities**: - Discovers checklist files in configured directory - Parses YAML frontmatter for metadata (name, description) - Returns checklist content in AI-consumable format - Handles file read errors gracefully - **Communication**: - Reads markdown files from local file system #### Container 4: Process Module - **Technology**: Python, PyYAML or frontmatter library - **Purpose**: Reads, parses, and searches process documentation markdown files - **Responsibilities**: - Discovers process files in configured directory (separate from checklists) - Parses YAML frontmatter for metadata (name, description) - Returns process content in AI-consumable format - Provides keyword search across process name, description, and content - Ranks search results by relevance (title matches higher than content matches) - Handles file read errors gracefully - **Communication**: - Reads markdown files from local file system ### 4.3 Inter-Container Communication | From Container | To Container | Protocol | Purpose | Data Format | |----------------|--------------|----------|---------|-------------| | AI Clients | MCP Server | HTTP + SSE | Tool invocations | JSON-RPC over HTTP | | MCP Server | Auth Module | Function call | Auth status/trigger | Python objects | | MCP Server | Checklist Module | Function call | Checklist retrieval | Python objects | | MCP Server | Process Module | Function call | Process retrieval/search | Python objects | | Auth Module | Azure Entra ID | HTTPS | OAuth 2.0 flow | JSON | | Auth Module | Token Cache | File I/O | Token persistence | Encrypted JSON | | Checklist Module | Checklist Dir | File I/O | Read checklists | Markdown + YAML | | Process Module | Process Dir | File I/O | Read processes | Markdown + YAML | --- ## 5. Component View ### 5.1 MCP Server Component Diagram ```mermaid graph TB subgraph "MCP Server Module" Server[Server Core<br/>mcp.Server] ToolRegistry[Tool Registry<br/>@server.tool decorator] AuthMiddleware[Auth Middleware<br/>Checks auth state] end subgraph "Auth Module" AuthManager[Auth Manager<br/>Main auth orchestrator<br/>+ token refresh] TokenStore[Token Store<br/>Secure persistence] BrowserAuth[Browser Auth<br/>OAuth flow handler] end subgraph "Checklist Module" ChecklistService[Checklist Service<br/>Business logic] ChecklistDiscovery[File Discovery<br/>Glob pattern matching] ChecklistParser[Frontmatter Parser<br/>YAML extraction] end subgraph "Process Module" ProcessService[Process Service<br/>Business logic + Search] ProcessDiscovery[File Discovery<br/>Glob pattern matching] ProcessParser[Frontmatter Parser<br/>YAML extraction] SearchEngine[Search Engine<br/>Keyword search + ranking] end subgraph "Tools (MCP Exposed)" GetChecklist[get_checklist<br/>tool] ListChecklists[list_checklists<br/>tool] GetProcess[get_process<br/>tool] ListProcesses[list_processes<br/>tool] SearchProcesses[search_processes<br/>tool] end Server --> ToolRegistry ToolRegistry --> GetChecklist ToolRegistry --> ListChecklists ToolRegistry --> GetProcess ToolRegistry --> ListProcesses ToolRegistry --> SearchProcesses GetChecklist --> AuthMiddleware ListChecklists --> AuthMiddleware GetProcess --> AuthMiddleware ListProcesses --> AuthMiddleware SearchProcesses --> AuthMiddleware AuthMiddleware --> AuthManager GetChecklist --> ChecklistService ListChecklists --> ChecklistService GetProcess --> ProcessService ListProcesses --> ProcessService SearchProcesses --> ProcessService AuthManager --> TokenStore AuthManager --> BrowserAuth ChecklistService --> ChecklistDiscovery ChecklistService --> ChecklistParser ProcessService --> ProcessDiscovery ProcessService --> ProcessParser ProcessService --> SearchEngine ``` ### 5.2 Component Descriptions #### Component Group: MCP Server Module ##### Component: Server Core - **Purpose**: Main MCP server implementation using mcp-python-sdk - **Responsibilities**: - Initialize MCP server with HTTP Streamable transport - Start HTTP server on configurable port (default: 8080) - Handle SSE connections for streaming responses - Register available tools - Handle server lifecycle (start, shutdown) - **Dependencies**: mcp-python-sdk, ToolRegistry, aiohttp/starlette - **Exposed Interfaces**: HTTP endpoints for MCP protocol ##### Component: Tool Registry - **Purpose**: Registers and manages MCP tools - **Responsibilities**: - Define tool schemas (name, description, parameters) - Route tool calls to handlers - Format tool responses - **Dependencies**: Server Core ##### Component: Auth Middleware - **Purpose**: Enforces authentication before tool execution - **Responsibilities**: - Check authentication state before tool calls - Trigger authentication flow if not authenticated - Return appropriate errors for auth failures - **Dependencies**: AuthManager #### Component Group: Auth Module ##### Component: Auth Manager - **Purpose**: Orchestrates authentication flow, state, and token refresh - **Responsibilities**: - Coordinate authentication on server startup - Check if valid tokens exist - Delegate to BrowserAuth for new authentication - Handle token refresh when less than 5 minutes remaining (leverages MSAL built-in refresh) - Provide authentication state to other components - **Dependencies**: TokenStore, BrowserAuth, MSAL - **Key Operations**: - `ensure_authenticated(): bool` - `get_access_token(): str` - `is_authenticated(): bool` - `logout(): void` ##### Component: Token Store - **Purpose**: Securely persists authentication tokens - **Responsibilities**: - Encrypt tokens before storage - Store tokens in user-specific directory - Retrieve and decrypt tokens on startup - Clear tokens on logout - **Dependencies**: File system, encryption library - **Key Operations**: - `save_tokens(tokens): void` - `load_tokens(): TokenData | None` - `clear_tokens(): void` ##### Component: Browser Auth - **Purpose**: Handles OAuth 2.0 Authorization Code flow with PKCE - **Responsibilities**: - Generate PKCE code verifier and challenge - Open system browser with authorization URL - Start local HTTP server for OAuth callback - Exchange authorization code for tokens - **Dependencies**: MSAL, webbrowser, http.server - **Key Operations**: - `authenticate(): TokenData` #### Component Group: Checklist Module ##### Component: Checklist Service - **Purpose**: Business logic for checklist operations - **Responsibilities**: - Get checklist by name - List all available checklists - Format checklist data for MCP response - **Dependencies**: FileDiscovery, FrontmatterParser - **Key Operations**: - `get_checklist(name: str): ChecklistContent` - `list_checklists(): List[ChecklistMetadata]` ##### Component: File Discovery - **Purpose**: Discovers checklist files in configured directory - **Responsibilities**: - Scan directory for markdown files - Support dynamic discovery (no caching) - Handle file system errors gracefully - **Dependencies**: File system (pathlib) - **Key Operations**: - `discover_files(): List[Path]` ##### Component: Frontmatter Parser - **Purpose**: Parses YAML frontmatter from markdown files - **Responsibilities**: - Extract YAML frontmatter block - Parse name and description fields - Return content body separately - **Dependencies**: PyYAML or python-frontmatter - **Key Operations**: - `parse(content: str): (metadata: dict, body: str)` #### Component Group: Process Module ##### Component: Process Service - **Purpose**: Business logic for process operations - **Responsibilities**: - Get process by name (case-insensitive matching) - List all available processes with metadata - Search processes by keyword across name, description, and content - Return up to 50 search results, ranked by relevance - Format process data for MCP response - **Dependencies**: ProcessDiscovery, ProcessParser, SearchEngine - **Key Operations**: - `get_process(name: str): ProcessContent` - `list_processes(): List[ProcessMetadata]` - `search_processes(keyword: str): List[SearchResult]` ##### Component: Process File Discovery - **Purpose**: Discovers process files in configured directory - **Responsibilities**: - Scan process directory for markdown files - Support dynamic discovery (no caching) - Handle file system errors gracefully - Maintain separation from checklist directory - **Dependencies**: File system (pathlib) - **Key Operations**: - `discover_files(): List[Path]` ##### Component: Process Frontmatter Parser - **Purpose**: Parses YAML frontmatter from process markdown files - **Responsibilities**: - Extract YAML frontmatter block - Parse name and description fields - Return content body separately - Handle missing frontmatter gracefully (use filename as name) - **Dependencies**: PyYAML or python-frontmatter - **Key Operations**: - `parse(content: str): (metadata: dict, body: str)` ##### Component: Search Engine - **Purpose**: Provides keyword search across process documents - **Responsibilities**: - Search across process name, description, and content fields - Support partial keyword matching (substring search) - Rank results by relevance (title matches ranked higher than content matches) - Limit results to maximum 50 entries - Normalize search terms and process names for matching - **Dependencies**: None (pure Python implementation) - **Key Operations**: - `search(processes: List[Process], keyword: str): List[SearchResult]` - `calculate_relevance(process: Process, keyword: str): float` ### 5.3 Component Interaction Patterns **Pattern 1: Authentication Flow** ```mermaid sequenceDiagram participant Client as AI Client participant Server as MCP Server participant Auth as Auth Manager participant Store as Token Store participant Browser as Browser Auth participant Azure as Azure Entra ID Client->>Server: Initialize connection Server->>Auth: ensure_authenticated() Auth->>Store: load_tokens() alt Tokens exist and valid Store-->>Auth: tokens Auth->>Auth: validate_tokens() Auth-->>Server: authenticated else Tokens near expiry (< 5 min) Auth->>Auth: refresh via MSAL Auth-->>Server: authenticated (after refresh) else No tokens or refresh failed Auth->>Browser: authenticate() Browser->>Browser: Open browser Browser->>Azure: Authorization request Azure-->>Browser: Auth code (via redirect) Browser->>Azure: Exchange code for tokens Azure-->>Browser: Access + Refresh tokens Browser->>Store: save_tokens() Browser-->>Auth: tokens Auth-->>Server: authenticated end Server-->>Client: Ready for tool calls ``` **Pattern 2: Checklist Tool Invocation** ```mermaid sequenceDiagram participant Client as AI Client participant Server as MCP Server participant Auth as Auth Middleware participant Checklist as Checklist Service participant Files as File System Client->>Server: get_checklist("coding") Server->>Auth: check_auth() Auth-->>Server: authenticated Server->>Checklist: get_checklist("coding") Checklist->>Files: read coding.md Files-->>Checklist: file content Checklist->>Checklist: parse_frontmatter() Checklist-->>Server: ChecklistContent Server-->>Client: MCP tool response ``` **Pattern 3: Process Search Flow** ```mermaid sequenceDiagram participant Client as AI Client participant Server as MCP Server participant Auth as Auth Middleware participant Process as Process Service participant Search as Search Engine participant Files as File System Client->>Server: search_processes("deployment") Server->>Auth: check_auth() Auth-->>Server: authenticated Server->>Process: search_processes("deployment") Process->>Files: discover all process files Files-->>Process: list of .md files Process->>Process: parse all frontmatter Process->>Search: search(processes, "deployment") Search->>Search: match name, description, content Search->>Search: calculate relevance scores Search->>Search: sort by relevance, limit to 50 Search-->>Process: SearchResult[] Process-->>Server: ranked search results Server-->>Client: MCP tool response ``` --- ## 6. Code View ### 6.1 Code Organization **Directory Structure**: ```text sso-mcp-server/ ├── src/ │ └── sso_mcp_server/ │ ├── __init__.py │ ├── __main__.py # Entry point │ ├── server.py # MCP Server Core │ ├── tools/ # MCP Tools │ │ ├── __init__.py │ │ ├── get_checklist.py │ │ ├── list_checklists.py │ │ ├── get_process.py # NEW: Get process by name │ │ ├── list_processes.py # NEW: List all processes │ │ └── search_processes.py # NEW: Search processes by keyword │ ├── auth/ # Authentication Module │ │ ├── __init__.py │ │ ├── manager.py # Auth Manager (includes token refresh) │ │ ├── browser.py # Browser Auth flow │ │ ├── token_store.py # Secure token persistence │ │ ├── middleware.py # Auth middleware for tool calls │ │ └── cloud/ # Cloud mode authentication │ │ ├── __init__.py │ │ ├── claims.py # Token claims model │ │ ├── jwks_client.py # JWKS client for token validation │ │ └── validator.py # JWT token validator │ ├── checklists/ # Checklist Module │ │ ├── __init__.py │ │ ├── service.py # Checklist Service │ │ ├── discovery.py # File Discovery │ │ └── parser.py # Frontmatter Parser │ ├── processes/ # NEW: Process Module │ │ ├── __init__.py │ │ ├── service.py # Process Service (get, list, search) │ │ ├── discovery.py # File Discovery │ │ ├── parser.py # Frontmatter Parser │ │ └── search.py # Search Engine with relevance ranking │ ├── metadata/ # Protected Resource Metadata │ │ ├── __init__.py │ │ └── resource_metadata.py │ └── config/ # Configuration │ ├── __init__.py │ └── settings.py # Settings management ├── checklists/ # Default checklist directory │ ├── coding.md │ ├── architecture.md │ └── detailed-design.md ├── processes/ # NEW: Default process directory │ ├── code-review.md │ ├── deployment.md │ └── incident-response.md ├── tests/ │ ├── unit/ │ │ ├── test_auth_manager.py │ │ ├── test_token_store.py │ │ ├── test_checklist_service.py │ │ ├── test_frontmatter_parser.py │ │ ├── test_process_service.py # NEW │ │ └── test_search_engine.py # NEW │ ├── integration/ │ │ ├── test_auth_flow.py │ │ └── test_mcp_tools.py │ └── conftest.py ├── docs/ │ └── architecture.md # This document ├── pyproject.toml # Project configuration (uv) └── README.md ``` ### 6.2 Naming Conventions **Files**: - snake_case for all Python modules: `auth_manager.py`, `token_store.py` - Lowercase with hyphens for checklist files: `coding.md`, `detailed-design.md` **Code**: - PascalCase for classes: `class AuthManager`, `class ChecklistService` - snake_case for functions/methods: `def get_checklist()`, `def ensure_authenticated()` - UPPER_SNAKE_CASE for constants: `DEFAULT_TOKEN_PATH`, `OAUTH_SCOPES` - Prefix private members with underscore: `_token_cache`, `_refresh_token()` ### 6.3 Key Design Patterns | Pattern | Purpose | Usage Example | |---------|---------|---------------| | Facade | Simplified auth interface | `AuthManager` wrapping MSAL complexity | | Strategy | Interchangeable token storage | `TokenStore` interface for different backends | | Factory | Create checklist parsers | Future support for different formats | | Singleton | Single auth state | `AuthManager` instance per server | | Observer | Token expiration events | Trigger refresh on expiration warning | --- ## 7. Deployment View ### 7.1 Deployment Architecture #### 7.1.1 Local Development Environment ```mermaid graph TB subgraph "Developer Machine" subgraph "VSCode" Copilot[GitHub Copilot] MCPConfig[mcp.json config] end subgraph "Claude Code" ClaudeConfig[claude_desktop_config.json] end subgraph "MCP Server Process" Python[Python 3.11+] Server[sso-mcp-server] end subgraph "Local Files" Checklists[checklists/*.md] TokenCache[~/.sso-mcp-server/tokens] EnvConfig[.env or config.json] end Browser[System Browser] end subgraph "External" Azure[Azure Entra ID<br/>login.microsoftonline.com] end Copilot -->|HTTP + SSE| Server MCPConfig -->|configures| Copilot ClaudeConfig -->|configures| ClaudeCode ClaudeCode -->|HTTP + SSE| Server Server --> Python Server -->|reads| Checklists Server -->|reads/writes| TokenCache Server -->|reads| EnvConfig Server -->|opens| Browser Browser -->|OAuth| Azure ``` #### 7.1.2 Environment Specifications | Environment | Purpose | Infrastructure | Notes | |-------------|---------|----------------|-------| | **Development** | Local development and testing | Developer machine, Python 3.11+ | Primary deployment target | | **CI/CD** | Automated testing | GitHub Actions runner | Unit and integration tests | ### 7.2 Configuration Files #### 7.2.1 VSCode GitHub Copilot Configuration Location: `.vscode/mcp.json` ```json { "servers": { "sso-checklist": { "url": "http://localhost:8080/mcp", "transport": "http" } } } ``` **Note**: The server must be started separately before connecting. Use the startup command to run the server with proper environment variables. #### 7.2.2 Claude Code Configuration Location: `~/.claude/claude_desktop_config.json` ```json { "mcpServers": { "sso-checklist": { "url": "http://localhost:8080/mcp", "transport": "http" } } } ``` #### 7.2.3 Server Startup Configuration Create a `.env` file or use environment variables: ```bash # Start the MCP server AZURE_CLIENT_ID=<app-registration-client-id> \ AZURE_TENANT_ID=<tenant-id> \ CHECKLIST_DIR=/path/to/checklists \ PROCESS_DIR=/path/to/processes \ MCP_PORT=8080 \ uv run sso-mcp-server ``` **Environment Variables**: | Variable | Required | Default | Description | |----------|----------|---------|-------------| | `AZURE_CLIENT_ID` | Yes (local mode) | - | Azure App Registration client ID | | `AZURE_TENANT_ID` | Yes (local mode) | - | Azure tenant ID | | `CHECKLIST_DIR` | Yes | - | Directory containing checklist markdown files | | `PROCESS_DIR` | No | `./processes` | Directory containing process markdown files | | `MCP_PORT` | No | `8080` | Server port | | `AUTH_MODE` | No | `local` | Authentication mode: `local`, `cloud`, or `auto` | ### 7.3 Installation and Setup **Prerequisites**: 1. Python 3.11 or later 2. uv package manager 3. Azure App Registration with appropriate permissions **Installation Steps**: ```bash # Clone repository git clone <repository-url> cd sso-mcp-server # Install dependencies with uv uv sync # Configure environment cp .env.example .env # Edit .env with Azure credentials # Test the server uv run sso-mcp-server --help ``` ### 7.4 CI/CD Pipeline ```mermaid graph LR A[Push to Branch] --> B[Lint & Format Check] B --> C[Unit Tests] C --> D[Integration Tests] D --> E[Security Scan] E --> F{Branch?} F -->|main| G[Create Release] F -->|feature| H[PR Ready] ``` **Pipeline Stages**: 1. **Lint & Format**: ruff check, ruff format --check 2. **Unit Tests**: pytest tests/unit/ --cov 3. **Integration Tests**: pytest tests/integration/ 4. **Security Scan**: bandit, safety check --- ## 8. Architecture Decisions ### 8.1 Decision Log | ID | Date | Title | Status | |----|------|-------|--------| | ADR-001 | 2025-12-11 | Single-Process Python App with HTTP Streamable Transport | Accepted (Updated) | | ADR-002 | 2025-12-11 | OAuth 2.0 with PKCE for Authentication | Accepted | | ADR-003 | 2025-12-11 | Local File System for Checklist Storage | Accepted | | ADR-004 | 2025-12-11 | MSAL for Azure Authentication | Accepted | | ADR-005 | 2025-12-11 | Secure Local Token Persistence | Accepted | | ADR-006 | 2025-12-13 | Parallel Module Design for Processes | Accepted | | ADR-007 | 2025-12-13 | In-Memory Search with Relevance Ranking | Accepted | ### 8.2 Architecture Decision Records #### ADR-001: Single-Process Python Application with HTTP Streamable Transport **Date**: 2025-12-11 **Status**: Accepted (Updated) **Deciders**: Architecture Team **Context**: The MCP server needs to integrate with AI assistants and run locally on developer machines. The MCP specification supports multiple transports including stdio and HTTP Streamable. **Decision**: Implement as a single-process Python application using the MCP Python SDK with HTTP Streamable transport as the default protocol. **Rationale**: - HTTP Streamable is the recommended transport for network-capable MCP servers - Provides better flexibility for client connections (URL-based configuration) - Supports Server-Sent Events (SSE) for streaming responses - Enables future remote deployment scenarios if needed - Better debugging and monitoring via standard HTTP tools **Consequences**: *Positive*: - Simple URL-based configuration for clients - Standard HTTP semantics familiar to developers - Easier to debug with HTTP tools (curl, browser dev tools) - Future-proof for remote deployment scenarios - SSE provides efficient streaming *Negative*: - Requires starting server before client connection (not auto-spawned) - Slightly more setup than stdio (port configuration) **Alternatives Considered**: 1. **stdio transport**: Standard input/output communication - Pros: Auto-spawn by clients, simpler setup - Cons: Limited to local process, harder to debug - Why rejected: HTTP Streamable provides better flexibility and debugging 2. **WebSocket transport**: Full-duplex communication - Pros: Bidirectional streaming - Cons: More complex, not needed for request-response pattern - Why rejected: SSE sufficient for MCP use case --- #### ADR-002: OAuth 2.0 with PKCE for Authentication **Date**: 2025-12-11 **Status**: Accepted **Deciders**: Architecture Team, Security Team **Context**: The system requires Azure Entra ID authentication. Options include device code flow, authorization code flow with PKCE, or client credentials (service principal). **Decision**: Use OAuth 2.0 Authorization Code flow with PKCE for browser-based SSO authentication. **Rationale**: - PKCE is the recommended flow for public clients (desktop/CLI apps) - Provides familiar SSO experience via browser - Supports MFA and conditional access policies - No secrets stored in application configuration **Consequences**: *Positive*: - Secure authentication without storing secrets - Familiar SSO experience for users - Supports organizational security policies - Refresh tokens enable long sessions *Negative*: - Requires browser interaction for initial authentication - More complex than device code flow **Alternatives Considered**: 1. **Device Code Flow**: User enters code on separate device - Pros: Works in terminal-only environments - Cons: More friction, unfamiliar to users - Why rejected: Browser-based is more user-friendly 2. **Client Credentials**: Service principal authentication - Pros: No user interaction needed - Cons: Requires secret management, no user identity - Why rejected: Need user-specific authentication --- #### ADR-003: Local File System for Checklist Storage **Date**: 2025-12-11 **Status**: Accepted **Deciders**: Architecture Team **Context**: Checklists need to be stored and accessed by the MCP server. Options include database, cloud storage, or local file system. **Decision**: Store checklists as markdown files with YAML frontmatter in a local directory. **Rationale**: - Markdown is human-readable and version-controllable - YAML frontmatter is a standard pattern for metadata - Local files require no external dependencies - Easy to update and customize checklists **Consequences**: *Positive*: - Simple to manage and version control - No database setup required - Human-editable format - Works offline (after authentication) *Negative*: - No centralized checklist management - Each user manages their own checklists **Alternatives Considered**: 1. **SQLite Database**: Embedded database for checklists - Pros: Query capabilities, structured data - Cons: Overkill for read-only text content - Why rejected: Unnecessary complexity 2. **Remote API**: Fetch checklists from central server - Pros: Centralized management, always up-to-date - Cons: Requires additional infrastructure, network dependency - Why rejected: Out of scope, adds complexity --- #### ADR-004: MSAL for Azure Authentication **Date**: 2025-12-11 **Status**: Accepted **Deciders**: Architecture Team **Context**: Need a library to handle Azure Entra ID OAuth 2.0 authentication in Python. **Decision**: Use Microsoft Authentication Library (MSAL) for Python. **Rationale**: - Official Microsoft library for Azure authentication - Handles token caching and refresh automatically - Well-documented and maintained - Supports PKCE flow out of the box **Consequences**: *Positive*: - Battle-tested implementation - Automatic token management - Good documentation and community support *Negative*: - Microsoft-specific (not portable to other IdPs) **Alternatives Considered**: 1. **authlib**: Generic OAuth 2.0 library - Pros: Provider-agnostic - Cons: More manual Azure-specific configuration - Why rejected: MSAL has better Azure integration --- #### ADR-005: Secure Local Token Persistence **Date**: 2025-12-11 **Status**: Accepted **Deciders**: Architecture Team, Security Team **Context**: Tokens need to persist across server restarts to avoid repeated authentication. Need to balance convenience with security. **Decision**: Persist tokens in encrypted local storage using MSAL's built-in token cache with encryption at rest. **Rationale**: - MSAL provides secure token caching mechanism - Tokens are encrypted on disk - Stored in user-specific directory with restricted permissions - Standard practice for desktop applications **Consequences**: *Positive*: - Seamless session resumption - Tokens protected at rest - Follows MSAL best practices *Negative*: - Tokens exist on local disk (mitigated by encryption) - User responsible for machine security **Alternatives Considered**: 1. **No persistence**: Re-authenticate every startup - Pros: No tokens on disk - Cons: Poor UX, defeats SSO purpose - Why rejected: Unacceptable user experience 2. **System keychain**: Use OS credential store - Pros: OS-managed security - Cons: Platform-specific implementation - Why rejected: MSAL cache is simpler and cross-platform --- #### ADR-006: Parallel Module Design for Processes **Date**: 2025-12-13 **Status**: Accepted **Deciders**: Architecture Team **Context**: A new feature is needed to expose development process documentation through the MCP server. Processes are similar to checklists (markdown files with YAML frontmatter) but serve a different purpose (procedural documentation vs. verification items) and require additional capabilities (keyword search). **Decision**: Implement the Process Module as a parallel structure to the Checklist Module, with its own service, discovery, and parser components, plus a dedicated search engine. **Rationale**: - Clear separation of concerns between checklists and processes - Independent evolution of each module without cross-dependencies - Reuse of proven patterns from checklist implementation - Search capability is process-specific and doesn't apply to checklists - Separate directories prevent confusion between content types **Consequences**: *Positive*: - Clean architecture with no coupling between modules - Easy to test each module independently - Can add new document types following the same pattern - Search implementation isolated to process module *Negative*: - Some code duplication between checklist and process modules (discovery, parser) - Could extract shared components later if needed (premature optimization avoided) **Alternatives Considered**: 1. **Single unified document module**: Handle both checklists and processes - Pros: Less code, shared infrastructure - Cons: Coupling, harder to evolve independently, search adds complexity - Why rejected: Violates single responsibility, complicates testing 2. **Extend checklist module**: Add process support to existing module - Pros: Reuse existing code - Cons: Checklists and processes have different semantics - Why rejected: Conceptual mismatch, would confuse the codebase --- #### ADR-007: In-Memory Search with Relevance Ranking **Date**: 2025-12-13 **Status**: Accepted **Deciders**: Architecture Team **Context**: The process query feature requires keyword search across process documents. Options include full-text search engines (Elasticsearch, Whoosh), database-backed search (SQLite FTS), or simple in-memory search. **Decision**: Implement in-memory search with relevance ranking using pure Python, searching across process name, description, and content fields. **Rationale**: - Process documents are expected to be small in number (< 100 files) - Search performance requirement (< 3 seconds) easily met with in-memory approach - No additional dependencies or infrastructure required - Simple substring matching meets functional requirements - Relevance ranking (title > description > content) provides good UX **Consequences**: *Positive*: - Zero additional dependencies - Fast implementation and easy maintenance - No external service dependencies - Simple to test and debug - Meets performance requirements comfortably *Negative*: - Limited to substring matching (no fuzzy search, stemming, etc.) - Re-reads files on each search (no persistent index) - May need optimization if document count grows significantly **Alternatives Considered**: 1. **Whoosh (Python full-text search)**: Embedded search library - Pros: Advanced search features, persistent index - Cons: Additional dependency, index management complexity - Why rejected: Overkill for < 100 documents 2. **SQLite FTS**: Full-text search with SQLite - Pros: Powerful, well-tested - Cons: Requires database setup, schema management - Why rejected: Adds unnecessary complexity for read-only markdown files 3. **Elasticsearch**: Distributed search engine - Pros: Enterprise-grade search - Cons: Massive overkill, requires infrastructure - Why rejected: Inappropriate for local CLI tool --- ## 9. Quality Attributes ### 9.1 Performance Strategies **Strategy 1: Lazy Authentication** - **Implementation**: Defer authentication until first tool call - **Expected Impact**: Server starts in < 1 second (auth only when needed) **Strategy 2: File Caching** - **Implementation**: Cache parsed checklist metadata in memory after first read - **Cache Invalidation**: On tool call, check file modification time - **Expected Impact**: Subsequent list operations < 100ms **Strategy 3: Proactive Token Refresh** - **Implementation**: Refresh tokens when less than 5 minutes remaining (via MSAL in Auth Manager) - **Expected Impact**: No user-visible delays during session, seamless 8+ hour sessions ### 9.2 Security Strategies **Strategy 1: PKCE for Public Client** - **Implementation**: Generate code_verifier and code_challenge for each auth request - **Expected Impact**: Protection against authorization code interception **Strategy 2: Encrypted Token Storage** - **Implementation**: MSAL token cache with encryption, restricted file permissions - **Expected Impact**: Tokens protected even if disk is compromised **Strategy 3: Minimal Scopes** - **Implementation**: Request only necessary Azure API scopes - **Expected Impact**: Principle of least privilege **Strategy 4: No Secrets in Code** - **Implementation**: Azure credentials via environment variables only - **Expected Impact**: No accidental secret exposure in version control ### 9.3 Maintainability Strategies **Strategy 1: Clean Code Adherence** - **Implementation**: Follow project ground rules, ruff linting, type hints - **Expected Impact**: Consistent, readable codebase **Strategy 2: Test Coverage** - **Implementation**: Unit tests for all components, integration tests for flows - **Target**: >80% coverage for auth and MCP modules - **Expected Impact**: Confident refactoring, regression prevention **Strategy 3: Structured Logging** - **Implementation**: Python logging with structured format (JSON in production) - **Levels**: DEBUG for development, INFO for production - **Expected Impact**: Easy troubleshooting, audit trail ### 9.4 Usability Strategies **Strategy 1: Browser-Based SSO** - **Implementation**: Auto-open system browser for authentication - **Expected Impact**: Familiar login experience, supports MFA **Strategy 2: Actionable Error Messages** - **Implementation**: All errors include description and suggested action - **Expected Impact**: Users can self-resolve common issues **Strategy 3: Configuration Examples** - **Implementation**: Provide template configurations for VSCode and Claude Code - **Expected Impact**: < 5 minute setup time --- ## 10. Risks & Technical Debt ### 10.1 Architecture Risks | Risk ID | Description | Impact | Probability | Mitigation Strategy | |---------|-------------|--------|-------------|---------------------| | AR-001 | Azure Entra ID service outage prevents authentication | High | Low | Clear error messages, document retry process | | AR-002 | Token refresh fails silently causing auth errors | Medium | Medium | Proactive refresh, clear re-auth prompt | | AR-003 | MCP protocol changes break compatibility | Medium | Low | Pin SDK version, monitor MCP spec updates | | AR-004 | Local token cache corruption | Medium | Low | Graceful degradation to re-authentication | ### 10.2 Known Technical Debt | Debt ID | Description | Impact | Effort | Priority | Plan | |---------|-------------|--------|--------|----------|------| | TD-001 | No automated integration tests with real Azure | Medium | Medium | P2 | Add test tenant for CI | | TD-002 | Limited observability beyond logging | Low | Low | P3 | Add metrics if needed | ### 10.3 Open Questions & Future Considerations **Open Questions**: 1. Should we support multiple Azure tenants? - Status: Deferred (single-tenant for MVP) - Decision if needed: Add tenant selection UI **Future Enhancements**: - **Enhancement 1**: Support for additional IdPs (Okta, Google) - Timeframe: If business need arises - Depends on: Customer requirements - **Enhancement 2**: Checklist synchronization from central repository - Timeframe: Post-MVP - Depends on: Infrastructure for central checklist management --- ## 11. Appendices ### 11.1 Glossary | Term | Definition | |------|------------| | MCP | Model Context Protocol - Protocol for AI assistant tool integration | | Tool | An MCP-exposed function that AI assistants can invoke | | PKCE | Proof Key for Code Exchange - OAuth 2.0 extension for public clients | | Frontmatter | YAML metadata block at the start of a markdown file | | Token Cache | Encrypted local storage for OAuth tokens | ### 11.2 References 1. **Standards**: - Model Context Protocol Specification: https://modelcontextprotocol.io/ - OAuth 2.0 Authorization Code Flow with PKCE: RFC 7636 - Azure Entra ID Documentation: https://learn.microsoft.com/entra/ 2. **Libraries**: - MCP Python SDK: https://github.com/modelcontextprotocol/python-sdk - MSAL Python: https://github.com/AzureAD/microsoft-authentication-library-for-python 3. **Project References**: - Ground Rules: `memory/ground-rules.md` - Feature Specification (Checklist): `specs/001-mcp-sso-checklist/spec.md` - Feature Specification (Process Query): `specs/003-process-query/spec.md` ### 11.3 Related Documents - **Ground Rules**: `memory/ground-rules.md` - Project quality standards - **Feature Specification (Checklist)**: `specs/001-mcp-sso-checklist/spec.md` - Checklist feature requirements - **Feature Specification (Process Query)**: `specs/003-process-query/spec.md` - Process query requirements - **Implementation Plan**: `specs/001-mcp-sso-checklist/design.md` - Checklist implementation design ### 11.4 Diagrams & Models All diagrams in this document use Mermaid format for maintainability: - **System Context Diagram**: Section 3.1 - **Container Diagram**: Section 4.1 - **Component Diagram**: Section 5.1 - **Authentication Sequence**: Section 5.3 (Pattern 1) - **Checklist Tool Invocation Sequence**: Section 5.3 (Pattern 2) - **Process Search Flow Sequence**: Section 5.3 (Pattern 3) - **Deployment Diagram**: Section 7.1 - **CI/CD Pipeline**: Section 7.4 --- **END OF ARCHITECTURE DESIGN DOCUMENT**

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DauQuangThanh/sso-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server