OneNote管理服务器

OneNote MCP Server是一个功能强大的模型上下文协议服务器,允许AI助手安全地与Microsoft OneNote数据进行交互,实现笔记本、章节和页面的读取、写入、搜索和编辑操作。

  • by IAmKSquared
  • JavaScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 IAmKSquared/onenotemcp

使用说明

OneNote MCP服务器

OneNote MCP服务器是一个功能强大的模型上下文协议(MCP)服务器 使AI助手能够安全地与您的Microsoft OneNote数据进行交互。它 允许阅读、写作、搜索和全面编辑您的 OneNote笔记本、分区和页面直接通过您的AI界面。

此服务器为高级OneNote管理提供了一套丰富的工具, 包括健壮的文本提取、HTML内容处理和细粒度页面 操纵。

特性

  • 身份验证: 用于Microsoft Graph API访问的安全设备代码流。
  • 读取操作:
    • 列出笔记本、分区、分区组和分区内的页面。
    • 使用高级过滤功能按名称搜索部分,按标题搜索页面。
    • 按修改日期范围和特定笔记本筛选页面。
    • 获取各种格式的页面内容(完整HTML、可读文本、摘要)。
  • 笔记本和章节管理:
    • 创建新的笔记本、分区和分区组。
    • 以编程方式构建和组织OneNote结构。
  • 写入和编辑操作:
    • 使用自定义HTML或markdown内容创建新的OneNote页面。
    • 更新整个页面内容,保留或替换标题。
    • 使用可选的时间戳和分隔符将内容附加到现有页面。
    • 更新页面标题。
    • 查找和替换页面中的文本(区分大小写或不区分大小写)。
    • 在页面上添加格式化的笔记(如标注或待办事项)。
    • 将结构化表格从CSV数据插入页面。
  • 页面管理:
    • 在各部分之间复制页面。
  • 高级内容处理:
    • 复杂的HTML到可读文本提取。
    • 页面内容的Markdown到HTML转换。
  • 稳健的错误处理:
    • 针对瞬态故障,采用指数回退的自动重试(速率 限制、服务器错误、超时)。
    • 详细的、可操作的错误消息,并为每个错误提供具体指导 类型。
    • 智能处理身份验证、权限和网络问题。
  • 安全与验证:
    • 输入验证和消毒,以防止注射攻击。
    • 使用Zod定义和验证工具输入模式。
  • 性能优化:
    • 对于频繁访问的资源(笔记本电脑, 部分)。
    • 并行API调用多部分查询以减少延迟。
    • 批处理资源验证,以最大限度地减少多余的API请求。
  • 结构化日志记录:
    • 使用Pino进行高性能、结构化的JSON日志记录。
    • 可配置的日志级别(跟踪、调试、信息、警告、错误、致命)。
    • 开发中的打印输出很漂亮,生产中的JSON。

先决条件

  • Node.js: 建议使用18.x或更高版本。(从安装 nodejs.org)
  • npm: 通常与Node.js捆绑在一起。
  • Git
  • Microsoft帐户: 具有OneNote访问权限的活动Microsoft帐户。
  • Azure应用程序注册(建议用于生产/共享):
    • 而服务器默认使用Microsoft Graph Explorer的公共 客户端ID便于测试,可供常规或共享使用,它是 强烈地 推荐 创建自己的Azure应用程序注册。
    • 确保您的应用注册具有以下授权的Microsoft Graph API 权限: Notes.Read, Notes.ReadWrite, Notes.Create, User.Read.
    • 您需要从应用程序注册中获得“应用程序(客户端)ID”。

安装

  1. 克隆存储库:

    git clone https://github.com/IAmKSquared/onenotemcp.git
    cd onenotemcp
    
  2. 安装依赖关系:

    npm install
    

项目结构

为了可维护性和清晰性,代码库遵循模块化架构:

