diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..aa0bec9 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,69 @@ +name: Deploy Documentation + +on: + push: + branches: [ main ] + paths: [ 'docs/**', 'mkdocs.yml', 'requirements.txt' ] + pull_request: + branches: [ main ] + paths: [ 'docs/**', 'mkdocs.yml', 'requirements.txt' ] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Setup Pages + id: pages + uses: actions/configure-pages@v3 + if: github.ref == 'refs/heads/main' + + - name: Build documentation + env: + PROJECT_VERSION: ${{ github.ref_name }} + BUILD_DATE: ${{ github.event.head_commit.timestamp }} + run: | + mkdocs build --clean --strict + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v2 + if: github.ref == 'refs/heads/main' + with: + path: ./site + + deploy: + if: github.ref == 'refs/heads/main' + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 \ No newline at end of file diff --git a/README.md b/README.md index 5404cd7..13a3a9e 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,10 @@ pnpm dev ## Documentation +**📚 [View Full Documentation](https://raxitai.github.io/mcp-oauth-sample/)** - Interactive Material for MkDocs site + +### Quick Reference + | Topic | Description | |-------|-------------| | [🚀 Setup Guide](./docs/setup.md) | Complete installation and configuration | @@ -71,6 +75,20 @@ pnpm dev | [❓ Troubleshooting](./docs/troubleshooting.md) | Common issues and solutions | | [👨‍đŸ’ģ Development](./docs/development.md) | Development guide and contributing | +### Local Documentation Development + +```bash +# Serve documentation locally with hot reload +./docs-serve.sh + +# Or on Windows +docs-serve.bat + +# Manual setup +pip install -r requirements.txt +mkdocs serve +``` + ## MCP Specification Compliance This implementation is fully compliant with the MCP Authorization Specification. diff --git a/docs-serve.bat b/docs-serve.bat new file mode 100644 index 0000000..8613e6e --- /dev/null +++ b/docs-serve.bat @@ -0,0 +1,61 @@ +@echo off +REM MkDocs development server script for Windows + +echo 🚀 Setting up MkDocs for MCP OAuth Sample documentation... + +REM Check if Python is installed +python --version >nul 2>&1 +if errorlevel 1 ( + echo ❌ Python is required but not installed. + echo Please install Python and try again. + pause + exit /b 1 +) + +REM Check if pip is installed +pip --version >nul 2>&1 +if errorlevel 1 ( + echo ❌ pip is required but not installed. + echo Please install pip and try again. + pause + exit /b 1 +) + +REM Create virtual environment if it doesn't exist +if not exist "venv" ( + echo đŸ“Ļ Creating virtual environment... + python -m venv venv +) + +REM Activate virtual environment +echo 🔄 Activating virtual environment... +call venv\Scripts\activate.bat + +REM Install/upgrade pip +echo âŦ†ī¸ Upgrading pip... +python -m pip install --upgrade pip + +REM Install dependencies +echo đŸ“Ĩ Installing MkDocs dependencies... +pip install -r requirements.txt + +REM Check if mkdocs.yml exists +if not exist "mkdocs.yml" ( + echo ❌ mkdocs.yml not found in current directory. + echo Please run this script from the project root. + pause + exit /b 1 +) + +echo ✅ Setup complete! +echo. +echo 🌐 Starting MkDocs development server... +echo 📖 Documentation will be available at: http://127.0.0.1:8000 +echo 🔄 The server will auto-reload when you make changes to the docs. +echo âšī¸ Press Ctrl+C to stop the server. +echo. + +REM Start the development server +mkdocs serve + +pause \ No newline at end of file diff --git a/docs-serve.sh b/docs-serve.sh new file mode 100755 index 0000000..aed02f7 --- /dev/null +++ b/docs-serve.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# MkDocs development server script + +set -e + +echo "🚀 Setting up MkDocs for MCP OAuth Sample documentation..." + +# Check if Python is installed +if ! command -v python3 &> /dev/null; then + echo "❌ Python 3 is required but not installed." + echo "Please install Python 3 and try again." + exit 1 +fi + +# Check if pip is installed +if ! command -v pip &> /dev/null; then + echo "❌ pip is required but not installed." + echo "Please install pip and try again." + exit 1 +fi + +# Create virtual environment if it doesn't exist +if [ ! -d "venv" ]; then + echo "đŸ“Ļ Creating virtual environment..." + python3 -m venv venv +fi + +# Activate virtual environment +echo "🔄 Activating virtual environment..." +source venv/bin/activate + +# Install/upgrade pip +echo "âŦ†ī¸ Upgrading pip..." +pip install --upgrade pip + +# Install dependencies +echo "đŸ“Ĩ Installing MkDocs dependencies..." +pip install -r requirements.txt + +# Check if mkdocs.yml exists +if [ ! -f "mkdocs.yml" ]; then + echo "❌ mkdocs.yml not found in current directory." + echo "Please run this script from the project root." + exit 1 +fi + +echo "✅ Setup complete!" +echo "" +echo "🌐 Starting MkDocs development server..." +echo "📖 Documentation will be available at: http://127.0.0.1:8000" +echo "🔄 The server will auto-reload when you make changes to the docs." +echo "âšī¸ Press Ctrl+C to stop the server." +echo "" + +# Start the development server +mkdocs serve \ No newline at end of file diff --git a/docs/hooks.py b/docs/hooks.py new file mode 100644 index 0000000..76ee06d --- /dev/null +++ b/docs/hooks.py @@ -0,0 +1,20 @@ +import os +import logging +from mkdocs.config import config_options +from mkdocs.plugins import BasePlugin + +logger = logging.getLogger(__name__) + +class CustomHooksPlugin(BasePlugin): + """Custom hooks for MCP OAuth Sample documentation""" + + def on_env(self, env, config, files, **kwargs): + """Add custom environment variables to the Jinja2 environment""" + env.globals['project_version'] = os.environ.get('PROJECT_VERSION', '1.0.0') + env.globals['build_date'] = os.environ.get('BUILD_DATE', 'unknown') + return env + + def on_page_markdown(self, markdown, page, config, files, **kwargs): + """Process markdown before conversion to HTML""" + # Add custom processing if needed + return markdown \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 3830679..868d2ca 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,15 @@ # MCP OAuth Sample Documentation -Welcome to the comprehensive documentation for the MCP OAuth Sample project - an OAuth 2.1 authorization server with Model Context Protocol (MCP) integration. +
+ đŸŸĸ + Live Demo Available +
+ +Welcome to the comprehensive documentation for the MCP OAuth Sample project - a production-ready OAuth 2.1 authorization server with Model Context Protocol (MCP) integration. + +!!! info "What is MCP OAuth Sample?" + + This project extends the [run-llama/mcp-nextjs](https://github.com/run-llama/mcp-nextjs) reference implementation with OAuth 2.1 compliance, refresh tokens, DIY analytics, and enhanced security monitoring. ## Quick Navigation @@ -29,14 +38,37 @@ This project extends the [run-llama/mcp-nextjs](https://github.com/run-llama/mcp ## Key Features -- ✅ OAuth 2.1 Authorization Server with PKCE -- ✅ MCP Server with Authentication -- ✅ Real-time Analytics Dashboard -- ✅ Security Monitoring & Threat Detection -- ✅ Google SSO Integration -- ✅ PostgreSQL with Prisma ORM -- ✅ Next.js 15 App Router -- ✅ Production Deployment Ready +
+
+

🔐 OAuth 2.1 Compliance

+

Full OAuth 2.1 authorization server with PKCE support, refresh token rotation, and resource indicators.

+
+ +
+

🔌 MCP Integration

+

Authenticated Model Context Protocol server with tool execution and transport support.

+
+ +
+

📊 DIY Analytics

+

Real-time analytics dashboard with performance metrics, user tracking, and OAuth insights.

+
+ +
+

đŸ›Ąī¸ Security Monitoring

+

Comprehensive threat detection, security event logging, and risk assessment.

+
+ +
+

🚀 Production Ready

+

Built with Next.js 15, PostgreSQL, Prisma ORM, and optimized for Vercel deployment.

+
+ +
+

🔗 Google SSO

+

Integrated Google authentication with NextAuth.js and multi-admin support.

+
+
## Quick Start diff --git a/docs/javascripts/mathjax.js b/docs/javascripts/mathjax.js new file mode 100644 index 0000000..f0d0ad5 --- /dev/null +++ b/docs/javascripts/mathjax.js @@ -0,0 +1,19 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache() + MathJax.typesetClear() + MathJax.texReset() + MathJax.typesetPromise() +}) \ No newline at end of file diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..2ec0291 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,184 @@ +/* Custom styles for MCP OAuth Sample documentation */ + +:root { + --md-primary-fg-color: #2563eb; + --md-primary-fg-color--light: #3b82f6; + --md-primary-fg-color--dark: #1d4ed8; + --md-accent-fg-color: #2563eb; +} + +/* Custom admonition for OAuth flows */ +.md-typeset .admonition.oauth, +.md-typeset details.oauth { + border-color: #2563eb; +} + +.md-typeset .oauth > .admonition-title, +.md-typeset .oauth > summary { + background-color: rgba(37, 99, 235, 0.1); + border-color: #2563eb; +} + +.md-typeset .oauth > .admonition-title::before, +.md-typeset .oauth > summary::before { + background-color: #2563eb; + -webkit-mask-image: var(--md-admonition-icon--note); + mask-image: var(--md-admonition-icon--note); +} + +/* Custom styling for code blocks */ +.md-typeset .highlight .filename { + background-color: var(--md-code-bg-color); + border-bottom: 1px solid var(--md-default-fg-color--lightest); + font-size: 0.85em; + font-weight: 500; + padding: 0.5rem 1rem; + margin: 0; +} + +/* Custom styling for API endpoints */ +.api-endpoint { + background: var(--md-code-bg-color); + border-left: 4px solid var(--md-primary-fg-color); + padding: 1rem; + margin: 1rem 0; + border-radius: 0.2rem; +} + +.api-endpoint .method { + font-weight: bold; + color: var(--md-primary-fg-color); +} + +/* Environment variable styling */ +.env-var { + background: var(--md-code-bg-color); + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 0.2rem; + padding: 0.1rem 0.3rem; + font-family: var(--md-code-font); + font-size: 0.85em; +} + +/* Security badge styling */ +.security-badge { + display: inline-block; + padding: 0.2rem 0.5rem; + border-radius: 0.2rem; + font-size: 0.75rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.security-badge.critical { + background-color: #dc2626; + color: white; +} + +.security-badge.high { + background-color: #ea580c; + color: white; +} + +.security-badge.medium { + background-color: #ca8a04; + color: white; +} + +.security-badge.low { + background-color: #16a34a; + color: white; +} + +/* Custom grid for features */ +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1rem; + margin: 2rem 0; +} + +.feature-card { + background: var(--md-default-bg-color); + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 0.5rem; + padding: 1.5rem; + transition: box-shadow 0.2s ease; +} + +.feature-card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.feature-card h3 { + margin-top: 0; + color: var(--md-primary-fg-color); +} + +/* OAuth flow diagram styling */ +.oauth-flow { + background: var(--md-code-bg-color); + border-radius: 0.5rem; + padding: 1rem; + margin: 1rem 0; + overflow-x: auto; +} + +/* Status indicators */ +.status-indicator { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.25rem 0.5rem; + border-radius: 0.25rem; + font-size: 0.875rem; + font-weight: 500; +} + +.status-indicator.online { + background-color: rgba(34, 197, 94, 0.1); + color: #16a34a; +} + +.status-indicator.offline { + background-color: rgba(239, 68, 68, 0.1); + color: #dc2626; +} + +.status-indicator.maintenance { + background-color: rgba(251, 191, 36, 0.1); + color: #d97706; +} + +/* Custom table styling for API reference */ +.api-table { + width: 100%; + border-collapse: collapse; + margin: 1rem 0; +} + +.api-table th, +.api-table td { + padding: 0.75rem; + text-align: left; + border-bottom: 1px solid var(--md-default-fg-color--lightest); +} + +.api-table th { + background-color: var(--md-code-bg-color); + font-weight: 600; + color: var(--md-primary-fg-color); +} + +.api-table .param-name { + font-family: var(--md-code-font); + font-size: 0.9em; + color: var(--md-primary-fg-color); +} + +.api-table .param-type { + font-family: var(--md-code-font); + font-size: 0.85em; + color: var(--md-default-fg-color--light); +} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..76e0331 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,175 @@ +site_name: MCP OAuth Sample Documentation +site_description: Production-ready MCP OAuth 2.1 server with analytics and security monitoring +site_author: raxIT AI +site_url: https://raxitai.github.io/mcp-oauth-sample + +# Repository +repo_name: raxITai/mcp-oauth-sample +repo_url: https://github.com/raxITai/mcp-oauth-sample +edit_uri: edit/main/docs/ + +# Configuration +theme: + name: material + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: blue + accent: blue + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: blue + accent: blue + toggle: + icon: material/brightness-4 + name: Switch to system preference + + features: + - announce.dismiss + - content.action.edit + - content.action.view + - content.code.annotate + - content.code.copy + - content.code.select + - content.tabs.link + - content.tooltips + - header.autohide + - navigation.expand + - navigation.footer + - navigation.indexes + - navigation.instant + - navigation.instant.prefetch + - navigation.instant.progress + - navigation.prune + - navigation.sections + - navigation.tabs + - navigation.tabs.sticky + - navigation.top + - navigation.tracking + - search.highlight + - search.share + - search.suggest + - toc.follow + - toc.integrate + + icon: + repo: fontawesome/brands/github + edit: material/pencil + view: material/eye + +# Plugins +plugins: + - search: + separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])' + - minify: + minify_html: true + +# Hooks +hooks: + - docs/hooks.py + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - toc: + permalink: true + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + normalize_issue_symbols: true + repo_url_shorthand: true + user: raxITai + repo: mcp-oauth-sample + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.snippets: + auto_append: + - includes/mkdocs.md + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + combine_header_slug: true + slugify: !!python/object/apply:pymdownx.slugs.slugify + kwds: + case: lower + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + +# Page tree +nav: + - Home: index.md + - Getting Started: + - Setup Guide: setup.md + - Quick Start: index.md#quick-start + - Architecture: + - System Design: architecture.md + - Security Model: security.md + - Features: + - Analytics Dashboard: analytics.md + - API Reference: api.md + - Operations: + - Deployment: deployment.md + - Development: development.md + - Troubleshooting: troubleshooting.md + +# Customization +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/raxITai/mcp-oauth-sample + - icon: fontawesome/brands/linkedin + link: https://www.linkedin.com/company/raxit-ai + - icon: fontawesome/brands/x-twitter + link: https://x.com/raxit_ai + - icon: fontawesome/brands/bluesky + link: https://bsky.app/profile/raxit.ai + + generator: false + +extra_css: + - stylesheets/extra.css + +extra_javascript: + - javascripts/mathjax.js + - https://polyfill.io/v3/polyfill.min.js?features=es6 + - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js + +# Copyright +copyright: > + Copyright © 2024 raxIT AI – + Change cookie settings \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..13a56fa --- /dev/null +++ b/requirements.txt @@ -0,0 +1,16 @@ +# MkDocs and Material theme +mkdocs>=1.5.3 +mkdocs-material>=9.4.0 + +# Plugins +mkdocs-minify-plugin>=0.7.1 +mkdocs-redirects>=1.2.1 + +# Extensions +pymdown-extensions>=10.3.1 +markdown-callouts>=0.3.0 + +# Optional enhancements +mkdocs-git-revision-date-localized-plugin>=1.2.0 +mkdocs-git-committers-plugin-2>=1.2.0 +mkdocs-awesome-pages-plugin>=2.9.2 \ No newline at end of file