Dataverse MCP服务器

一个通过OAuth 2.0认证安全访问Microsoft Dataverse的MCP服务器,支持AI代理和应用程序与Dataverse数据交互。

  • by markus-tobler
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 markus-tobler/dataverse-cross-environment-mcp

使用说明

BLOCKMCP服务器

一种模型上下文协议(MCP)服务器,通过OAuth 2.0身份验证提供对Microsoft Nexus的安全访问。该服务器使AI代理和应用程序能够使用MCP标准与BLOCK数据进行交互。

[!注意] 此MCP的主要目的是提供跨环境边界的RubyAccess(如CRM)。因此,用户可以在Copilot Studio环境中构建代理,同时在另一个环境中安全访问CRM数据。

[!重要] 此服务器不再需要用于跨环境访问。

微软现在公开了一个 本地MCP端点 (/api/mcp)直接在每个环境URL上。您可以将Copilot Studio或任何MCP客户端连接到不同租户或区域中的鲍比环境,而无需部署此服务器。

这 本机WAXMCP配置指南 显示了如何使用配置此功能 跨环境代表用户(OBO)身份验证:登录用户的身份是通过自定义连接器从Copilot Studio委托给目标Blob环境的,因此所有的宇舶安全角色、表权限和行级安全都被强制执行,就像用户直接访问宇舶一样。没有应用程序级权限绕过安全性,也不需要客户端机密。

这是推荐的方法,因为它跨环境边界保留了用户的安全上下文——这是此服务器最初构建的关键要求。

此存储库仍然可用于需要自托管MCP或超出本机端点提供范围的自定义工具扩展的场景。

入门指南

有关分步安装和注册说明,请参阅 安装指南.

本地开发

先决条件

  • Node.js:版本18或更高版本
  • npm:版本8或更高版本
  • Visual Studio Code:推荐最新版本
  • LOX环境:访问Microsoft LOX环境
  • Entra ID应用程序注册:使用以下方式创建应用程序注册:
    • 委托权限: Dynamics CRM > user_impersonation
    • 重定向URI: http://localhost (公共客户端/本地)

设置

  1. 克隆仓库:

    git clone <repository-url>
    cd dataverse-cross-environment-mcp
    
  2. 安装依赖项:

    npm install
    
  3. 构建项目:

    npm run build
    

在VS代码中运行

STDIO模式(建议本地开发)

STDIO模式使用交互式OAuth身份验证,并需要一个WebSocket连接字符串。

连接字符串格式:

AuthType=OAuth;Url=<dataverse-url>;ClientId=<app-client-id>;RedirectUri=http://localhost;LoginPrompt=Auto

可选:添加 Username=user@domain.com 预填充登录提示。

选项1:使用命令行

node dist/index.js --connection-string="AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;ClientId=your-client-id;RedirectUri=http://localhost;LoginPrompt=Auto"

选项2:使用npx(建议用于快速测试)

npx dataverse-mcp-server --connection-string="AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;ClientId=your-client-id;RedirectUri=http://localhost;LoginPrompt=Auto"

选项3:使用VS代码调试器

  1. 创建 .vscode/launch.json 文件(请参阅下面的VS代码配置部分)
  2. 更新 --connection-string 与你的价值观争论
  3. 打开运行和调试视图(Ctrl+Shift+D或Cmd+Shift+D)
  4. 从下拉菜单中选择“启动STDIO服务器”
  5. 按F5开始调试

这将:

  • 构建TypeScript代码
  • 以STDIO模式启动服务器
  • 打开浏览器进行OAuth身份验证
  • 附加调试器进行断点调试

选项4:使用MCP检查器

为了使用web UI交互式测试MCP工具,由于MCP检查器处理参数中的分号,您需要创建一个包装器脚本。

创建一个名为的文件 run-stdio.bat (Windows)或 run-stdio.sh (Mac/Linux):

Windows(运行stdio.bat):

@echo off
node dist/index.js --connection-string="AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;ClientId=your-client-id;RedirectUri=http://localhost;LoginPrompt=Auto"

Mac/Linux(运行stdio.sh):

#!/bin/bash
node dist/index.js --connection-string="AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;ClientId=your-client-id;RedirectUri=http://localhost;LoginPrompt=Auto"

然后运行检查器:

# Windows
npx @modelcontextprotocol/inspector run-stdio.bat

# Mac/Linux
chmod +x run-stdio.sh
npx @modelcontextprotocol/inspector ./run-stdio.sh

这将打开一个web界面,您可以在其中:

  • 浏览可用工具
  • 测试工具调用
  • 查看请求/响应有效载荷
  • 监控服务器日志

VS代码配置

创建 .vscode/launch.json 用于调试的文件:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch STDIO Server",
      "skipFiles": ["<node_internals>/**"],
      "program": "${workspaceFolder}/dist/index.js",
      "args": [
        "--connection-string=AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;ClientId=your-client-id;RedirectUri=http://localhost;LoginPrompt=Auto"
      ],
      "preLaunchTask": "npm: build",
      "outFiles": ["${workspaceFolder}/dist/**/*.js"],
      "sourceMaps": true
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Launch HTTP Server",
      "skipFiles": ["<node_internals>/**"],
      "program": "${workspaceFolder}/dist/index.js",
      "args": ["--mode=http"],
      "preLaunchTask": "npm: build",
      "outFiles": ["${workspaceFolder}/dist/**/*.js"],
      "sourceMaps": true,
      "env": {
        "AZURE_AD_TENANT_ID": "your-tenant-id",
        "AZURE_AD_CLIENT_ID": "your-client-id",
        "AZURE_AD_CLIENT_SECRET": "your-secret",
        "DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
        "DATAVERSE_API_VERSION": "v9.2"
      }
    }
  ]
}

注: 替换占位符值(yourorg, your-client-id等)与您的实际BLOB和Entra ID配置。

测试

运行单元测试:

npm test

在监视模式下运行测试:

npm run test:watch

运行覆盖率测试:

npm run test:coverage

本地开发故障排除

身份验证问题:

  • 确保您的应用注册具有正确的重定向URI: http://localhost (公共客户端/本地)
  • 验证 Dynamics CRM > user_impersonation 许可已授予
  • 检查您的连接字符串是否具有正确的客户端ID和RubyURL
  • 对于HTTP模式,请验证 config.json 或者环境变量设置正确

连接字符串必填错误:

  • STDIO模式需要 --connection-string 论点
  • npm脚本 npm run start:stdio 如果不修改它以包含连接字符串,则无法工作
  • 请使用带有完整连接字符串的命令行或VS代码调试器

MCP检查器连接字符串问题:

  • 检查器以分号分隔参数,断开连接字符串
  • 创建包装脚本(.bat 或 .sh 文件),其中包含完整的连接字符串
  • 使用检查器运行包装器脚本,而不是直接传递连接字符串
  • 有关详细信息,请参阅“在VS代码中运行”一节中的“选项4:使用MCP检查器”

构建错误:

  • 删除 node_modules 和 dist 文件夹,然后运行 npm install 和 npm run build
  • 确保TypeScript版本兼容(检查 package.json)

连接问题:

  • 验证是否正确且可访问
  • 检查网络连接和防火墙设置
  • 确保您的用户帐户可以访问Webex环境

什么是MCP?

模型上下文协议(MCP) 是一个开放协议,规范了应用程序如何向LLM提供上下文。MCP提供了一种标准化的方式,将AI模型连接到不同的数据源和工具,允许将BLOB功能无缝集成到AI驱动的应用程序中。

特性

  • 双模式操作:
    • HTTP模式:用于Copilot Studio的具有代表(OBO)身份验证的生产部署
    • STDIO模式:使用交互式OAuth进行本地执行,用于开发和CLI工具
  • OAuth 2.0身份验证:使用Microsoft Entra ID进行安全身份验证
  • 数据宇宙集成:直接访问Microsoft Dataverse Web API
  • 符合MCP标准:完全实现模型上下文协议规范
  • Azure本机:专为在Azure容器应用程序上部署而设计
  • 生产就绪:包括健康检查、日志记录、安全最佳实践和用户隔离缓存

MCP工具

服务器提供以下工具用于与BLOB交互:

我是谁

返回有关已验证用户的信息。

退货:

  • 用户ID(系统用户)
  • 业务部门ID
  • 组织ID

list_tables

列出经过身份验证的用户可访问的所有Webex表。