onenote-mcp-server/
├── src/
│   ├── auth/               # Authentication modules
│   │   ├── device-code-flow.mjs    # OAuth device code flow
│   │   ├── token-manager.mjs       # Token file operations
│   │   ├── encryption.mjs          # AES-256-GCM authenticated encryption
│   │   └── key-storage.mjs         # OS keychain integration
│   ├── api/                # API infrastructure
│   │   ├── cache.mjs              # Caching layer with TTL
│   │   └── retry.mjs              # Retry logic with exponential backoff
│   ├── tools/              # MCP tool definitions
│   │   ├── auth-tools.mjs         # Authentication tools
│   │   ├── read-tools.mjs         # Read operations (list, search, get)
│   │   ├── write-tools.mjs        # Edit operations (update, append, replace)
│   │   ├── create-tools.mjs       # Creation tools (notebooks, sections, pages)
│   │   └── delete-tools.mjs       # Delete operations (pages)
│   ├── utils/              # Shared utilities
│   │   ├── common.mjs             # Core utilities (validation, conversion, cache)
│   │   ├── html.mjs               # HTML formatting helpers
│   │   ├── logger.mjs             # Pino structured logging
│   │   └── validation.mjs         # Resource validation and fetching
│   ├── config/             # Configuration
│   │   └── constants.mjs          # Centralized constants (no magic numbers)
│   ├── session.mjs         # Session state management
│   └── server.mjs          # Main entry point
├── test/                   # Test suite
│   ├── test_unit.mjs              # 132 unit tests
│   ├── test_smoke.mjs             # Server startup verification
│   └── test_integration.mjs       # 55 integration tests
└── package.json

主要架构特征:

  • 模块化设计: 明确分离关注点(auth、API、工具、实用程序)
  • 会话管理: 封装状态通过 OneNoteSession 类(否 全局变量)
  • 集中配置: 所有幻数都替换为命名常量
  • 综合测试: 187多项测试,涵盖安全性、功能性和 整合

配置

  1. Azure客户端ID: 此服务器需要Azure应用程序客户端ID才能 使用Microsoft Graph进行身份验证。

    • 建议用于生产/共享用途: 设置 AZURE_CLIENT_ID 将环境变量设置为您自己的Azure应用程序的“应用程序(客户端)ID”。
      export AZURE_CLIENT_ID="your-actual-azure-app-client-id"
      
      (在Windows上,使用 set AZURE_CLIENT_ID=your-actual-azure-app-client-id)
    • 快速测试: 如果 AZURE_CLIENT_ID 环境变量为 如果未设置,服务器将默认使用Microsoft Graph Explorer的 公共客户端ID。这适用于初始测试,但不建议使用 用于长期或共享使用。
    • 或者,您可以修改 clientId 变量直接在 src/auth/device-code-flow.mjs,但使用环境变量 首选。
  2. 日志记录配置(可选): 服务器使用Pino进行结构化 登录中。您可以使用环境变量配置日志记录行为:

    • LOG_LEVEL: 设置要输出的最小日志级别(默认值: info). 可用级别: trace, debug, info, warn, error, fatal

      export LOG_LEVEL=debug  # Enable debug-level logging
      

      (在Windows上: set LOG_LEVEL=debug)

    • NODE_ENV: 吃起来 production 为了更好地输出JSON格式的日志 解析/分析。在开发中(默认),日志打印得很漂亮 颜色和时间戳。

      export NODE_ENV=production
      
  3. .gitignore: 该项目包括 .gitignore 文件。确保它 至少包含以下内容以防止提交敏感文件:

    node_modules/
    .DS_Store
    *.log
    .access-token.txt
    .env
    

    这 .access-token.txt 服务器将创建文件来存储您的 身份验证令牌。

运行MCP服务器

配置后,从项目的根目录启动服务器:

npm start

或者直接:

node src/server.mjs

您应该看到控制台输出,指示服务器已启动,并列出 可用工具类别。

连接到MCP客户端

您可以将此服务器连接到任何兼容MCP的客户端,例如Claude 桌面。

