AI文档平台

自托管的知识库平台,支持基于角色的访问控制、跟踪共享链接和MCP集成,可自动或手动编写文档。

  • by Nikhil-Singh-2503
  • TypeScript
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 Nikhil-Singh-2503/AIDotMD

使用说明



AIDotMd

The AI-native docs platform. One command to launch.
Self-hosted knowledge base with login, role-based access control, tracked share links, and MCP integration.
Claude, Cursor, and Windsurf write your docs automatically — or author them yourself.

Quick Start · MCP Integration · Features · Sharing · Configuration · Tech Stack


为什么是AIDotMd?

每个使用AI工具的开发人员都会遇到同样的问题。AIDotMd是这样修复它的:

| 🚨 疼痛|❌ 通常会发生什么✅ AIDotMd如何修复它| |---|---|---| | 💸 厂商锁定 |Notion、Confluence、GitBook将您的数据存储在他们的服务器上——付费计划,没有控制权。 | 完全自托管 --SQLite在您的计算机上,可选S3/R2。您的数据永远不会离开您的基础设施。 | | 🧠 研究蒸发 |你花了几个小时在Cursor或Claude中进行研究,然后会话结束,上下文消失了。 | AI代理直接写入AIDotMd 通过MCP——自动、实时、无需复制粘贴。每个用户都有自己的API密钥用于审计跟踪。 | | 📁 无组织视图 |即使你救了 .md 本地文件,无法一起查看。 | 基于章节的知识库 使用干净的阅读器——将所有文档组织在一个地方,并进行搜索。 | | 🔗 分享很麻烦 |要共享文档,您需要将其粘贴到Google Docs、Drive或Loop中——每次都是手动粘贴。 | 一键复制链接+PDF导出。 只需设置一次公共URL,即可永久共享,无需粘贴。 |


✨ 特性

捕获、组织和共享AI生成的知识所需的一切——每个用户的MCP密钥、版本差异、RBAC等——零云依赖。

功能 描述
🤖 AI原生MCP服务器 9个内置工具——代理可以列出、创建、搜索和流式传输文档
🔑 每个用户的MCP密钥 每个用户都获得自己的API密钥,并回退到共享的遗留密钥
⚡ 直播渲染器 通过SSE观看代理写入时markdown逐块渲染
📜 版本历史 查看、还原和比较文档或节的任何以前版本
📋 版本差异 并排比较两个版本,并突出显示干净的行级别差异
👤 文档作者跟踪 查看每个文档的创建者和最后更新时间戳
🐳 单命令设置 docker-compose up --build --全栈,无需配置
🔒 自托管 您的文档、数据和存储。默认为SQLite,S3/R2可选
🔍 全文搜索 跨所有部分和文档的即时搜索
🎨 美丽的读者 干净、无干扰的文档阅读器,支持黑暗模式
📂 分段和段塞 将文件组织成章节;每个文档都有一个人类可读的URL
📸 图片上传 拖放存储在文件系统或S3上的图像上传
🔏 草案/已发布 在草稿(仅限管理员)和已发布(公开)之间切换文档
🌐 随时随地分享 配置公共URL(Cloudflare、ngrok等),复制链接始终有效
🖨️ PDF导出 直接从浏览器将任何文档打印为PDF——干净、样式化的输出
🚇 Cloudflare 隧道 内置隧道服务——立即通过公共URL共享您的本地文档
🔄 自动更新 使用部署感知说明从GitHub检查新版本
👥 用户帐户和登录 带有会话管理的电子邮件+密码身份验证
🛡️ 基于角色的访问控制 三个角色:管理员、编辑和具有精细权限的查看器
👤 用户管理 管理员仪表板,用于创建、编辑和管理用户
🔗 每个文档共享链接 创建具有过期、最大使用次数和查看/编辑权限的跟踪共享链接
📋 权限覆盖 设置每个文档和每个部分的访问覆盖(读/写)
🔔 吐司通知 保存、删除、错误和操作的实时反馈

🚀 快速开始

一个命令。全栈。不到一分钟就准备好了。

git clone https://github.com/Nikhil-Singh-2503/aidotmd.git
cd aidotmd
docker-compose up --build