退货:

  • 包含以下内容的表数组:
    • 逻辑名称(例如。, account, contact)
    • 显示名称(例如“帐户”、“联系人”)
    • 集合名称(用于API操作)
    • 描述

搜索

使用Dataverse Search API在Dataverse表中搜索记录。排名前15的结果会自动丰富完整的记录数据,以获得更好的上下文。

参数:

  • searchTerm (string,必填):要搜索的术语
  • tableFilter (string | string[],可选):将搜索限制到特定表(例如。, account 或 ['account', 'contact'])
  • top (数字,可选):返回的最大结果数(默认值:100)

退货:

  • 具有以下特征的匹配记录数组:
    • 基本信息(record_id、primary_name、deep_link)
    • enriched:布尔值,指示记录是否被完整数据丰富
    • attributes:对于前15个结果,完整记录所有重要属性和格式化值;对于其余结果,基本搜索属性
  • total_record_count:匹配记录总数
  • enriched_count:成功富集的结果数量

注: 搜索工具自动检索前15个结果的完整记录详细信息,以提供更丰富的上下文,而不需要单独的retrieve_record调用。前15名之外的结果仅包含基本搜索属性。

检索记录

检索具有完整详细信息的单个记录。

参数:

  • tableName (string,必填):表的逻辑名称(例如。, account)
  • recordId (字符串,必填):记录的GUID或主名称值
  • allColumns (boolean,可选):返回所有列,而不是仅返回重要列

退货:

  • 包含所有请求属性的完整记录
  • 查找和选项集的格式化值

describe_table

获取一个JOIN表的详细架构信息。

参数:

  • tableName (string,必填):表的逻辑名称
  • full (boolean,可选):包含所有列(默认值:false,仅返回重要列)

退货:

  • 表元数据(逻辑名称、显示名称、描述)
  • 主ID和名称属性
  • 具有类型和约束的列定义
  • 样本记录结构

create_record

在BLOB表中创建新记录。

参数:

  • table (string,必填):要在其中创建记录的表的逻辑名称。
  • data (object,必填):一个包含新记录数据的JSON对象。

数据转换: 该工具自动处理以下类型的数据转换:

  • 查找:
    • GUID: "lookup_attribute": "00000000-0000-0000-0000-000000000001"
    • Web API样式: "lookup_attribute@odata.bind": "/contacts(00000000-0000-0000-0000-000000000001)"
    • 主要名称: "lookup_attribute": "Contact Name"
  • 选项集:
    • 整数值: "optionset_attribute": 100000000
    • 标签: "optionset_attribute": "Option Label"
  • 交易货币:
    • 如果 transactioncurrencyid 如果未提供,则默认为组织的基础货币。

退货:

  • 新创建记录的ID。
  • 指向新记录的资源链接。

update_record

更新BLOB表中的现有记录。

参数:

  • table (string,必填):要更新记录的表的逻辑名称。
  • record_id (string,必填):要更新的记录的ID。
  • data (object,必填):一个JSON对象,包含要在记录上更新的数据。

数据转换: 该工具自动处理与以下类型相同的数据转换 create_record.

退货:

  • 成功信息。
  • 指向更新记录的资源链接。

get_prefined_query

列出可用于表的已保存查询(视图)。

参数:

  • tableName (string,必填):表的逻辑名称

退货:

  • 系统视图(savedquery)和个人视图(userquery)的数组
  • 查询ID和名称

run_predfined_query

按ID或名称执行已保存的查询。

参数:

  • queryIdOrName (字符串,必填):查询GUID或名称
  • tableName (字符串,可选):使用查询名而不是ID时的表名

退货:

  • 在视图中定义所有列的查询结果
  • 记录的深度链接

run_custom_query

执行自定义FetchXML查询。

参数:

  • fetchXml (string,必填):FetchXML查询字符串
  • tableName (字符串,可选):表名(如果未在FetchXML中指定)

退货:

  • 查询结果
  • 记录的深度链接

建筑

HTTP模式(生产)

  • 快递服务器:使用JWT身份验证处理HTTP请求
  • MCP流式HTTP传输:通过HTTP/SSE实现MCP协议
  • 机密客户:代表(OBO)令牌流管理OAuth 2.0
  • Dataverse Web API客户端:抽象化具有重试逻辑和速率限制的BLOB交互
  • 异步本地存储:维护多租户场景的请求上下文