Claude桌面或光标示例:

  1. 打开MCP客户端的配置文件。

    • 克劳德桌面(macOS): ~/Library/Application Support/Claude/claude_desktop_config.json
    • 克劳德桌面(Windows): %APPDATA%\Claude\claude_desktop_config.json
    • 光标: 首选项->MCP选项卡。
  2. 添加或更新 mcpServers 配置:

    基本配置(使用默认客户端ID):

    {
      "mcpServers": {
        "onenote": {
          "command": "node",
          "args": ["/full/path/to/your/onenotemcp/src/server.mjs"]
        }
      }
    }
    

    使用自定义Azure客户端ID(可选):

    {
      "mcpServers": {
        "onenote": {
          "command": "node",
          "args": ["/full/path/to/your/onenotemcp/src/server.mjs"],
          "env": {
            "AZURE_CLIENT_ID": "YOUR_AZURE_APP_CLIENT_ID_HERE"
          }
        }
      }
    }
    
    • 替换 /full/path/to/your/onenotemcp/ 随着 绝对路径 到 在那里克隆了存储库。
    • 注意:路径应指向 src/server.mjs 在项目目录中。
    • 这 env 部分是 可选的 只有在以下情况下才需要:
      • 您想使用自定义Azure应用程序客户端ID,并且
      • 您尚未设置 AZURE_CLIENT_ID 作为系统范围的环境变量
    • 如果省略,服务器将使用Microsoft Graph Explorer的公共客户端 ID(适用于测试和个人使用)。
  3. 重新启动MCP客户端(克劳德桌面/光标)。

身份验证流程

