{"id":43541574,"url":"https://github.com/bocan/codex","last_synced_at":"2026-04-12T18:31:38.018Z","repository":{"id":334634715,"uuid":"1136614050","full_name":"bocan/codex","owner":"bocan","description":"A wiki and document store built with React + Express. Organize markdown files in folders with a beautiful three-pane UI, dark mode, live preview, full REST API, and an optional built in MCP server","archived":false,"fork":false,"pushed_at":"2026-03-29T21:55:41.000Z","size":3133,"stargazers_count":6,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-30T00:45:38.657Z","etag":null,"topics":["document-management","document-store","express","markdown","markdown-editor","mcp","mcp-server","mermaid","note-taking","open-source","personal-wiki","react","self-hosted","typescript","vite","wiki"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bocan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-18T02:23:06.000Z","updated_at":"2026-03-24T00:56:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"55a26b13-c03f-4faf-ad28-e11c435263bb","html_url":"https://github.com/bocan/codex","commit_stats":null,"previous_names":["bocan/codex"],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/bocan/codex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bocan%2Fcodex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bocan%2Fcodex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bocan%2Fcodex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bocan%2Fcodex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bocan","download_url":"https://codeload.github.com/bocan/codex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bocan%2Fcodex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31313846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["document-management","document-store","express","markdown","markdown-editor","mcp","mcp-server","mermaid","note-taking","open-source","personal-wiki","react","self-hosted","typescript","vite","wiki"],"created_at":"2026-02-03T18:14:06.549Z","updated_at":"2026-04-02T19:01:52.634Z","avatar_url":"https://github.com/bocan.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📝 Codex\n\n\u003e A wiki and document store built with React and Express.\n\n**Single-user personal knowledge base** - A full-stack TypeScript application that provides a beautiful, intuitive interface for creating and managing markdown documents organized in a hierarchical folder structure.\n\n\u003e ⚠️ **Note**: Codex is designed as a **single-user application**. It does not support concurrent multi-user editing or collaboration features. Perfect for personal wikis, note-taking, and documentation.\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-6.0-blue)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-19-61dafb)](https://reactjs.org/)\n[![Express](https://img.shields.io/badge/Express-5.2.1-green)](https://expressjs.com/)\n\n## ✨ Features\n\n- 📁 **Folder Management**: Create, delete, and rename folders in a collapsible tree view with right-click context menus\n- 📝 **Markdown Pages**: Create and edit markdown documents with GitHub Flavored Markdown support\n- 🧩 **Smart Templates**: Create new pages from reusable templates (stored under `data/templates/`)\n- 📊 **Mermaid Diagrams**: Render Mermaid code fences in preview/reading mode, with export/download support\n- 🎨 **Three-Pane Layout**: Folder tree (left), markdown editor (center), live preview (right)\n- 📐 **Fully Resizable**: Drag to resize both horizontal panes (left/right) and vertical sections (folder tree/page list)\n- 🌓 **Theme Options**: Auto-detects system theme preference with manual override - cycles through auto/light/dark/high-contrast modes\n- ♿ **Accessibility**: Full ARIA labels, semantic HTML, high-contrast theme, and improved color contrast for WCAG compliance\n- 📤 **Move Pages**: Elegant folder picker to move pages between folders via right-click menu\n- 💾 **Smart Auto-save**: 10-second throttled saves with 5-second typing debounce - prevents excessive saves while keeping your work safe\n- 🔄 **Live Preview**: Real-time markdown preview that updates instantly as you type (no waiting for saves)\n- 🔗 **Internal Links**: Click links to other `.md` files to navigate within the app; anchor links scroll to headings\n- 📜 **Version History**: Git-backed version control with visual diff highlighting (green/red for additions/deletions)\n- 🔍 **Restore Versions**: Browse and restore any previous version of your documents\n- 📖 **Reading Mode**: Open any page in a new window for distraction-free reading\n- 🔃 **Synchronized Scrolling**: Editor scroll position syncs to preview pane\n- 📄 **Auto-select README**: Navigating to a folder automatically opens its README.md if present\n- 🔎 **Full-Text Search**: Quick search across all pages with keyboard shortcut (⌘K/Ctrl+K) and relevance-ranked results\n- 📑 **Table of Contents**: Auto-generated, collapsible TOC for easy document navigation with active section highlighting\n- 🎤 **Speech-to-Text**: Dictate content using Web Speech API (Chrome/Edge/Safari)\n- ⚡ **Performance Caching**: Server-side caching layer with 30-second TTL for fast folder/page loading\n- 🌐 **RESTful API**: Programmatic access to all folder and page operations\n- ✅ **Tested**: Comprehensive test suite for both backend and frontend\n- 🎯 **Collapsible Panes**: Hide sidebars for distraction-free writing\n- 🚀 **Fast \u0026 Lightweight**: Built with Vite for lightning-fast development\n- 🔐 **Password Protection**: Simple password-based authentication to secure your data\n- 🛡️ **Security Features**: Rate limiting, request logging, and security headers\n- 🤖 **AI Chat**: Built-in AI assistant supporting Anthropic Claude and local Ollama models with streaming responses, thinking blocks, and document context\n\n## 🧩 Smart Templates\n\nWhen creating a new page, Codex can start from a template instead of a blank page.\n\n- Templates live in `data/templates/*.md`\n- Optional frontmatter at the top of the template file:\n  - `template: Your Template Name` (display name)\n  - `autoname: true|false` (auto-generate a filename when creating)\n- The frontmatter is stripped from the created page content automatically\n\n## 📊 Mermaid Diagrams\n\nCodex supports Mermaid diagrams in markdown via fenced code blocks:\n\n````md\n```mermaid\ngraph TD\n  A --\u003e B\n```\n````\n\n- Diagrams render in the live preview and in reading mode (open in new window)\n- You can download rendered diagrams as SVG\n- Export flows (e.g. Word/PDF) include diagrams as images rather than raw Mermaid text\n\n## 🤖 AI Chat\n\nCodex includes an integrated AI chat assistant for asking questions about your documents:\n\n### Supported Providers\n\n- **Anthropic Claude** - Cloud-based AI with optional \"thinking\" mode for extended reasoning\n- **Ollama** - Run local models like Llama, Mistral, CodeLlama, and more\n\n### Features\n\n- **Streaming Responses** - See AI responses as they're generated in real-time\n- **Document Context** - AI can reference the currently open document for context-aware answers\n- **Thinking Blocks** - Anthropic's extended thinking feature shows the AI's reasoning process (collapsible)\n- **Token Usage** - Track input/output tokens for cost monitoring\n- **Chat History** - Conversation persists while the app is open\n- **Export Chat** - Download conversation history as JSON\n- **Custom System Prompts** - Configure how the AI behaves via settings\n- **Multiple Accounts** - Switch between different AI providers/accounts\n- **Markdown Rendering** - AI responses render with full markdown support including code highlighting\n- **Copy Support** - Copy individual messages or code blocks with one click\n\n### Configuration\n\nAI accounts are configured in Settings (gear icon):\n\n1. Click the settings icon in the header\n2. Navigate to the \"AI\" section\n3. Add an account:\n   - **Anthropic**: Enter your API key from [console.anthropic.com](https://console.anthropic.com)\n   - **Ollama**: Enter host (default: localhost) and port (default: 11434)\n4. Enable \"AI Search\" to show the AI chat button\n\n### Usage\n\n1. Click the robot icon (🤖) in the bottom-right corner to open AI chat\n2. Select your AI account from the dropdown\n3. Type your question and press Enter or click Send\n4. Use the thinking toggle (brain icon) for Anthropic's extended reasoning\n5. Click the settings icon to customize the system prompt\n\n### Ollama Setup\n\nTo use local AI models with Ollama:\n\n```bash\n# Install Ollama (macOS)\nbrew install ollama\n\n# Start Ollama server\nollama serve\n\n# Pull a model (in another terminal)\nollama pull llama3.2\nollama pull codellama  # Great for code questions\n```\n\nThen add an Ollama account in Codex settings with host `localhost` and port `11434`.\n\n## 🔐 Security \u0026 Logging\n\nCodex includes several security features to protect your data:\n\n### Authentication\n- **Password-based login** with bcrypt hashing (10 salt rounds)\n- **Session management** using httpOnly cookies (24-hour expiration)\n- Authentication can be disabled by not setting `AUTH_PASSWORD` (not recommended for public deployments)\n\n### Rate Limiting\n- **Login endpoint** is rate-limited to 5 attempts per 15 minutes per IP address\n- Prevents brute force password attacks\n- Returns `429 Too Many Requests` when limit is exceeded\n\n### Logging\nAll login attempts are logged with timestamps and IP addresses:\n- `✓ Successful login from 192.168.1.100` - Successful authentication\n- `✗ Failed login attempt from 192.168.1.100` - Invalid password\n- `Login attempt without password from 192.168.1.100` - Missing password\n- `Login attempt when auth disabled from 192.168.1.100` - Auth not configured\n\nHTTP request logging (via morgan):\n- **Development**: Concise colored output showing method, URL, status, and response time\n- **Production**: Combined Apache-style logs with full details\n\n### Security Headers\nHelmet middleware provides:\n- Content Security Policy (CSP)\n- X-Frame-Options (clickjacking protection)\n- X-Content-Type-Options (MIME sniffing protection)\n- Strict-Transport-Security (HTTPS enforcement in production)\n- And other security headers\n\n### Best Practices\n- Always set a strong `AUTH_PASSWORD` for deployments\n- Use a unique `SESSION_SECRET` in production\n- Enable HTTPS in production (`NODE_ENV=production`)\n- Monitor logs for suspicious login patterns\n- Consider deploying behind a reverse proxy (nginx, Caddy) for additional security\n\n## ♿ Accessibility Features\n\nCodex is designed to be accessible to all users, including those using assistive technologies:\n\n### Screen Reader Support\n- **Comprehensive ARIA labels** on all interactive elements\n- **Semantic HTML** structure using `\u003cheader\u003e`, `\u003cnav\u003e`, `\u003cmain\u003e`, `\u003csection\u003e`, `\u003caside\u003e`, and `\u003carticle\u003e` elements\n- **Live regions** (`aria-live`) announce dynamic content updates\n- **Proper roles** (`role=\"tree\"`, `role=\"button\"`, `role=\"dialog\"`) for enhanced navigation\n- **Keyboard navigation** support with proper focus management and `tabIndex` attributes\n- **Descriptive labels** explain the state and purpose of all controls\n\n### Visual Accessibility\n- **Four theme options**: Auto (follows system), Light, Dark, and High-Contrast\n- **High-contrast mode** provides maximum visual clarity:\n  - Pure black (#000) background with white (#fff) text\n  - Yellow (#ffff00) secondary text for clear distinction\n  - Cyan (#00ffff) accent colors for links and interactive elements\n  - White borders for clear element separation\n- **Improved contrast ratios** in all themes for WCAG compliance\n- **Larger interactive elements**: Buttons sized at 32px for easier clicking\n- **Consistent theming**: All features including reading mode support all themes\n\n### Keyboard Accessibility\n- **Tab navigation** through all interactive elements\n- **Arrow key navigation** (↑↓) or vim-style (`j`/`k`) in folder tree, page list, and search results\n- **Enter** to activate buttons, open folders/pages, and select search results\n- **Escape** to close modals and dialogs\n- **⌘K/Ctrl+K** global search shortcut\n- **Focus indicators** show keyboard-selected items with blue outline\n- **Mouse hover sync** updates keyboard selection for seamless interaction\n\nThe accessibility features ensure Codex can be used effectively by people with:\n- Visual impairments (screen readers, high-contrast mode)\n- Motor disabilities (keyboard-only navigation, larger click targets)\n- Color blindness (semantic colors with sufficient contrast)\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/bocan/codex.git\ncd codex\n\n# Install dependencies\nmake install\n```\n\n### Configuration\n\nCreate a `.env` file in the root directory:\n\n```env\n# Required: Set your password\nAUTH_PASSWORD=your-secure-password-here\n\n# Optional: Server port (default: 3001)\nPORT=3001\n```\n\n### Running\n\n```bash\n# Start both server and client\nmake dev\n\n# Visit http://localhost:3000\n# Login with your AUTH_PASSWORD\n```\n\n## 🛠️ Development\n\n### Project Scripts\n\n```bash\n# Development\nmake dev              # Run both server and client\nmake dev-server       # Run server only (port 3001)\nmake dev-client       # Run client only (port 3000)\n\n# Building\nmake build            # Build both server and client\nmake build-server     # Build server only\nmake build-client     # Build client only\n\n# Testing\nmake test             # Run all tests\nmake test-server      # Run backend tests\nmake test-client      # Run frontend tests\n\n# Maintenance\nmake clean            # Remove all node_modules and build artifacts\nmake install          # Fresh install of all dependencies\nmake help             # Show all available commands\n```\n\n### Development Workflow\n\n1. Make your changes in the appropriate files\n2. Tests run automatically in watch mode (if enabled)\n3. Server auto-reloads on file changes (via tsx)\n4. Client hot-reloads on file changes (via Vite HMR)\n5. Run `make test` before committing\n\n### Git Workflow \u0026 Releases\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/) and [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for automated changelog generation.\n\n#### Commit Message Format\n\n```\ntype(scope): description\n\nExamples:\nfeat: add search functionality\nfix: resolve dark mode flicker\ndocs: update README\nrefactor(api): simplify error handling\n```\n\n**Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`\n\n#### Pull Request Workflow\n\n```bash\n# 1. Create and switch to feature branch\ngit switch -c feature/my-change\n\n# 2. Make changes, commit (repeat as needed)\ngit add .\ngit commit -m \"feat: add new feature\"\n\n# 3. Push branch to GitHub\ngit push -u origin feature/my-change\n\n# 4. Create PR (via GitHub CLI or web)\ngh pr create --title \"feat: add new feature\" --body \"Description\"\n\n# 5. After PR is merged, switch back to main\ngit switch main\ngit pull\n```\n\n#### Creating a Release\n\nAfter merging PRs and when ready to release:\n\n```bash\n# Patch release (1.0.0 → 1.0.1) - bug fixes\nnpm run release\n\n# Minor release (1.0.0 → 1.1.0) - new features\nnpm run release:minor\n\n# Major release (1.0.0 → 2.0.0) - breaking changes\nnpm run release:major\n\n# Push with tags\ngit push --follow-tags\n```\n\nThis will:\n1. Bump version in `package.json`\n2. Update `CHANGELOG.md` with commits since last release\n3. Create a git commit and tag (e.g., `v1.1.0`)\n\n### Adding New Features\n\n#### Backend (Adding a new API endpoint)\n\n1. Create controller in `server/src/controllers/`\n2. Add route in `server/src/routes/`\n3. Register route in `server/src/index.ts`\n4. Add tests in `server/tests/`\n\n#### Frontend (Adding a new component)\n\n1. Create component in `client/src/components/`\n2. Add corresponding CSS file\n3. Import and use in parent component\n4. Add tests in same directory (`.test.tsx`)\n\n## 🏗️ Project Structure\n\n```\ncodex/\n├── 📄 Makefile                    # Build automation\n├── 📄 package.json                # Root package config\n├── 📄 README.md                   # This file\n│\n├── 📁 server/                     # Backend (Express + TypeScript)\n│   ├── 📄 package.json            # Server dependencies\n│   ├── 📄 tsconfig.json           # TypeScript config\n│   ├── 📄 jest.config.js          # Test configuration\n│   ├── 📁 src/\n│   │   ├── 📄 index.ts            # Server entry point\n│   │   ├── 📁 controllers/        # Request handlers\n│   │   │   ├── folderController.ts\n│   │   │   └── pageController.ts\n│   │   ├── 📁 routes/             # API routes\n│   │   │   ├── folders.ts\n│   │   │   └── pages.ts\n│   │   └── 📁 services/           # Business logic\n│   │       └── fileSystem.ts      # File operations\n│   └── 📁 tests/                  # Test files\n│       └── api.test.ts\n│\n├── 📁 client/                     # Frontend (React + TypeScript)\n│   ├── 📄 package.json            # Client dependencies\n│   ├── 📄 tsconfig.json           # TypeScript config\n│   ├── 📄 vite.config.ts          # Vite configuration\n│   ├── 📄 vitest.config.ts        # Test configuration\n│   ├── 📄 index.html              # HTML entry point\n│   ├── 📁 src/\n│   │   ├── 📄 main.tsx            # React entry point\n│   │   ├── 📄 App.tsx             # Main app component\n│   │   ├── 📄 App.css             # App styles\n│   │   ├── 📁 components/         # React components\n│   │   │   ├── FolderTree.tsx     # Folder navigation\n│   │   │   ├── FolderTree.css\n│   │   │   ├── PageList.tsx       # Page list in folder\n│   │   │   ├── PageList.css\n│   │   │   ├── Editor.tsx         # Markdown editor\n│   │   │   ├── Editor.css\n│   │   │   ├── Preview.tsx        # Markdown preview\n│   │   │   ├── Preview.css\n│   │   │   └── *.test.tsx         # Component tests\n│   │   ├── 📁 services/           # API client\n│   │   │   └── api.ts\n│   │   ├── 📁 types/              # TypeScript types\n│   │   │   └── index.ts\n│   │   └── 📁 test/               # Test setup\n│   │       └── setup.ts\n│\n└── 📁 data/                       # File storage\n    └── Welcome.md                 # Default welcome page\n```\n\n## 📋 Table of Contents\n\n- [Quick Start](#-quick-start)\n- [Installation](#-installation)\n- [Usage](#-usage)\n- [Project Structure](#-project-structure)\n- [AI Chat](#-ai-chat)\n- [MCP Server (AI Agent Access)](#-mcp-server-ai-agent-access)\n- [API Documentation](#-api-documentation)\n- [Testing](#-testing)\n- [Development](#-development)\n- [Tech Stack](#-tech-stack)\n- [Makefile Commands](#-makefile-commands)\n- [Troubleshooting](#-troubleshooting)\n- [Contributing](#-contributing)\n\n## 🚀 Quick Start\n\nThe fastest way to get started using the Makefile:\n\n```bash\n# Install all dependencies\nmake install\n\n# Run the application\nmake dev\n```\n\nThen open [http://localhost:3000](http://localhost:3000) in your browser!\n\n## 📦 Installation\n\n### Prerequisites\n\n- Node.js 25+ and npm\n- macOS, Linux, or Windows with WSL\n\n### Option 1: Using Make (Recommended)\n\n```bash\nmake install\n```\n\n### Option 2: Using npm\n\n```bash\nnpm run install:all\n```\n\n### Option 3: Manual Installation\n\n```bash\n# Install root dependencies\nnpm install\n\n# Install server dependencies\ncd server \u0026\u0026 npm install\n\n# Install client dependencies\ncd ../client \u0026\u0026 npm install\n```\n\n## 🎯 Usage\n\n### Running the Application\n\n#### Option 1: Using Make (Recommended)\n\n```bash\n# Run both server and client in development mode\nmake dev\n\n# Or run them separately\nmake dev-server    # Runs server on port 3001\nmake dev-client    # Runs client on port 3000\n```\n\n#### Option 2: Using npm\n\n```bash\n# Run both concurrently\nnpm run dev\n\n# Or run separately\nnpm run dev:server\nnpm run dev:client\n```\n\nThe application will be available at:\n- **Frontend**: http://localhost:3000\n- **Backend API**: http://localhost:3001\n- **API Health Check**: http://localhost:3001/api/health\n\n### Using the Web Interface\n\n1. **Navigate Folders**: Click on folders in the left pane to select them\n2. **Create Folders**: Right-click any folder and select \"New Folder\"\n3. **Create Pages**: Select a folder and click \"+ New Page\"\n4. **Edit Content**: Click on a page to open it in the editor (center pane)\n5. **Rename Page**: Right-click on a page and select \"Rename\"\n6. **Move Page**: Right-click on a page and select \"Move to...\" to move it to another folder\n7. **Delete Page**: Right-click on a page and select \"Delete\"\n8. **Preview**: See live markdown preview in the right pane\n9. **Auto-save**: Content saves automatically after 2 seconds\n10. **Resize Panes**:\n    - Drag the edge of left/right panes to resize horizontally\n    - Drag the divider between folder tree and page list to resize vertically\n11. **Collapse Panes**: Use the arrow buttons to hide left/right panes\n12. **Theme Toggle**: Click the theme button (🌓/☀️/🌙/◐) in the header to cycle through auto/light/dark/high-contrast modes\n\n### Production Build\n\n```bash\n# Using Make\nmake build\n\n# Using npm\nnpm run build\n```\n\nThis creates optimized production builds in:\n- `server/dist/` - Compiled backend\n- `client/dist/` - Optimized frontend bundle\n\n## � Docker Deployment\n\nCodex can be run in Docker for simplified deployment. In production mode, Express serves both the API and the React UI from a single port (3001).\n\n### Pre-built Images\n\nOfficial multi-architecture (AMD64/ARM64) images are available on Docker Hub:\n\n```bash\ndocker pull bocan/codex:latest\n```\n\n**Available tags**:\n- `latest` - Latest stable release\n- `2.16.0` - Specific version (example)\n- `2.16` - Minor version (example)\n- `2` - Major version (example)\n\n**Image verification** (signed with Cosign):\n```bash\ncosign verify bocan/codex:latest \\\n  --certificate-identity-regexp=https://github.com/bocan/codex \\\n  --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n```\n\n**Supply chain security**:\n- Images are signed with Cosign for authenticity verification\n- SBOM (Software Bill of Materials) embedded in image metadata\n- Provenance attestations document the build process\n\nTo inspect the SBOM:\n```bash\ndocker buildx imagetools inspect bocan/codex:latest --format \"{{ json .SBOM }}\"\n```\n\n### Using Docker Compose (Recommended)\n\n```bash\n# Build and start the container\ndocker compose up -d --build\n\n# View logs\ndocker compose logs -f codex\n\n# Stop the container\ndocker compose down\n```\n\nThe application will be available at **http://localhost:3001** (both UI and API on the same port).\n\n### Using Raw Docker\n\n```bash\n# Build the image\ndocker build -t codex .\n\n# Run the container\ndocker run -d \\\n  --name codex \\\n  -p 3001:3001 \\\n  -v $(pwd)/data:/app/data \\\n  -e NODE_ENV=production \\\n  codex\n\n# View logs\ndocker logs -f codex\n\n# Stop and remove\ndocker stop codex \u0026\u0026 docker rm codex\n```\n\n### Docker Configuration\n\n**Environment Variables** (in `docker-compose.yml`):\n- `NODE_ENV=production` - Runs in production mode\n- `PORT=3001` - Server port (default)\n- `AUTH_PASSWORD=your-password` - Set to enable authentication (optional)\n- `TRUST_PROXY=true` - Enable when behind a reverse proxy with HTTPS\n\n**Volume Mounting**:\n- `./data:/app/data` - Persists your wiki data outside the container\n\n**Templates on first run**:\n- The Docker image includes built-in starter templates; on first startup, if `data/templates/` is missing or empty, Codex will copy the defaults into it.\n\n### Authentication in Docker\n\n**Important**: Due to secure cookie requirements, there are two ways to run Codex with authentication:\n\n#### Option 1: Run Passwordless Locally (for testing)\nRemove or comment out the `AUTH_PASSWORD` environment variable in `docker-compose.yml`:\n\n```yaml\nenvironment:\n  - NODE_ENV=production\n  - PORT=3001\n  # - AUTH_PASSWORD=your-password  # Commented out\n```\n\nThis allows direct HTTP access without authentication, suitable for local testing.\n\n#### Option 2: Deploy Behind a Reverse Proxy (for production)\nFor production with authentication, deploy behind a reverse proxy (nginx, Caddy, Traefik) that:\n1. Terminates TLS/HTTPS\n2. Forwards requests to Codex with the `X-Forwarded-Proto: https` header\n3. Set `TRUST_PROXY=true` in the environment variables\n\nExample with nginx:\n```nginx\nserver {\n    listen 443 ssl;\n    server_name wiki.example.com;\n\n    ssl_certificate /path/to/cert.pem;\n    ssl_certificate_key /path/to/key.pem;\n\n    location / {\n        proxy_pass http://localhost:3001;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}\n```\n\n**Why?** In production mode, session cookies use `secure: auto`, which requires HTTPS. Direct HTTP access with a password set will fail because the browser won't send the secure cookie. The reverse proxy provides HTTPS termination while communicating with Codex via HTTP internally.\n\n## 🤖 MCP Server (AI Agent Access)\n\nCodex includes a [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that allows AI agents like Claude, GitHub Copilot, and other MCP-compatible clients to interact with your documentation.\n\n### Quick Setup\n\n1. **Enable the MCP server** by setting environment variables:\n   ```bash\n   export MCP_ENABLED=true\n   export MCP_API_KEY=your-secure-api-key\n   ```\n\n2. **Start the server** (runs alongside the main app):\n   ```bash\n   npm run dev:mcp -w server  # Development with hot reload\n   ```\n\n3. **Connect your MCP client** to `http://localhost:3002/mcp`\n\n### Available Tools\n\nThe MCP server exposes 16 tools for AI agents:\n\n| Tool | Description |\n|------|-------------|\n| `search_pages` | Search documentation by query |\n| `get_page` | Read a page's content |\n| `create_page` | Create a new page |\n| `update_page` | Update an existing page |\n| `delete_page` | Delete a page |\n| `rename_page` | Rename a page |\n| `move_page` | Move a page to another folder |\n| `list_folders` | Get folder hierarchy |\n| `list_pages` | List pages in a folder |\n| `create_folder` | Create a new folder |\n| `delete_folder` | Delete an empty folder |\n| `rename_folder` | Rename a folder |\n| `list_attachments` | List attachments in a folder |\n| `upload_attachment` | Upload a file attachment |\n| `get_attachment` | Download an attachment |\n| `delete_attachment` | Delete an attachment |\n\n### Client Configuration\n\n\u003e **Important**: Claude Desktop only supports **stdio** transport and cannot connect to HTTP-based MCP servers directly. You must use [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) as a bridge. VS Code/GitHub Copilot supports native HTTP connections.\n\n**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):\n\nClaude Desktop requires `mcp-remote` to bridge stdio to HTTP:\n\n```json\n{\n  \"mcpServers\": {\n    \"codex\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"mcp-remote\",\n        \"https://your-codex-server.com/mcp\",\n        \"--header\",\n        \"Authorization: Bearer your-api-key\"\n      ]\n    }\n  }\n}\n```\n\nFor local development:\n```json\n{\n  \"mcpServers\": {\n    \"codex\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"mcp-remote\",\n        \"http://localhost:3002/mcp\",\n        \"--header\",\n        \"Authorization: Bearer your-api-key\"\n      ]\n    }\n  }\n}\n```\n\n**VS Code / GitHub Copilot** (settings or `.vscode/mcp.json`):\n\nVS Code supports native HTTP transport:\n\n```json\n{\n  \"servers\": {\n    \"codex\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:3002/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer your-api-key\" }\n    }\n  }\n}\n```\n\nFor full documentation, see [server/src/mcp/README.md](server/src/mcp/README.md).\n\n## 📡 API Documentation\nThe REST API is available at `http://localhost:3001/api`\n\n### Health Check\n\n```bash\nGET /api/health\n```\n\n**Response:**\n```json\n{\n  \"status\": \"ok\"\n}\n```\n\n### Folder Endpoints\n\n#### Get Folder Tree\n\n```bash\nGET /api/folders\n```\n\n**Response:**\n```json\n{\n  \"name\": \"root\",\n  \"path\": \"/\",\n  \"type\": \"folder\",\n  \"children\": [\n    {\n      \"name\": \"Projects\",\n      \"path\": \"Projects\",\n      \"type\": \"folder\",\n      \"children\": []\n    }\n  ]\n}\n```\n\n#### Create Folder\n\n```bash\nPOST /api/folders\nContent-Type: application/json\n\n{\n  \"path\": \"folder-name\"\n}\n# or nested: \"parent/subfolder\"\n```\n\n**Example:**\n```bash\ncurl -X POST http://localhost:3001/api/folders \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"path\": \"My Notes\"}'\n```\n\n#### Delete Folder\n\n```bash\nDELETE /api/folders/:path\n```\n\n**Example:**\n```bash\ncurl -X DELETE http://localhost:3001/api/folders/My%20Notes\n```\n\n#### Rename Folder\n\n```bash\nPUT /api/folders/rename\nContent-Type: application/json\n\n{\n  \"oldPath\": \"old-name\",\n  \"newPath\": \"new-name\"\n}\n```\n\n**Example:**\n```bash\ncurl -X PUT http://localhost:3001/api/folders/rename \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"oldPath\": \"My Notes\", \"newPath\": \"Work Notes\"}'\n```\n\n### Page Endpoints\n\n#### List Pages in Folder\n\n```bash\nGET /api/pages?folder=folder-path\n```\n\n**Response:**\n```json\n[\n  {\n    \"name\": \"page1.md\",\n    \"path\": \"folder/page1.md\",\n    \"type\": \"file\"\n  }\n]\n```\n\n#### Get Page Content\n\n```bash\nGET /api/pages/:path\n```\n\n**Response:**\n```json\n{\n  \"path\": \"folder/page1.md\",\n  \"content\": \"# Page Title\\n\\nContent here...\"\n}\n```\n\n**Example:**\n```bash\ncurl http://localhost:3001/api/pages/My%20Notes/hello.md\n```\n\n#### Create Page\n\n```bash\nPOST /api/pages\nContent-Type: application/json\n\n{\n  \"path\": \"folder/page.md\",\n  \"content\": \"# Page Title\\n\\nContent here...\"\n}\n```\n\n**Example:**\n```bash\ncurl -X POST http://localhost:3001/api/pages \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"path\": \"My Notes/hello.md\", \"content\": \"# Hello World\\n\\nThis is my first page!\"}'\n```\n\n#### Update Page\n\n```bash\nPUT /api/pages/:path\nContent-Type: application/json\n\n{\n  \"content\": \"# Updated Content\"\n}\n```\n\n**Example:**\n```bash\ncurl -X PUT http://localhost:3001/api/pages/My%20Notes/hello.md \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"content\": \"# Updated Hello\\n\\nNew content!\"}'\n```\n\n#### Delete Page\n\n```bash\nDELETE /api/pages/:path\n```\n\n**Example:**\n```bash\ncurl -X DELETE http://localhost:3001/api/pages/My%20Notes/hello.md\n```\n\n#### Rename Page\n\n```bash\nPUT /api/pages/rename/file\nContent-Type: application/json\n\n{\n  \"oldPath\": \"old-page.md\",\n  \"newPath\": \"new-page.md\"\n}\n```\n\n**Example:**\n```bash\ncurl -X PUT http://localhost:3001/api/pages/rename/file \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"oldPath\": \"My Notes/hello.md\", \"newPath\": \"My Notes/welcome.md\"}'\n```\n\n#### Move Page\n\n```bash\nPUT /api/pages/move\nContent-Type: application/json\n\n{\n  \"oldPath\": \"folder1/page.md\",\n  \"newFolderPath\": \"folder2\"\n}\n# Returns: { \"success\": true, \"newPath\": \"folder2/page.md\" }\n```\n\n**Example:**\n```bash\ncurl -X PUT http://localhost:3001/api/pages/move \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"oldPath\": \"My Notes/hello.md\", \"newFolderPath\": \"Projects\"}'\n```\n\n### AI Endpoints\n\n#### Stream Chat (SSE)\n\n```bash\nPOST /api/ai/chat\nContent-Type: application/json\n\n{\n  \"config\": {\n    \"type\": \"anthropic\",\n    \"apiKey\": \"sk-ant-...\"\n  },\n  \"messages\": [\n    { \"role\": \"user\", \"content\": \"What is this document about?\" }\n  ],\n  \"documentContext\": \"# My Document\\n\\nContent here...\",\n  \"systemPrompt\": \"You are a helpful assistant.\"\n}\n```\n\n**Response:** Server-Sent Events stream with events:\n- `{ \"type\": \"text\", \"content\": \"...\" }` - Text chunks\n- `{ \"type\": \"thinking\", \"content\": \"...\" }` - Thinking block content (Anthropic)\n- `{ \"type\": \"thinking_done\" }` - Thinking block complete\n- `{ \"type\": \"usage\", \"inputTokens\": 100, \"outputTokens\": 50 }` - Token usage\n- `{ \"type\": \"done\" }` - Stream complete\n- `{ \"type\": \"error\", \"error\": \"...\" }` - Error occurred\n\n**Config for Ollama:**\n```json\n{\n  \"config\": {\n    \"type\": \"ollama\",\n    \"host\": \"localhost\",\n    \"port\": 11434,\n    \"model\": \"llama3.2\"\n  },\n  \"messages\": [...]\n}\n```\n\n#### List Ollama Models\n\n```bash\nGET /api/ai/ollama/models?host=localhost\u0026port=11434\n```\n\n**Response:**\n```json\n{\n  \"models\": [\"llama3.2\", \"codellama\", \"mistral\"]\n}\n```\n\n#### Test Ollama Connection\n\n```bash\nGET /api/ai/ollama/test?host=localhost\u0026port=11434\n```\n\n**Response:**\n```json\n{\n  \"success\": true\n}\n```\n\n## 🧪 Testing\n\n### Run All Tests\n\n```bash\n# Using Make\nmake test\n\n# Using npm\nnpm test\n```\n\n### Run Tests for Specific Component\n\n```bash\n# Backend tests only\nmake test-server\n# or: cd server \u0026\u0026 npm test\n\n# Frontend tests only\nmake test-client\n# or: cd client \u0026\u0026 npm test\n\n# Frontend tests with UI\ncd client \u0026\u0026 npm run test:ui\n\n# Backend tests in watch mode\ncd server \u0026\u0026 npm run test:watch\n```\n\n### Test Coverage\n\nThe project includes tests for:\n- ✅ All API endpoints (folders and pages)\n- ✅ File system operations\n- ✅ React components (FolderTree, Editor, Preview)\n- ✅ Error handling and edge cases\n\n## 🔧 Troubleshooting\n\n### Common Issues\n\n#### Port Already in Use\n\nIf you see \"Port 3000 or 3001 already in use\":\n\n```bash\n# Find and kill process on port 3001\nlsof -ti:3001 | xargs kill -9\n\n# Find and kill process on port 3000\nlsof -ti:3000 | xargs kill -9\n```\n\n#### Dependencies Not Installing\n\n```bash\n# Clean everything and reinstall\nmake clean\nmake install\n\n# Or manually\nrm -rf node_modules server/node_modules client/node_modules\nnpm install\ncd server \u0026\u0026 npm install\ncd ../client \u0026\u0026 npm install\n```\n\n#### TypeScript Errors\n\n```bash\n# Rebuild TypeScript projects\ncd server \u0026\u0026 npm run build\ncd ../client \u0026\u0026 npm run build\n```\n\n#### Tests Failing\n\n```bash\n# Make sure dependencies are installed\nmake install\n\n# Run tests with verbose output\ncd server \u0026\u0026 npm test -- --verbose\ncd client \u0026\u0026 npm test -- --verbose\n```\n\n#### Data Directory Issues\n\nThe `data/` directory is created automatically. If you encounter permission issues:\n\n```bash\n# Make sure the data directory is writable\nchmod 755 data/\n```\n\n### Getting Help\n\n- Check the [GitHub Issues](https://github.com/yourusername/codex/issues)\n- Review the API documentation above\n- Ensure all prerequisites are installed\n- Try a clean install: `make clean \u0026\u0026 make install`\n\n## ⌨️ Keyboard Shortcuts\n\n### Search Modal\n| Shortcut | Description |\n|----------|-------------|\n| `⌘K` / `Ctrl+K` | Open search modal |\n| `↑` `↓` | Navigate search results |\n| `Enter` | Select highlighted search result |\n| `Esc` | Close search modal |\n\n### Folder Tree \u0026 Page List Navigation\n| Shortcut | Description |\n|----------|-------------|\n| `↑` / `k` | Move selection up (vim-style) |\n| `↓` / `j` | Move selection down (vim-style) |\n| `Enter` | Open selected folder or page |\n\n**Note:** Click in the folder tree or page list to focus it, then use keyboard navigation. Mouse hover also updates the keyboard selection for seamless interaction.\n\n## 🔍 Search Features\n\nCodex includes a powerful full-text search that:\n- **Searches across all pages** in all folders recursively\n- **Ranks results by relevance** (number of matches)\n- **Highlights matching text** in context snippets\n- **Shows search context** (50 characters before and after match)\n- **Keyboard-driven** with quick access via `⌘K` / `Ctrl+K`\n- **Instant results** with 300ms debounce for smooth typing\n- **Arrow key navigation** to browse results\n- **Click or Enter** to jump to matching pages\n\n### Using Search\n\n1. Click the search button in the header or press `⌘K` / `Ctrl+K`\n2. Type your query (case-insensitive)\n3. Navigate results with `↑` `↓` arrow keys\n4. Press `Enter` or click to open the page\n5. Press `Esc` to close the search modal\n\n## 📑 Table of Contents\n\nThe Table of Contents automatically:\n- **Extracts all headings** from the current document\n- **Creates hierarchical structure** based on heading levels (H1-H6)\n- **Highlights the current section** as you scroll\n- **Provides quick navigation** - click any heading to jump to it\n- **Collapsible sidebar** - click the toggle to show/hide\n- **Remembers your preference** - state persists across sessions\n- **Smooth scrolling** to target sections\n- **Auto-hides on small screens** (responsive design)\n\nThe TOC appears as a floating widget on the right side of the preview pane when viewing pages with multiple headings.\n\n## 💻 Tech Stack\n\n### Backend\n- **[Express](https://expressjs.com/)** `^5.2.1` - Fast, unopinionated web framework\n- **[TypeScript](https://www.typescriptlang.org/)** `^6.0.2` - Type-safe JavaScript\n- **[CORS](https://www.npmjs.com/package/cors)** `^2.8.6` - Cross-origin resource sharing\n- **[tsx](https://www.npmjs.com/package/tsx)** `^4.21.0` - Development server with auto-reload\n\n**Testing:**\n- **[Jest](https://jestjs.io/)** `^30.3.0` - Testing framework\n- **[Supertest](https://www.npmjs.com/package/supertest)** `^7.2.2` - HTTP assertion library\n- **[ts-jest](https://www.npmjs.com/package/ts-jest)** `^29.1.1` - TypeScript preprocessor for Jest\n\n### Frontend\n- **[React](https://reactjs.org/)** `^19.2.4` - UI library\n- **[TypeScript](https://www.typescriptlang.org/)** `^6.0.2` - Type-safe JavaScript\n- **[Vite](https://vitejs.dev/)** `^8.0.0` - Next-generation frontend tooling\n- **[React Markdown](https://www.npmjs.com/package/react-markdown)** `^10.1.0` - Markdown renderer\n- **[remark-gfm](https://www.npmjs.com/package/remark-gfm)** `^4.0.0` - GitHub Flavored Markdown\n- **[Axios](https://axios-http.com/)** `^1.13.4` - HTTP client\n\n**Testing:**\n- **[Vitest](https://vitest.dev/)** `^4.1.1` - Unit test framework\n- **[Testing Library](https://testing-library.com/)** - React testing utilities\n- **[jsdom](https://www.npmjs.com/package/jsdom)** `^29.0.1` - DOM implementation\n\n### Development Tools\n- **[Concurrently](https://www.npmjs.com/package/concurrently)** `^9.2.1` - Run multiple commands\n- **ESLint** - Code linting\n- **Prettier** - Code formatting (optional)\n\n## 🎮 Makefile Commands\n\nAll available Make commands:\n\n```bash\nmake help           # Show all available commands\nmake install        # Install all dependencies\nmake dev            # Run both server and client in dev mode\nmake dev-server     # Run server only\nmake dev-client     # Run client only\nmake build          # Build both server and client\nmake build-server   # Build server only\nmake build-client   # Build client only\nmake test           # Run all tests\nmake test-server    # Run server tests\nmake test-client    # Run client tests\nmake clean          # Remove node_modules and build artifacts\nmake clean-server   # Clean server only\nmake clean-client   # Clean client only\n```\n\n### Makefile Quick Reference\n\n```makefile\n# Quick start\nmake install \u0026\u0026 make dev\n\n# Clean slate\nmake clean \u0026\u0026 make install \u0026\u0026 make test\n\n# Production build\nmake clean \u0026\u0026 make install \u0026\u0026 make build\n```\n\n## 🤝 Contributing\n\nContributions are welcome! Here's how you can help:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Run tests (`make test`)\n5. Commit your changes (`git commit -m 'Add amazing feature'`)\n6. Push to the branch (`git push origin feature/amazing-feature`)\n7. Open a Pull Request\n\n### Code Style\n\n- Use TypeScript for all new code\n- Follow existing code formatting\n- Add tests for new features\n- Update documentation as needed\n\n## 📄 License\n\nMIT\n\n## 🙏 Acknowledgments\n\n- Built with [React](https://reactjs.org/) and [Express](https://expressjs.com/)\n- Markdown rendering by [react-markdown](https://github.com/remarkjs/react-markdown)\n- Icons from Unicode emoji\n\n---\n\n**Made with ❤️ for taking better notes**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbocan%2Fcodex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbocan%2Fcodex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbocan%2Fcodex/lists"}