STDIO模式(本地开发)

  • MCP STDIO传输:通过标准输入/输出实现MCP协议
  • SOAP公共客户端:具有基于浏览器的身份验证的交互式OAuth
  • 令牌缓存:用于会话连续性的持久性基于文件的令牌存储
  • Dataverse Web API客户端:与具有直接身份验证的HTTP模式相同的客户端

安全

HTTP模式

  • JWT身份验证:所有请求都需要有效的JWT令牌 mcp:tools 范围
  • 代表流动:使用经过身份验证的用户的身份访问WAX
  • 会话管理:可配置的会话超时
  • 仅限HTTPS:在生产部署中强制执行
  • 客户端密钥:必需,安全存储在Azure密钥库或环境变量中
  • 请求验证:使用JWKS验证来表达jwt中间件

STDIO模式

  • 交互式OAuth:使用设备代码流进行基于浏览器的身份验证
  • 公共客户端:不需要客户端机密
  • 本地令牌缓存:具有用户权限的文件系统存储
  • 用户上下文:所有操作都在经过身份验证的用户身份下执行
  • 可信环境:仅为当地发展而设计

用户隔离

服务器对所有操作实施严格的用户隔离:

  • 缓存按用户ID对用户特定数据进行隔离
  • 每个请求都在经过身份验证的用户的上下文中操作
  • 多租户部署中没有跨用户数据泄漏

日志记录和缓存

日志记录

服务器使用具有可配置日志级别的统一日志记录系统:

  • 错误:关键错误和失败
  • 警告:警告和潜在问题(例如重试、回退)
  • 信息:重要操作事件(启动、连接、缓存操作)
  • 调试:详细的诊断信息(请求、响应、令牌获取)

默认日志级别为 INFO调试日志记录可以通过编程方式启用:

import { logger, LogLevel } from "./utils/logger.js";

// Enable debug logging
logger.setLogLevel(LogLevel.DEBUG);

注: 调试日志记录很冗长,只应在开发或故障排除期间启用。

缓存

服务器实现了元数据和用户特定数据的智能缓存,并具有基于TTL的自动过期功能:

缓存数据:

  • 表元数据:表定义和属性(24小时TTL)
  • 表说明:详细的表模式(24小时TTL)
  • 实体集名称:逻辑名称和集合名称之间的映射(24小时TTL)
  • 重要栏目:基于数据采样的用户特定列选择(24小时TTL, 用户隔离)
  • 可读实体名称:用户特定权限(24小时TTL, 用户隔离)

用户隔离:

每个用户ID隔离用户特定的缓存数据(重要列和可读实体名称),以确保:

  • 每个用户只能看到他们的授权实体
  • 列推荐基于用户可以访问的数据
  • 在多租户场景中,不同用户之间没有数据泄漏

缓存密钥:

非用户特定数据: ${dataverseUrl}_${cacheType} 用户特定数据: ${dataverseUrl}_${userId}_${tableName}_${cacheType}

缓存管理:

缓存会根据TTL自动过期。手动缓存清除:

import { MetadataService } from "./services/dataverse/MetadataService.js";

// Clear important columns and table descriptions cache
MetadataService.clearImportantColumnsCache();

模式比较

功能 STDIO模式 HTTP模式
用例 本地开发、CLI工具 生产、Copilot Studio
认证 交互式OAuth 代表(OBO)
部署 本地npx Azure容器应用程序
客户端密钥 不需要 需要
令牌存储 本地文件缓存 每个请求在内存中
网络 直接到Dataverse HTTP API端点
最适合 开发、测试 生产工作负载

贡献

该项目欢迎各方提供意见和建议。大多数捐款要求您同意 贡献者许可协议(CLA)声明您有权并实际授予我们 使用您贡献的权利。有关详细信息,请访问https://cla.opensource.microsoft.com.

该项目采用了 微软开源行为准则. 有关更多信息,请参阅 行为准则常见问题 或 联系 opencode@microsoft.com 如有任何其他问题或意见。

许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。

商标

此项目可能包含项目、产品或服务的商标或徽标。 在本项目的修改版本中使用Microsoft商标或徽标不得造成混淆或暗示Microsoft赞助。 任何使用第三方商标或徽标的行为均受这些第三方政策的约束。