您第一次尝试通过人工智能助手或通过以下方式使用OneNote工具 明确调用 authenticate 工具:

  1. 调用 authenticate 工具: 您的AI助手将呼叫 authenticate 服务器上的工具。
  2. 设备代码提示: 服务器将输出一个URL(通常 https://microsoft.com/devicelogin)并为其添加用户代码 stderr.你的 MCP客户端(例如Claude Desktop)应向您显示此信息。
  3. 浏览器身份验证: 在web浏览器中打开提供的URL并输入 用户代码。
  4. 登录并授予权限: 使用您的Microsoft帐户登录 具有OneNote访问权限,并授予请求的权限。
  5. 已保存令牌: 浏览器身份验证成功后,服务器将 自动接收访问令牌并将其保存到 .access-token.txt 文件在其目录中。
  6. 验证(可选但推荐): 调用 saveAccessToken 工具 通过你的AI助手。这个工具实际上并没有保存(因为它已经保存了 由后台进程保存),而是加载和验证令牌, 确认身份验证成功并显示您的帐户信息。

保存的令牌将用于后续会话,直到到期,届时 您可能需要重新进行身份验证。

可用的MCP工具

此服务器向您的AI助手公开以下工具:

身份验证:

  • authenticate:启动与Microsoft的设备代码身份验证流程 图表。
  • saveAccessToken:加载并验证本地保存的访问令牌。

正在读取OneNote数据:

  • listNotebooks:列出所有OneNote笔记本。
  • listSections:列出分区,可选择按笔记本或分区筛选 集团。(Args: notebookId (可选字符串), sectionGroupId (可选 字符串)
  • listSectionGroups:列出分区组,可选择按笔记本或 父节组。(Args: notebookId (可选字符串), sectionGroupId (可选字符串))
  • searchSections:按名称搜索节。(Arg: query (字符串)
  • listPagesInSection:列出特定部分中的所有页面。(Arg: sectionId (字符串)
  • searchPages:按标题搜索页面,可选择日期和笔记本 过滤。(Args: query (可选字符串), modifiedAfter (可选ISO 8601年日期), modifiedBefore (可选ISO 8601日期), notebookId (可选 字符串)
  • getRecentPages:检索笔记本中最近修改的页面。(Args: notebookId (字符串), limit (可选数字,默认值:10,最大值:50)
  • getPageContent:检索特定OneNote页的内容。(Args: pageId (字符串), format (枚举:“文本”、“html”、“摘要”,可选, 默认值:“文本”)
  • getPageByTitle:按页面标题查找页面并检索其内容。(Args: title (字符串), format (枚举:“文本”、“html”、“摘要”,可选, 默认值:“文本”)
  • getPageLink:获取在浏览器或桌面应用程序中打开页面的直接链接。 (Arg: pageId (字符串)

创建和管理结构:

  • createNotebook:创建新的OneNote笔记本。(Arg: displayName (字符串)
  • createSection:在笔记本中创建新分区。(Args: notebookId (字符串), displayName (字符串)
  • createSectionGroup:在笔记本中创建新的分区组。(Args: notebookId (字符串), displayName (字符串)

编辑和创建OneNote页面:

  • createPage:在第一个可用分区中创建新的OneNote页。 (Args: title (字符串), content (字符串-HTML或markdown)
  • createPageInSection:在特定分区中创建新的OneNote页。 (Args: sectionId (字符串), title (字符串), content (字符串-HTML或 降价)
  • updatePageContent:替换现有页面的全部内容。(Args: pageId (字符串), content (字符串), preserveTitle (布尔值,可选, 默认值:true))
  • appendToPage:将新内容添加到现有页面的末尾。(Args: pageId (字符串), content (字符串), addTimestamp (布尔值,可选, 默认值:true), addSeparator (布尔值,可选,默认值:true)
  • updatePageTitle:更改现有页面的标题。(Args: pageId (字符串), newTitle (字符串)
  • replaceTextInPage:查找并替换页面中的文本。(Args: pageId (字符串), findText (字符串), replaceText (字符串), caseSensitive (布尔值,可选,默认值:false)
  • addNoteToPage:向页面添加格式化的带时间戳的注释/评论。(Args: pageId (字符串), note (字符串), noteType (enum: “注意”, “所有”, “重要”、“问题”、可选、默认:“注意”), position (枚举:“top”, “bottom”,可选,默认值:“bottle”)
  • addTableToPage:从CSV数据向页面添加格式化表。(Args: pageId (字符串), tableData (字符串-CSV), title (字符串,可选), position (枚举:“top”,“bottom”,可选,默认值:“bottle”)

页面管理:

  • copyPage:将页面复制到其他部分(异步操作)。 (Args: pageId (字符串), targetSectionId (字符串)

删除资源:

  • deletePage:永久删除页面。(Args: pageId (字符串), confirmDelete (布尔值,必须为true)

与AI交互示例

一旦连接并通过身份验证,您就可以让您的AI助手执行任务 比如:

  • “列出我的OneNote笔记本。”
  • “创建一个名为‘Work 2025’的新笔记本电脑。”
  • “在我的工作笔记本中创建一个名为“每周报告”的部分。”
  • “显示笔记本中的所有部分。”
  • 搜索包含“Project”的节
  • “显示“会议笔记”部分中的所有页面。”
  • “查找2024-01-01之后修改的所有页面。”
  • “搜索上次修改过的标题中包含“预算”的页面 周。"
  • “显示特定笔记本中包含“会议”的所有页面 标题。"
  • “创建一个名为“会议想法”的新OneNote页面,内容为“头脑风暴” 新的营销策略”。"
  • 在“工作项目”部分创建一个标题为“行动项”的页面
  • “将此页面复制到“存档”部分。”
  • “你能找到我关于‘凤凰计划’的OneNote页面并告诉我吗 总结?"
  • 将“跟进John Doe”添加到带有ID的OneNote页面 “您的页面id在这里”。"
  • “在我的OneNote页面“配方创意”中,将所有“糖”实例替换为 “甜味剂”。"

测试

该项目包括一个全面的测试套件,以确保可靠性和捕获能力 回归。

运行测试

运行所有测试:

npm test

运行特定测试类型:

npm run test:unit         # Unit tests (132 tests for utility functions)
npm run test:smoke        # Smoke test (verifies server starts and tools are registered)
npm run test:integration  # Integration tests (55 tests for core functionality)

测试结构

  • test/test_unit.mjs -实用功能单元测试(132次测试) (escapeODataString、sanitizeUrl、validateId、extractReadableText、, extractTextSummary、textToHtml、Cache类、CSV验证)
  • test/test_smoke.mjs -烟雾测试,验证MCP服务器启动和 所有25个工具都已正确注册
  • test/test_integration.mjs -验证的集成测试(55个测试) 加密、重试逻辑、错误处理和格式化功能

测试覆盖率

  • ✅ 安全功能: OData注入预防、XSS保护、ID 验证
  • ✅ 内容处理: HTML到文本转换,markdown到HTML 转换
  • ✅ 缓存: TTL过期,模式无效
  • ✅ 服务器启动: MCP协议合规性、工具注册
  • ✅ API集成: 部分查询、带过滤器的页面搜索

代码质量和工具

该项目使用现代代码质量工具来保持一致性、安全性和 记录良好的代码:

装订和格式化

  • ESLint:静态代码分析,具有全面的代码质量规则, 最佳实践和安全
  • 更漂亮:自动代码格式化,确保整个系统风格一致 代码库
  • JSDoc验证:确保所有导出的函数都有适当的文档

可用命令:

npm run lint          # Check for code issues
npm run lint:fix      # Auto-fix linting issues
npm run format        # Format all code files
npm run format:check  # Check if files are formatted
npm run quality       # Run linting, formatting, and all tests

预提交钩子

该项目使用 哈士奇 和 皮棉上演 自动执行代码 质量:

  • 自动植绒:ESLint在所有舞台上运行 .js 和 .mjs 文件
  • 自动格式化:在提交之前对所有暂存文件进行预格式化
  • 零配置:运行时会自动设置挂钩 npm install

这确保了每个提交都能保持项目的质量标准,而无需 手动干预。

配置文件

  • eslint.config.js -带安全规则和JSDoc的ESLint配置 验证
  • .prettierrc.json -预处理格式规则
  • .prettierignore -从格式化中排除的文件
  • .husky/pre-commit -Git预提交钩子配置
  • package.json (lint分段部分)-分段文件处理规则

故障排除

  • 身份验证问题:
    • 确保您的 AZURE_CLIENT_ID (如果设置)是正确的,并且具有所需的API 权限。
    • 如果设备代码流失败,请在其他浏览器或 匿名/私人窗口。
    • 令牌到期:如果工具停止工作,您可能需要重新运行 authenticate 工具。
  • 服务器未启动:
    • 检查Node.js版本(node -v).
    • 确保安装了所有依赖项(npm install).
  • MCP客户端问题(例如,克劳德桌面、光标):
    • 验证 command 和 args (尤其是通往 src/server.mjs)客户端的MCP服务器配置是正确的。
    • 更改配置后重新启动MCP客户端。
    • 检查MCP客户端的日志和服务器的控制台输出是否有错误。

安全说明

  • 加密密钥存储: 服务器使用操作系统本机安全存储 加密密钥:
    • 视窗:Windows凭据管理器(DPAPI)
    • macOS:钥匙扣服务
    • Linux:特勤局API(gnome-keyring/KWallet)
    • 后备方案:如果操作系统密钥链不可用,则使用加密文件存储 带有警告信息。
    • 迁移:现有的基于文件的密钥会自动迁移到操作系统 首次启动时使用钥匙扣。
  • 访问令牌安全: 这 .access-token.txt 文件包含加密 根据定义的范围授予对OneNote数据访问权限的令牌。 令牌使用AES-256-GCM(经过身份验证的加密)和密钥进行加密 安全地存储在您的操作系统钥匙链中。像保护任何文件一样保护此文件 敏感凭证。确保它包含在您的 .gitignore 文件。
  • Azure客户端ID: 如果您创建了自己的Azure应用程序注册,请保留其 客户端机密(如果为其他流生成)是安全的。对于此设备代码 流,此脚本不使用客户端机密。
  • 权限: 此服务器请求 Notes.ReadWrite 和 Notes.Create 权限。请注意您授予的访问权限。

已知限制

以下操作是 不支持 由于Microsoft Graph API 限制:

重命名节或节组

Microsoft Graph API不支持修改节或节组 创建后的属性。正在尝试对这些资源使用PATCH操作 返回“找不到资源”错误。

解决方法: 使用所需名称创建新部分并手动复制 使用OneNote应用程序访问它的页面。

在节之间移动页面

Microsoft Graph API仅提供 copyToSection 端点--没有 moveToSection 操作。虽然我们理论上可以复制一页,然后 删除原始文件,这是不安全的,因为:

  1. 异步操作: 复制操作是异步的,没有完成 回调
  2. 数据丢失风险: 如果在复制完成之前删除了原件,或 如果复制失败,页面将永久丢失
  3. 无原子性: 无法确保这两项行动同时成功

解决方法: 使用 copyPage 要手动将页面复制到目标部分 验证复制成功,然后使用删除原始页面 deletePage.

删除章节、章节组和笔记本

Microsoft Graph API仅支持删除 页面。没有DELETE 分区、分区组或笔记本的端点。

解决方法: 使用OneNote桌面或web应用程序删除分区, 分区组或笔记本。

为什么存在这些限制

这些限制是由Microsoft的OneNote API设计施加的,而不是由此MCP施加的 服务器。OneNote API将数据安全置于破坏性数据的便利性之上 操作。有关API的最新功能,请参阅 Microsoft Graph OneNote API文档.

致谢

该项目最初源于 onenotemcp 由Ehsan Shahabi撰写,但已经 由于已经用新的架构、特征和功能进行了实质性的重写和扩展, 以及工具。

许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件 了解详情。