打开 http://localhost:3000 --就是这样。

URL 你得到什么
http://localhost:3000 主页
http://localhost:3000/login 登录您的帐户
http://localhost:3000/docs 文档阅读器(需要登录)
http://localhost:3000/admin 管理员仪表板(管理员和编辑角色)
http://localhost:3000/my-dashboard 最小仪表板(查看器角色)
http://localhost:3000/admin/users 用户管理(仅限管理员)
http://localhost:3000/admin/permissions 权限覆盖仪表板(仅限管理员)
http://localhost:3000/settings 存储、数据库、MCP和共享配置(仅限管理员)

第一轮: 自动创建管理员帐户(admin@aidotmd.local)随机密码打印到服务器日志中。检查日志,然后访问 /login 登录。设置 ADMIN_PASSWORD 在你的 .env 文件使用已知密码而不是随机密码。

数据持续存在 在 ./data/ 在您的主机上——容器重启时不会丢失任何数据。


🌐 共享您的文档

快速共享(零配置)

AIDotMd包括一个 Cloudflare 隧道 在Docker中自动运行的服务——无需帐户、域或配置。

启动堆栈时,会为容器分配一个免费的公共URL:

docker-compose up --build

# Once running, get your public URL:
docker-compose logs cloudflared | grep trycloudflare.com
# → https://abc123xyz.trycloudflare.com

与任何人共享该URL——他们可以在任何地方从任何设备读取您发布的文档。

注: 每次Docker重启时,URL都会发生变化。有关永久URL,请参阅下面的升级指南。

共享链接(每份文档)

每个文档都有一个 分享 用于创建跟踪共享链接的按钮:

按钮 操作
🔗 分享 打开共享模式以创建和管理共享链接
🖨️ 打印/另存为PDF 打开浏览器打印对话框——选择“另存为PDF”以获得干净的PDF
✏️ 编辑 打开该文档的管理编辑器

创建共享链接:

  1. 单击任何文档上的“共享”按钮
  2. 选择 仅查看 或 可以编辑 许可
  3. 设置可选 到期 (1小时、24小时、7天、30天或从不)
  4. 设置可选 最大用途 限制(1、5、10、25、100或无限制)
  5. 点击 创建共享链接

管理共享链接:

  • 文档的所有活动链接都显示在共享模式中
  • 每个链接显示:权限级别、使用次数(3/10 uses),以及到期日期
  • 点击 复制 要复制链接URL,请执行以下操作: https://...?share=dm_share_<token>
  • 点击 删除 立即撤销链接

共享链接的工作原理:

  • 收件人确实 不 需要登录
  • 侧边栏仅显示共享文档/部分
  • 搜索仅限于共享资源
  • 每个链接都适用于其特定的文档或部分——文档a的链接无法访问文档B
  • 跟踪使用情况: use_count 每次唯一令牌验证递增一次
  • 过期或已达到最大值的链接显示明确的错误消息

配置公共URL

默认情况下 复制 按钮使用您当前的浏览器URL。要使用自定义公共URL:

  1. 首选 设置→ 共享
  2. 粘贴您的公共URL(Cloudflare、ngrok或任何自定义域)
  3. 切换 “使用公共URL进行共享” → ON
  4. 点击 保存

自动更新系统

AIDotMd包括一个内置的更新检查器,可帮助您保持最新状态:

特性 描述
版本显示 侧边栏和仪表板中显示的当前版本
更新检查 管理仪表板中的手动检查按钮
更新日志 直接在应用程序中查看发行说明
部署感知 根据部署显示Docker或Source更新命令
自动检查 可选的每小时背景调查
设置 切换自动检查并包括预发布

要检查更新,请转到 管理员→ 更新 在管理面板中。

系统检查GitHub版本并提供:

  • 当前版本与最新版本比较
  • 主要/次要更新指标
  • 部署特定的更新说明(docker compose vs git命令)
  • 链接到GitHub上的完整更新日志

草稿与已发布

控制登录用户可见的文档:

  • 发表 --对有权访问文档的经过身份验证的用户可见(所有文档的默认设置)
  • 草案 --仅在管理面板中可见;直接URL返回404

非管理员用户的导航树和搜索结果中跳过草稿。在文档编辑器中切换可见性 能见度 → 已发布/草稿。


永久公共URL(可选升级)

对于重新启动时不会更改的固定URL,请设置一个命名的Cloudflare隧道:

先决条件: 自由 Cloudflare帐户 +添加到Cloudflare DNS的域。

# 1. Install cloudflared and authenticate
brew install cloudflare/cloudflare/cloudflared   # macOS
cloudflared tunnel login                          # opens browser

# 2. Create tunnel and add DNS record
cloudflared tunnel create aidotmd
cloudflared tunnel route dns aidotmd docs.yourdomain.com

# 3. Get the tunnel token
cloudflared tunnel token aidotmd

更新您的 .env 文件:

CLOUDFLARE_TUNNEL_TOKEN=<paste-token-here>

更新 docker-compose.yml --更改 cloudflared 服务:

cloudflared:
  image: cloudflare/cloudflared:latest
  restart: unless-stopped
  command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}
  environment:
    CLOUDFLARE_TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}
  depends_on:
    - frontend
  networks:
    - aidotmd_net

同时更新中的后端环境 docker-compose.yml:

BASE_URL: "https://docs.yourdomain.com"
USE_PUBLIC_URL: "true"
CORS_ORIGINS: "https://docs.yourdomain.com,http://localhost:3000"

重新启动: docker-compose up --build --您的文档永久可用,网址为 https://docs.yourdomain.com.


🔐 身份验证和基于角色的访问控制

AIDotMd包括一个内置的身份验证系统,有三个用户角色:

角色

角色 权限
管理员 完全访问权限--管理文档、部分、用户、设置、垃圾箱、更新
编辑 创建、编辑和删除文档和部分。无法管理用户、设置、垃圾箱或更新
观众 对已发布文档的只读访问。无法创建、编辑或删除任何内容

首次运行设置

首次启动时,系统会自动创建一个管理员帐户,并将凭据打印到服务器日志中:

============================================================
AIDotMD Admin Account (auto-created)
  Email:    admin@aidotmd.local
  Password: <random token>
============================================================

访问 http://localhost:3000/login 然后登录。对于后续的初创公司,您可以通过以下方式设置固定的管理员密码 ADMIN_PASSWORD 环境变量。

用户管理

管理员可以在以下位置管理用户 /admin/users:

  • 创建用户 --设置电子邮件、姓名、密码和角色
  • 编辑角色 --内联更改用户的角色
  • 重置密码 --生成临时密码
  • 启用/禁用 账户
  • 删除用户

密码恢复

如果您丢失了管理员密码,您有两个选择:

  1. 通过本地主机重置 --在登录页面上 localhost:3000/login,单击 “忘记密码?在本地主机上重置” 以生成新的临时密码。

  2. 集 ADMIN_PASSWORD env 是 --添加 ADMIN_PASSWORD=yourpassword 到你的 .env 文件。每次启动时,管理员密码都会强制设置为此值。

按角色路由访问

路由 公共 共享链接 查看器 编辑器 管理员
/ 主页 ✅ ✅ ✅ ✅ ✅
/docs/* 读者 ❌ ✅ ✅ ✅ ✅
/login ✅ ✅ ➡️ 重定向 ➡️ 重定向 ➡️ 重定向
/my-dashboard ❌ ❌ ✅ ✅ ❌
/admin 仪表板 ❌ ❌ ❌ ✅ ✅
/admin/documents/* ❌ ❌ ❌ ✅ ✅
/admin/sections/* ❌ ❌ ❌ ✅ ✅
/admin/trash/* ❌ ❌ ❌ ❌ ✅
/admin/users/* ❌ ❌ ❌ ❌ ✅
/admin/permissions ❌ ❌ ❌ ❌ ✅
/admin/updates/* ❌ ❌ ❌ ❌ ✅
/settings ❌ ❌ ❌ ❌ ✅

AIDotMd内置 MCP(模型上下文协议)服务器 任何兼容的AI代理都可以连接到。

每个用户的MCP密钥 -每个用户都有自己的API密钥,在创建帐户时自动生成。管理员可以从用户管理仪表板查看任何用户的密钥。非管理员用户可以在 简介 modal(点击侧边栏中的头像/姓名)或 设置→ MCP (仅限管理员)。MCP服务器首先对每个用户的密钥进行身份验证,然后回退到共享的旧密钥以实现向后兼容性。

连接克劳德桌面

把这个加进去 ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "aidotmd": {
      "type": "http",
      "url": "http://localhost:3000/mcp/",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY_HERE"
      }
    }
  }
}

连接光标

添加 .cursor/mcp.json 在您的项目根目录中,或通过 光标设置→ MCP:

{
  "mcpServers": {
    "aidotmd": {
      "url": "http://localhost:3000/mcp/?api_key=YOUR_API_KEY_HERE"
    }
  }
}

密钥嵌入在URL中(?api_key=…)为了光标兼容性。

可用工具

list_sections      → List all documentation sections
create_section     → Create a new section
list_documents     → List documents (optionally filtered by section)
get_document       → Fetch a document by ID or slug
create_document    → Create a new document with content
update_document    → Update title, content, or append to a document
stream_write       → Stream content chunk-by-chunk (live browser render)
commit_stream      → Finalize stream and save to database
search_docs        → Full-text search across all documents

直播在行动

当代理人来电时 stream_write,浏览器呈现markdown 生活,一个字符接一个字符。绿色 ● Live 表头中的指示器脉冲。当代理人来电时 commit_stream,它切换到 已保存✓ 并且该文档被持久化。

# Example: agent researches Redis and writes a doc in real-time
await stream_write(doc_id="abc123", chunk="# Redis Commands & Data Types\n\n")
await stream_write(doc_id="abc123", chunk="Redis supports **5 core data types**...\n")
await commit_stream(doc_id="abc123")
# → Doc is live in the browser and saved to DB

⚙️ 配置

所有配置都可以通过环境变量进行设置 docker-compose.yml 或通过 设置UI 在 /settings.

环境变量

变量 默认值 描述
DATABASE_URL sqlite+aiosqlite:///./aidotmd.db SQLAlchemy数据库连接URL
DOCS_OUTPUT_DIR ./data/docs 在哪里 .md 文件已导出
STATIC_DIR ./data/static/img 图像上传目录
BASE_URL http://localhost:3000 面向公众的基本URL(用于共享链接)
USE_PUBLIC_URL false 使用 BASE_URL 用于复制链接,而不是 window.location
CORS_ORIGINS http://localhost:5173 允许的CORS源的逗号分隔列表
S3_BUCKET (空) S3/R2存储桶名称(可选)
S3_REGION (空) S3区域
S3_ACCESS_KEY_ID (空) S3访问密钥ID
S3_SECRET_ACCESS_KEY (空) S3秘密访问密钥
S3_ENDPOINT_URL (空) R2/MinIO的自定义端点
MCP_API_KEY (自动生成) 用于MCP身份验证的API密钥
ADMIN_PASSWORD (第一轮随机) 设置固定的管理员密码。每次启动时都会覆盖自动生成的密码
AIDOTMD_DEPLOYMENT (自动检测) 覆盖部署类型: docker 或 source

版本和更新 --The VERSION 字段在构建时在容器中设置,不能通过环境变量进行配置。更新系统会自动检测您是通过Docker还是源代码运行,并显示相应的更新命令。

存储:本地文件系统

默认情况下,上传的图像和导出的markdown文件存储在 ./data/ 在您的主机上(作为Docker卷挂载)。容器内的路径为 /app/data/.

要使用其他主机路径,请在中更改卷装载 docker-compose.yml:

volumes:
  - /your/custom/path:/app/data   # ← change left side to any host path

存储:兼容Cloudflare R2/S3

STORAGE_BACKEND=s3
S3_BUCKET=your-bucket
S3_REGION=auto
S3_ACCESS_KEY_ID=your-key
S3_SECRET_ACCESS_KEY=your-secret
S3_ENDPOINT_URL=https://<account>.r2.cloudflarestorage.com

数据库:PostgreSQL

DATABASE_URL=postgresql+asyncpg://user:password@host:5432/aidotmd

改变 DATABASE_URL 需要重新启动容器: docker-compose restart backend


🛠️ 本地开发

更喜欢实时重新加载?单独运行服务:

后端

cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
alembic upgrade head
uvicorn app.main:app --reload
# → API: http://localhost:8000
# → Swagger UI: http://localhost:8000/docs

前端

cd frontend
npm install
npm run dev
# → http://localhost:5173

Vite-dev服务器代理 /api, /mcp,以及 /static 到 localhost:8000.


🗂️ 项目结构

Click to expand project tree
aidotmd/
├── docker-compose.yml          # Single-command full-stack launch
├── data/                       # Persisted data (gitignored)
│   ├── aidotmd.db              # SQLite database
│   ├── aidotmd.config.json     # Runtime settings (MCP key, storage, etc.)
│   ├── docs/                   # Markdown file exports
│   │   └── {section}/{slug}.md
│   └── static/img/             # Uploaded images
│
├── backend/
│   ├── app/
│   │   ├── main.py             # FastAPI app + lifespan + auth/MCP middleware
│   │   ├── config.py           # Pydantic settings (env vars)
│   │   ├── api/                # REST routers
│   │   │   ├── auth.py         # Login, logout, me, change-password, reset-admin
│   │   │   ├── admin_users.py  # Admin user management CRUD
│   │   │   ├── documents.py
│   │   │   ├── sections.py
│   │   │   ├── stream.py       # SSE endpoints (/live, /live/status)
│   │   │   ├── nav.py          # Sidebar tree builder (permission-filtered)
│   │   │   ├── permissions.py  # Per-doc/section permission overrides CRUD
│   │   │   ├── share_links.py  # Share link creation, listing, revocation
│   │   │   ├── search.py       # Full-text search (permission-filtered)
│   │   │   ├── trash.py        # Restore / permanent delete
│   │   │   └── settings.py     # Settings CRUD + storage test
│   │   ├── mcp/
│   │   │   └── server.py       # FastMCP server (9 tools)
│   │   ├── schemas/
│   │   │   ├── auth.py         # Pydantic models for auth requests/responses
│   │   │   ├── document.py     # Document + DocumentVersion schemas
│   │   │   ├── permission.py   # Permission CRUD schemas
│   │   │   └── share_link.py   # Share link creation schemas
│   │   └── services/
│   │       ├── auth_service.py        # Password hashing, session management
│   │       ├── user_service.py        # User CRUD, first-run admin creation
│   │       ├── permission_service.py  # Role-based access control checks
│   │       ├── stream_manager.py      # In-memory pub/sub for live streaming
│   │       ├── document_service.py
│   │       └── settings_service.py
│   ├── alembic/                # Database migrations
│   └── requirements.txt
│
└── frontend/
    ├── nginx.conf              # SPA routing + API reverse proxy
    ├── Dockerfile              # Multi-stage: node build → nginx serve
    └── src/
        ├── pages/
        │   ├── HomePage.tsx         # Landing page
        │   ├── LoginPage.tsx        # Email + password sign-in
        │   ├── MyDashboard.tsx      # Minimal dashboard for editors/viewers
        │   ├── reader/DocPage.tsx   # Live SSE rendering + Copy Link + Print
        │   ├── admin/
        │   │   ├── Dashboard.tsx    # Admin overview with stats + quick actions
        │   │   ├── Users.tsx        # User creation, role management, password reset
        │   │   ├── Permissions.tsx  # Centralized permission overrides management
        │   │   ├── Documents.tsx    # Document list with drag-and-drop reorder
        │   │   ├── DocumentEdit.tsx # Markdown editor + metadata + permission manager
        │   │   └── Sections.tsx     # Hierarchical section management + per-section permissions
        │   └── Settings.tsx         # DB / Storage / MCP / Sharing config
        ├── components/
        │   ├── AuthGuard.tsx        # Redirects unauthenticated users to /login
        │   ├── AdminRoute.tsx       # Restricts routes to admin/editor roles
        │   ├── AdminOnlyGuard.tsx   # Restricts routes to admin role only
        │   ├── AdminGuard.tsx       # Checks auth + share token for admin access
        │   ├── DocsGuard.tsx        # Checks auth + share token for doc access
        │   ├── ProfileModal.tsx     # User profile modal (MCP key, info)
        │   ├── DiffModal.tsx        # Version diff comparison modal
        │   ├── VersionHistoryModal.tsx # Version history with restore + diff
        │   ├── admin/PermissionManager.tsx  # Per-doc/section permission dialog
        │   ├── ShareModal.tsx       # Share link creation and management modal
        │   ├── MarkdownRenderer.tsx
        │   ├── DocsSidebar.tsx
        │   ├── ui/Toaster.tsx       # Toast notification container
        │   └── ui/Toast.tsx         # Toast component with variants
        ├── context/
        │   ├── AuthContext.tsx      # Auth state management (login, logout, user)
        │   └── ToastContext.tsx     # Toast queue management
        └── api/
            └── client.ts            # Type-safe API client

🏗️ 技术栈

Layer Technology Why
Backend FastAPI + SQLAlchemy (async) Fast, async-first, great OpenAPI docs
Database SQLite (default) / PostgreSQL Zero-config local; scales to Postgres for production
MCP Server FastMCP (StreamableHTTP) Protocol-compliant MCP with session management
Streaming Server-Sent Events (SSE) Native browser support, no WebSocket complexity
Frontend React 18 + Vite + Tailwind v4 Fast builds, utility-first styling
UI Components shadcn/ui + Radix Accessible, unstyled primitives
Markdown react-markdown + remark-gfm + highlight.js GFM tables, code highlighting, syntax colors
Serving nginx (Docker) SPA fallback + reverse proxy in one container

🆚 AIDotMd有何不同

AIDotMd 概念 GitBook Docusaurus
您的数据,您的存储 ✅ 本地/S3 ❌ 他们的云❌ 他们的云⚠️ 手册
AI代理编写文档 ✅ 本地MCP ❌ ❌ ❌
直播渲染 ✅ 上海证券交易所❌ ❌ ❌
版本历史 ✅ ⚠️ 已付 ⚠️ 已付 ❌
基于角色的访问控制 ✅ 管理员/编辑器/查看器 ✅ ⚠️ 已付 ❌
每份文档权限 ✅ 读/写覆盖 ✅ ⚠️ 已付 ❌
跟踪共享链接 ✅ 过期+使用上限 ✅ ❌ ❌
自托管 ✅ ❌ 仅支付 ✅
单命令启动 ✅ Docker ❌ ❌ ⚠️ 手册
通过链接分享 ✅ ✅ ✅ ❌
PDF导出 ✅ ⚠️ 已付 ⚠️ 已付 ❌
内容无构建步骤 ✅ ✅ ✅ ❌
开源 ✅ MIT ❌ ❌ ✅

🤝 贡献

欢迎投稿!请先打开一个问题,讨论您想更改的内容。

提交拉取请求

提交PR时,请使用我们的 拉取请求模板:

# 1. Fork the repo
# 2. Clone your fork
git clone https://github.com/Nikhil-Singh-2503/aidotmd.git
cd aidotmd

# 3. Create a feature branch
git checkout -b feature/your-feature-name

# 4. Make changes and commit
# Follow Conventional Commits: feat/, fix/, docs/, etc.
git commit -m "feat: add awesome new feature"

# 5. Push and create PR
git push -u origin feature/your-feature-name

拉取请求清单

提交前,请确保:

  • []代码遵循项目惯例
  • []已进行自我审查
  • []为复杂逻辑添加了注释
  • []文件已更新(如需要)
  • []构建通行证: npm run build (前端)/测试通过
  • []为UI更改添加了截图

PR标题格式

使用 约定式提交:

feat(admin): add new dashboard feature
fix(search): resolve empty results issue
docs(readme): update installation steps
refactor(api): simplify document service

报告问题

  • 使用GitHub问题
  • 包括复制步骤
  • 如果与UI相关,请添加屏幕截图
  • 适当标记(错误、功能、增强)

📄 许可证

麻省理工学院——见 许可证 了解详情。


Built with ❤️ for the AI-native era of documentation.