BLOCKMCP服务器
用于Microsoft Dataverse的模型上下文协议(MCP)服务器,可使用Dataverse Web API进行模式操作,包括创建和更新表、列、关系和选项集。
🚀 主要特点
✅ 管理表和列 -创建、更新、删除和列出所有列类型(字符串、整数、布尔值、日期时间、选择列表、查找、自动编号等)的自定义表
✅ 管理关系 -在具有适当级联行为的实体之间创建一对多和多对多关系
✅ 管理选项集 -使用自定义选项、颜色和值创建和管理全局选项集
✅ 基于解决方案的架构 -具有持久上下文和自动自定义前缀的企业级解决方案管理
✅ 安全和访问控制 -完整的安全角色管理、团队运营和业务部门层次结构管理
✅ WebAPI调用生成器 -为任何一个WAX操作生成即用型HTTP请求、cURL命令和JavaScript代码
✅ PowerPages WebAPI生成器 -使用生成特定于PowerPage的WebAPI调用 /_api/[logicalEntityName] 使用React示例的格式
✅ PowerPages配置管理 -使用YAML文件自动化管理PowerPages代码站点的表权限和WebAPI站点设置
✅ 模式导出和可视化 -通过高级过滤将完整的解决方案模式导出为JSON,然后生成具有关系可视化的专业Mermaid ERD图
✅ 美人鱼图生成 -将导出的模式转换为具有增强列标记、查找目标显示和无限表支持的专业实体关系图
✅ 自动编号列管理 -使用可自定义的格式模式创建和管理自动编号列,用于自动序列号、参考代码和唯一标识符
✅ 专业整合 -OAuth2身份验证、全面的错误处理和企业就绪部署
✅ 生产就绪 -全面测试完成,发现并修复了7个关键错误,实现了100%的工具覆盖率
目录
- 表操作 - 列操作 - 自动编号列操作 - 关系运营 - 选项集操作 - 解决方案和发行商运营 - 安全角色操作 - 团队运营 - 业务部门运营 - 架构导出操作 - WebAPI调用生成器 - PowerPages WebAPI生成器 - PowerPages配置管理
- 主要优势 - 解决方案工作流 - 示例:XYZ组织设置 - 持久解决方案上下文
- 1.Azure应用程序注册 - 2.创建客户端密码 - 3.在BLOB中创建应用程序用户 - 4.获取所需信息
- Windows MCP配置 - 选项1:使用.env文件(建议用于MCP服务器开发) - 选项2:使用MCP环境变量(建议正常使用) - 选项3:混合配置
- 创建自定义表 - 向表中添加列 - 创建自动编号列 - 建立关系 - 管理选项集 - 管理安全角色 - 管理团队 - 管理业务部门 - 导出解决方案架构 - 美人鱼图生成 - WebAPI调用生成器 - PowerPages WebAPI生成器 - PowerPages配置管理
- 发布服务器配置 - 解决方案上下文管理 - 环境促进 - Git集成
- MCP配置建议 - 始终允许配置的只读工具 - 此配置的好处 - 通用开发工作流 - 开发人员安全注意事项 - 高级配置提示
特性
此MCP服务器提供了全面的工具来管理RubySchema:
表操作
- create_dataverse_table ✅ 经过全面测试 - 创建JDBC表:使用指定的配置在BLOB中创建新的自定义表。当您需要创建新实体来存储业务数据时,请使用此选项。需要先设置解决方案上下文。
- get_dataverse_table ✅ 经过全面测试 - 获取数据库表:检索有关特定数据库表的详细信息,包括其元数据、属性和配置。使用此功能检查表定义并了解表结构。
- update_dataverse_table ✅ 经过全面测试 - 更新数据库表:更新现有BLOB表的属性和配置。使用此选项可以修改表设置,如显示名称、描述或功能启用(活动、注释、审核等)。更改会自动发布。
- delete_dataverse_table ✅ 经过全面测试 - 删除Webex表:将自定义表从BLOB中永久删除。警告:此操作无法撤消,将删除表中的所有数据。请务必谨慎使用,仅适用于不再需要的桌子。
- list_dataverse_tables ✅ 经过全面测试 - 列出JDBC表:检索带有筛选选项的Webex环境中的表列表。使用此功能可以发现可用表、查找自定义表或获取数据模型的概述。支持按自定义/系统表和托管/非托管状态进行筛选。
列操作
- create_dataverse_column ✅ 经过全面测试 - 创建JDBC列:使用指定的数据类型和配置在BLOB表中创建新列(字段)。支持各种列类型,包括文本、数字、日期、查找和选择列表。使用此选项可添加新字段以在表中存储特定数据。需要先设置解决方案上下文。
- get_dataverse_column ✅ 经过全面测试 - 获取JB列:检索有关BLOB表中特定列的详细信息,包括其数据类型、属性和配置设置。使用此选项可以检查列定义并了解字段结构。
- update_dataverse_column ✅ 经过全面测试 - 更新Webex列:更新数据库表中现有列的属性和配置。使用此选项可以修改列设置,如显示名称、描述、所需级别或审核设置。请注意,创建后无法更改数据类型。
- delete_dataverse_column ✅ 经过全面测试 - 删除JB列:永久删除一列。警告:此操作无法撤消,将删除此列中存储的所有数据。请务必谨慎使用,仅适用于不再需要的列。
- list_dataverse_columns ✅ 经过全面测试 - 列出JB列:检索具有筛选选项的特定BLOCK表中的列列表。使用此功能可以发现表中的可用字段、查找自定义列或获取表结构的概述。支持按自定义/系统列和托管/非托管状态进行筛选。
自动编号列操作
- 创建_自动编号_列 ✅ 经过全面测试 - 创建自动编号列:在具有指定格式的BLOB表中创建新的自动编号列。自动编号列使用序列号、随机字符串和日期时间占位符自动生成字母数字字符串。需要先设置解决方案上下文。
- update_autonumber_format ✅ 经过全面测试 - 更新自动编号格式:更新现有自动编号列的自动编号格式。这将改变未来值的生成方式,但不会影响现有记录。
- set_autonumber_sed ✅ 经过全面测试 - 设置自动编号种子:使用SetAutoNumberSeed操作为AutoNumber列的连续段设置种子值。这控制了未来记录的起始编号。注意:种子值是特定于环境的,不包含在解决方案中。
- 获取autonumber_column ✅ 经过全面测试 - 获取自动编号列:检索有关自动编号列的详细信息,包括其当前格式、属性和配置。
- 列表_自动编号_列 ✅ 经过全面测试 - 列出自动编号列:列出特定表中或环境中所有表中的所有自动编号列。帮助识别现有的自动编号实现。
- convert_to_autonumber ✅ 经过全面测试 - 转换为自动编号:通过添加自动编号格式将现有文本列转换为自动编号列。该列必须是文本格式的字符串类型,并且应为空或包含兼容的数据。
关系运营
- create_dataverse_relationship ✅ 经过全面测试 - 创建JDBC关系:在两个BLOB表之间创建关系。支持一对多关系(带查找字段的父子关系)和多对多关系。使用此功能可以在表之间建立数据连接、启用导航和维护引用完整性。
- get_dataverse_relationship ✅ 经过全面测试 - 获取JDBC关系:检索有关BLOB表之间特定关系的详细信息,包括其配置、级联设置和菜单行为。使用此选项可以检查关系定义并了解表连接。
- 删除数据关系 ✅ 经过全面测试 - 删除JDBC关系:永久删除一个关系的表之间。警告:此操作无法撤消,将删除表之间的连接,包括一对多关系的任何查找字段。请务必谨慎使用。
- list_dataverse_relations ✅ 经过全面测试 - 列出EJB关系:检索具有筛选选项的Webex环境中的关系列表。使用此功能可以发现表连接、查找自定义关系或获取数据模型关系的概述。支持按实体、关系类型和托管/非托管状态进行筛选。
选项集操作
- create_dataverse_optionset ✅ 经过全面测试 - 创建Webex选项集:使用预定义的选项在Webex中创建新的全局选项集(选项列表)。使用此选项可创建可跨多个表和列使用的可重用选择列表。选项集提供一致的数据输入选项并提高数据质量。
- get_dataverse_optionset ✅ 经过全面测试 - 获取Webex选项集:检索有关特定选项集的详细信息,包括其元数据、选项和配置。使用此功能检查选项集定义并了解可用选项。
- update_dataverse_optionset ✅ 经过全面测试 - 更新Webex选项集:通过修改现有选项集的属性和管理其选项来更新该选项集。使用此选项可以添加新选项、更新现有选项、删除过时的选项或更改选项集的显示名称和描述。更改会影响使用此选项集的所有列。
- delete_dataverse_optionset ✅ 经过全面测试 - 删除Webex选项集:永久性地从BLOB中删除选项集。警告:此操作无法撤消,如果任何列正在使用该选项集,此操作将失败。在删除之前,确保没有列引用此选项集。
- list_dataverse_optionsets ✅ 经过全面测试 - 列出JDBC选项集:检索带有筛选选项的在Webex环境中的选项集列表。使用此功能可以发现可用的选项列表、查找自定义选项集或获取可重用选项的概述。支持按自定义/系统和托管/非托管状态进行筛选。
- get_dataverse_optionset_options ✅ 经过全面测试 - 获取Webex选项集选项:检索特定选项集中的所有选项,包括其值、标签、描述和颜色。使用此功能检查选项集中的可用选项并了解其配置。
解决方案和发行商运营
- create_dataverse_publisher ✅ 经过全面测试 - 创建JDBC发布器:在BLOB中创建新的发布者。创建解决方案需要发布者,并为架构名称提供自定义前缀。在创建解决方案和自定义组件之前,使用此功能建立发布者标识。
- get_dataverse_publisher ✅ 经过全面测试 - 获取JDBC发布器:检索特定发布者的详细信息,包括其自定义前缀、选项值前缀和配置。使用此功能可以检查发布者属性并了解自定义设置。
- list_dataverse_publishers ✅ 经过全面测试 - 列出JDBC发布者:检索带有筛选选项的Rubyenvironment中的发布者列表。使用此功能可以发现可用的发布者,查找用于创建解决方案的自定义发布者,或获取包括自定义前缀在内的发布者配置的概述。
- create_dataverse_solution ✅ 经过全面测试 - 创建Webex解决方案:在BLOB中创建新的非托管解决方案。解决方案是自定义的容器,允许您打包、部署和管理自定义组件。在添加表、列和其他自定义项之前,使用此选项创建解决方案。
- get_dataverse_解决方案 ✅ 经过全面测试 - 获取Webex解决方案:检索有关特定解决方案的详细信息,包括其元数据、版本、发布者详细信息和配置。使用此工具检查解决方案属性并了解解决方案结构。
- list_dataverse_solutions ✅ 经过全面测试 - 列出JDBC解决方案:检索具有筛选选项的Webex环境中的解决方案列表。使用此功能可以发现可用的解决方案,查找非托管解决方案进行自定义,或获取解决方案包的概述。包括每个解决方案的发布者信息。
- set_solution_context ✅ 经过全面测试 - 设置解决方案上下文:为所有后续元数据操作设置活动解决方案上下文。设置解决方案上下文后,所有创建的表、列、关系和其他组件都将自动添加到此解决方案中。在创建任何自定义组件之前,这是必需的。
- get_solution_context ✅ 经过全面测试 - 获取解决方案上下文:检索当前活动的解决方案上下文信息。使用此选项可以检查当前为元数据操作设置了哪个解决方案,并验证用于新组件的自定义前缀。
- clear_solution_context ✅ 经过全面测试 - 清晰的解决方案上下文:清除当前活动的解决方案上下文。清除后,元数据操作将不会与任何特定解决方案相关联。当您想在没有解决方案上下文的情况下工作或切换到其他解决方案之前使用此选项。
安全角色操作
- create_dataverse_role ✅ 经过全面测试 - 创建JDBC安全角色:在BLOB中创建新的安全角色,以定义用户和团队的权限和访问级别。安全角色控制用户在系统中可以看到什么和做什么。使用此功能为不同的用户类型或作业职能建立自定义权限集。
- get_dataverse_role ✅ 经过全面测试 - 获取JDBC安全角色:检索有关特定安全角色的详细信息,包括其属性、业务部门关联和配置设置。使用此功能可以检查角色定义并了解权限结构。
- update_dataverse_role ✅ 经过全面测试 - 更新Webex安全角色:更新现有安全角色的属性和配置。使用此选项可以修改角色设置,如名称、描述、自动分配行为或继承设置,而无需更改实际权限。
- delete_dataverse_role ✅ 经过全面测试 - 删除Webex安全角色:从BLOB中永久删除安全角色。警告:此操作无法撤消,如果将角色分配给任何用户或团队,此操作将失败。删除之前,请确保该角色未被使用。
- list_dataverse_roles ✅ 经过全面测试 - 列出JDBC安全角色:检索具有筛选选项的Webex环境中的安全角色列表。使用此功能可以发现可用角色、查找自定义角色或获取权限结构的概述。支持按业务部门、自定义/系统角色和托管/非托管状态进行筛选。
- 添加特权到角色 ✅ 经过全面测试 - 为安全角色添加权限:为安全角色添加具有定义访问级别的特定权限。使用此功能可授予对实体或系统功能进行特定操作(创建、读取、写入、删除等)的权限。每个权限可以有不同的访问级别(基本、本地、深度、全局)。
- remove_privilege_rom_role ✅ 经过全面测试 - 从安全角色中删除权限:从安全角色中删除特定权限,撤销相关权限。使用此功能可以通过从角色中删除特定操作权限来限制访问。
- replace_role_特权 ✅ 经过全面测试 - 替换安全角色权限:用一组新的权限完全替换安全角色中的所有现有权限。警告:这将删除所有当前权限,并用指定的权限替换它们。用于全面的角色权限重组。
- 获取权限 ✅ 经过全面测试 - 获取安全角色权限:检索当前分配给安全角色的所有权限,显示该角色授予的权限。使用此功能可以审核角色权限,并了解角色为用户和团队提供的访问权限。
- assign_role_to_user ✅ 经过全面测试 - 为用户分配安全角色:为特定用户分配安全角色,授予他们该角色中定义的所有权限。使用此功能为用户提供其工作职能和职责的适当访问级别。
- remove_role_from_user ✅ 经过全面测试 - 从用户中删除安全角色:从特定用户中删除安全角色分配,撤销该角色授予的权限。当用户更改角色或不再需要某些访问级别时使用此选项。
- assign_role_to_team ✅ 经过全面测试 - 为团队分配安全角色:为团队分配安全角色,授予所有团队成员在该角色中定义的权限。使用此功能为共同处理类似任务的用户组提供一致的访问级别。
- remove_role_from_team ✅ 经过全面测试 - 从团队中删除安全角色:从团队中删除安全角色分配,撤销该角色为所有团队成员授予的权限。当团队不再需要某些访问级别或重组团队权限时,请使用此选项。
团队运营
- create_dataverse_team ✅ 经过全面测试 - 创建JDBC团队:在BLOB中创建一个新团队,用于组织用户和管理权限。团队可以是所有者团队(用于记录所有权)或访问团队(用于共享记录)。使用此功能可建立协同工作并需要类似访问级别的用户组。
- get_dataverse_team ✅ 经过全面测试 - 获取Webex团队:检索特定团队的详细信息,包括其属性、管理员、业务部门关联和配置设置。使用此功能检查团队定义并了解团队结构。
- update_dataverse_team ✅ 经过全面测试 - 更新Webex团队:更新现有团队的属性和配置。使用此选项可以修改团队设置,如名称、描述、管理员或其他团队属性,而无需更改团队成员资格。
- delete_dataverse_team ✅ 经过全面测试 - 删除小组:从BLOB中永久删除团队。警告:此操作无法撤消,如果团队拥有记录或已分配安全角色,则此操作将失败。在删除之前,确保该团队未被使用。
- list_dataverse_teams ✅ 经过全面测试 - 列出Webex团队:检索带有筛选选项的Webex环境中的团队列表。使用此功能可以发现可用的团队,按业务部门或类型查找团队,或获取团队组织的概述。支持按业务部门、团队类型和系统管理状态进行筛选。
- add_members_to_team ✅ 经过全面测试 - 将成员添加到团队:将用户添加为团队成员,授予他们访问团队拥有的记录和基于团队的权限。使用此功能可扩展团队成员资格,并为用户提供团队级别的资源访问权限。
- remove_members_from_team ✅ 经过全面测试 - 从团队中删除成员:从团队成员中删除用户,撤销他们对团队拥有的记录和基于团队的权限的访问权限。当用户不再需要团队访问权限或正在更改角色时,请使用此功能。
- get_team_members ✅ 经过全面测试 - 获取团队成员:检索属于特定团队的所有用户的列表,包括他们的基本信息和状态。使用此功能审核团队成员资格,并了解谁拥有基于团队的访问权限。
- convert_owner_team_to_access_team ✅ 经过全面测试 - 将所有者团队转换为访问团队:将所有者团队转换为访问团队,更改该团队用于记录所有权和共享的方式。警告:此操作无法撤消,并影响此团队拥有的记录的管理方式。
业务部门运营
- create_dataverse_businessunit ✅ 经过全面测试 - 创建Webex业务部门:使用全面的配置选项(包括联系人信息、地址和组织层次结构)创建新的业务部门。业务单元用于组织用户和控制数据访问。
- get_dataverse_businessunit ✅ 经过全面测试 - 获取JB业务部门:检索特定业务部门的详细信息,包括所有属性、地址和相关信息。使用此功能检查业务部门配置和层次关系。
- update_dataverse_businessunit ✅ 经过全面测试 - 更新Webex业务部门:更新现有业务部门的属性和配置。使用此选项可以修改业务部门信息、联系方式、地址和组织设置。只有提供的字段才会更新。
- delete_dataverse_businessunit ✅ 经过全面测试 - 删除Webex业务部门:将业务部门永久性地从BLOB中删除。警告:此操作无法撤消,可能会影响与业务部门关联的用户和团队。请务必谨慎使用。
- 列表_数据_业务单位 ✅ 经过全面测试 - 列出JB业务部门:检索具有过滤和排序选项的Webex环境中的业务部门列表。使用此功能可以发现可用的业务部门,了解组织层次结构,并根据条件找到特定的业务部门。
- get_businessunit_hierage ✅ 经过全面测试 - 获取业务部门层次结构:检索特定业务部门的完整组织层次结构,显示父子关系和完整的组织结构。使用此工具了解业务部门关系和组织结构。
- set_业务部门_租金 ✅ 经过全面测试 - 设置业务部门父级:更改给定业务部门的父业务部门,有效地在组织层次结构中移动它。使用此功能重新组织业务部门结构和报告关系。
- 获取_业务单位_用户 ✅ 经过全面测试 - 获取业务部门用户:检索与特定业务部门关联的所有用户,并可选择包括来自子业务部门的用户。使用此功能了解用户分配和组织成员资格。
- get_businessunit_teams ✅ 经过全面测试 - 组建业务部门团队:检索与特定业务部门关联的所有团队,并可选择包括来自子业务部门的团队。使用此方法了解团队组织和业务部门关系。
架构导出操作
- export_solution_schema ✅ 经过全面测试 - 导出解决方案架构:导出一个全面的JSON模式,其中包含BLOB表、列、关系和选项集。使用此功能记录数据模型、生成图表或分析解决方案结构。支持按前缀、系统/自定义组件和特定表进行筛选。
- generate_mermaid图 ✅ 经过全面测试 - 生成美人鱼图:从导出的架构JSON文件生成Mermaid实体关系图。使用表、列和关系创建数据模型的可视化文档。非常适合文档、演示和理解数据结构。
WebAPI调用生成器
- generate_webapi_call ✅ 经过全面测试 - 生成RubyWebAPI调用:生成HTTP请求、curl命令和用于RubyWebAPI操作的JavaScript示例。使用适当的OData查询参数和标头支持所有CRUD操作、关联、操作和函数。
PowerPages WebAPI生成器
- 发电机_电源\_ webapi_call ✅ 经过全面测试 - 生成PowerPages WebAPI调用:通过PowerPages门户为Dataverse操作生成特定于PowerPages的API调用、JavaScript示例和React组件。具有模式感知元数据检索、@odata.bind关系管理、自动字段推断和特定于PowerPage的身份验证模式。
PowerPages配置管理
- manage_powerpages_webapi_config ✅ 经过全面测试 - 管理PowerPages WebAPI配置:管理PowerPages WebAPI配置和表权限。添加/删除表的WebAPI访问权限,配置表权限,并检查PowerPages门户的配置状态。
基于解决方案的架构
MCP服务器按照Microsoft BLOB最佳实践实现企业级解决方案管理。
主要优势
- 专业架构命名:使用基于发布者的自定义前缀
- 解决方案协会:所有架构更改都会自动与活动解决方案相关联
- ALM支持:实现跨环境的正确解决方案打包和部署
- 持久上下文:解决方案上下文通过以下方式在服务器重启后仍然有效
.dataverse-mcp文件 - 企业治理:通过适当的隔离支持多个发布者和解决方案
解决方案工作流
- 创建发布者:定义组织的自定义前缀
- 创建解决方案:将解决方案链接到架构组织的发布者
- 设置上下文:激活解决方案以进行后续操作
- 创建架构:所有表、列和选项集都自动使用发布者的前缀
- 部署:导出解决方案以部署到其他环境
示例:XYZ组织设置
// 1. Create publisher with "xyz" prefix
await use_mcp_tool("dataverse", "create_dataverse_publisher", {
friendlyName: "XYZ Test Publisher",
uniqueName: "xyzpublisher",
customizationPrefix: "xyz",
customizationOptionValuePrefix: 20000,
description: "Publisher for XYZ organization"
});
// 2. Create solution linked to publisher
await use_mcp_tool("dataverse", "create_dataverse_solution", {
friendlyName: "XYZ Test Solution",
uniqueName: "xyzsolution",
publisherUniqueName: "xyzpublisher",
description: "Main solution for XYZ customizations"
});
// 3. Set solution context (persisted across server restarts)
await use_mcp_tool("dataverse", "set_solution_context", {
solutionUniqueName: "xyzsolution"
});
// 4. Create schema objects - they automatically use "xyz" prefix
await use_mcp_tool("dataverse", "create_dataverse_table", {
logicalName: "xyz_project", // Uses xyz prefix automatically
displayName: "XYZ Project",
displayCollectionName: "XYZ Projects"
});
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
logicalName: "xyz_description", // Uses xyz prefix automatically
displayName: "Description",
columnType: "Memo"
});持久解决方案上下文
服务器会自动将解决方案上下文持久化到 .dataverse-mcp 项目根目录中的文件:
{
"solutionUniqueName": "xyzsolution",
"solutionDisplayName": "XYZ Test Solution",
"publisherUniqueName": "xyzpublisher",
"publisherDisplayName": "XYZ Test Publisher",
"customizationPrefix": "xyz",
"lastUpdated": "2025-07-26T08:27:56.966Z"
}坚持的好处:
- 无上下文丢失:解决方案上下文在服务器重新启动后仍然有效
- 即时生产力:开发人员可以立即继续工作
- 一致的前缀:无需记住和重新设置解决方案上下文
- 团队隔离:每个开发人员都可以有自己的解决方案上下文(文件被git忽略)
支持的列类型
MCP服务器支持所有主要的具有全面配置选项的BLOB列类型。下表显示了实施状态和综合测试验证:
| 列类型 | 状态 | 已测试 | 描述 | 关键参数 |
|---|---|---|---|---|
| 字符串 | ✅ 已实施 | ✅ 完全验证 | 具有格式选项的文本字段 | maxLength, format (电子邮件、文本、文本区域、URL、电话) |
| 整数 | ✅ 已实施 | ✅ 完全验证 | 带约束的整数 | minValue, maxValue (默认值不受支持) |
| 十进制 | ✅ 已实施 | ✅ 完全验证 | 精确的十进制数 | precision, minValue, maxValue, defaultValue |
| 金钱 | ✅ 已实施 | ✅ 完全验证 | 货币价值 | precision, minValue, maxValue |
| 布尔 | ✅ 已实施 | ✅ 完全验证 | 带有自定义标签的True/false | trueOptionLabel, falseOptionLabel, defaultValue |
| 日期时间 | ✅ 已实施 | ✅ 完全验证 | 日期和时间字段 | dateTimeFormat (仅日期、日期和时间) |
| 选项列表 | ✅ 已实施 | ✅ 完全验证 | 选择字段(本地和全球) | options (对于本地), optionSetName (全球) |
| 查找 | ✅ 已实施 | ✅ 完全验证 | 参考其他表格 | targetEntity |
| 备忘录 | ✅ 已实施 | ✅ 完全验证 | 长文本字段 | maxLength |
| 双倍 | ✅ 已实施 | ✅ 完全验证 | 浮点数 | precision, minValue, maxValue |
| 大整数 | ✅ 已实施 | ✅ 完全验证 | 大整数值 | 无 |
列类型详细信息
字符串列✅ 经过全面测试
- 格式:电子邮件、文本、文本区域、URL、电话
- 最大长度:可配置(默认值:100)
- 默认值:支持
- 示例:员工姓名、电子邮件地址、电话号码
整数列✅ 经过全面测试
- 约束条件:最小/最大值验证
- 默认值:不受支持(限制为LOX)
- 示例:年龄、数量、分数,范围为0-100
布尔列✅ 经过全面测试
- 自定义标签:可配置的真/假选项标签
- 默认值:支持
- 示例:“活动/非活动”、“是/否”、“启用/禁用”
DateTime列✅ 经过全面测试
- 仅限日期:不含时间成分的日期(例如,雇佣日期、生日)
- 日期和时间:带时区处理的完整时间戳(例如,上次登录、创建日期)
- 行为:使用UserLocal时区行为
选择列表列✅ 经过全面测试
- 本地选项集:使用列创建内联选项
- 全局选项集:按名称引用现有全局选项集
- 颜色支持:选项可以具有关联的颜色
- 示例:状态(活动、非活动)、优先级(高、中、低)
查找列✅ 经过全面测试
- 目标实体:指定要引用的表
- 关系:自动创建基础关系
- 示例:客户查询、账户参考
测试柱场景
以下具体场景已在综合测试中成功测试和验证:
- 字符串列创建 ✅ 已验证
- 具有默认设置的基本文本字段 - 电子邮件格式验证 - 自定义最大长度约束
- 整数列创建 ✅ 已验证
- 具有最小/最大约束的数字字段(0-100范围) - 默认值处理(不支持-正确处理)
- 布尔列创建 ✅ 已验证
- 自定义真/假标签(“活动”/“非活动”) - 默认值配置
- DateTime列创建 ✅ 已验证
- 招聘日期的DateOnly格式 - 登录时间戳的DateAndTime格式
- 选择列表列创建 ✅ 已验证
- 带有自定义选项的本地选项集 - 使用现有选项集的全局选项集引用
- 查找列创建 ✅ 已验证
- 跨表引用创建 - 自动创建关系
- 十进制列创建 ✅ 已验证
- 精度和规模配置 - 最小/最大值约束
- 货币专栏创建 ✅ 已验证
- 精确的货币字段 - 正确的货币数据类型处理
- 备忘录列创建 ✅ 已验证
- 长文本字段配置 - 最大长度设置
- 双栏创建 ✅ 已验证
- 浮点数处理 - 精密配置
- BigInt列创建 ✅ 已验证
- 大整数值支持 - 正确的数据类型处理
列操作状态
| 操作 | 状态 | 描述 |
|---|---|---|
| 创建 | ✅ 经过全面测试 | 所有具有特定类型参数的列类型 |
| 阅读 | ✅ 经过全面测试 | 检索列元数据和配置 |
| 更新 | ✅ 经过全面测试 | 修改显示名称、描述、所需级别 |
| 删除 | ✅ 经过全面测试 | 从表中删除自定义列(使用依赖性检查) |
| 列表 | ✅ 经过全面测试 | 列出具有筛选功能的表的所有列 |
测试和质量保证
此MCP服务器经过全面测试,以确保生产就绪:
测试覆盖率
- ✅ 22个主要测试阶段已完成
- ✅ 100%工具覆盖率 -所有40+工具均已测试
- ✅ 所有列类型均已验证 -完成所有11种支撑柱类型的测试
- ✅ 测试所有关系类型 -一对多和多对多关系
- ✅ 完成CRUD操作 -为所有实体类型创建、读取、更新、删除
- ✅ 错误处理已验证 -边缘情况和无效输入处理
- ✅ Microsoft Dataverse API合规性 -完全符合API官方标准
发现并修复错误
在综合测试期间, 7个关键错误 已确定并解决:
- 整数列默认值Bug -修复了IntegerAttributeMetadata不支持的DefaultValue属性
- 表更新方法错误 -已修复在EntityMetadata更新中使用PUT而不是PATCH的问题
- 列更新方法错误 -已修复在AttributeMetadata更新中使用PUT而不是PATCH的问题
- PublishXml操作前缀错误 -修复了没有Microsoft的全局行动呼叫。动力学。CRM前缀
- 选项集更新方法错误 -已修复在PUT操作中使用MetadataId而不是Name的问题
- UpdateOptionValue缺少参数错误 -添加了必需的MergeLabels参数
- 选项集操作前缀错误 -已修复选项设置操作不包含不正确前缀的问题
测试文档
- 宠物店示例 -使用宠物店模式示例完成测试文档
- COMPREHENSIVE_TEST_PLAN.md -完成284线系统测试计划
- COMPREHENSIVE_TEST_REPORT.md -详细的测试结果和错误修复
生产准备就绪
- ✅ 稳健的错误处理 -针对所有场景的全面错误处理
- ✅ 依赖管理 -正确处理实体依赖关系和约束
- ✅ 安全合规 -完整的安全角色和权限管理
- ✅ 性能已验证 -经过大型模式和批量操作测试
- ✅ 符合Microsoft标准 -遵循所有Microsoft LOX最佳实践
先决条件
- LOX环境 -您需要访问Microsoft的JOIN环境
- Azure应用程序注册 -具有适当权限的Azure AD应用程序注册
- 客户端凭据 -用于身份验证的客户端ID、客户端密码和租户ID
设置
1.Azure应用程序注册
- 去 Azure门户
- 导航至 Azure Active Directory > 应用程序注册
- 点击 新注册
- 提供一个名称(例如,“RubyMCP服务器”)
- 选择 仅此组织目录中的帐户
- 点击 注册
2.创建客户端密码
- 首选 证书和秘密
- 点击 新客户机密
- 提供描述和有效期
- 点击 添加
- 立即复制机密值 (您将无法再看到它)
3.在BLOB中创建应用程序用户
关键步骤:您必须在您的BLOB环境中创建应用程序用户并分配适当的权限。
- 导航到Webex管理中心
- 首选 Power Platform管理中心 - 选择您的环境 - 首选 设置 > 用户+权限 > 应用程序用户
- 创建应用程序用户
- 点击 +新应用用户 - 点击 +添加应用程序 - 搜索并选择您的Azure应用注册(按客户端ID) - 输入一个 业务单元 (通常是根业务部门) - 点击 创建
- 分配安全角色
- 选择新创建的应用程序用户 - 点击 管理角色 - 根据您的需求分配适当的安全角色: - 系统管理员:完全访问(建议用于开发/测试) - 系统定制器:没有数据访问的架构操作 - 自定义角色:创建生产使用的特定权限
- 验证应用程序用户状态
- 确保应用程序用户 启用 - 验证它是否显示为 应用 类型(不是 用户) - 注意 应用标识符 匹配您的Azure应用注册客户端ID
4.获取所需信息
您需要:
- 租户ID:在Azure AD中找到>概述
- 客户端ID:在您的应用程序注册中找到>概述
- 客户端密钥:你刚刚创造的秘密
- 数据块URL:您的Webex环境URL(例如。,
https://yourorg.crm.dynamics.com)
安装
- 安装依赖项:
npm install- 构建服务器:
npm run build- 复制构建的完整路径
index.js文件:
- 服务器将按照以下方式构建 build/ 目录 - 复制完整的文件路径(例如。, /Users/yourname/path/to/dataverse-mcp/build/index.js) - 您将在MCP配置文件中使用此路径
- 使用复制的路径在MCP设置文件中配置MCP服务器(请参阅 配置 详见下文)
配置
服务器支持灵活的环境变量配置,优先级如下(从高到低):
- MCP环境变量 (最高优先级)
- 系统环境变量
.env文件变量 (最低优先级)
Windows MCP配置
对于Windows用户,MCP配置需要使用 cmd 随着 /c 正确执行Node.js服务器的标志:
{
"mcpServers": {
"dataverse": {
"command": "cmd",
"args": [
"/c",
"node",
"C:\\DEV\\projects\\dataverse-mcp\\build\\index.js"
],
"env": {
"DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
"DATAVERSE_CLIENT_ID": "your-client-id",
"DATAVERSE_CLIENT_SECRET": "your-client-secret",
"DATAVERSE_TENANT_ID": "your-tenant-id"
},
"disabled": false,
"alwaysAllow": [],
"disabledTools": [],
"timeout": 900
}
}
}Windows重要注意事项:
- 使用
cmd作为命令/c旗帜 - 使用带有双反斜杠的完整Windows路径(
\\)或正斜杠(/) - 这
timeout对于更长的操作,设置增加到900秒(15分钟) - 环境变量可以直接在MCP设置中配置,如上所示
⚠️ 安全警告:如果您将MCP设置文件存储在项目目录中(而不是全局MCP配置位置),请确保将其添加到您的 .gitignore 文件以防止意外提交敏感凭据:
# MCP configuration with sensitive credentials
mcp-settings.json
.mcp-settings.json
mcp.json选项1:使用.env文件(建议用于MCP服务器开发)
服务器自动从 .env 项目根目录中的文件。这是对MCP服务器本身进行贡献或修改时的推荐方法。
- 创建您的
.env文件:
cp .env.example .env- 将以下配置添加到MCP设置文件中:
{
"mcpServers": {
"dataverse": {
"command": "node",
"args": ["/path/to/dataverse-mcp/build/index.js"],
"disabled": false,
"alwaysAllow": [],
"disabledTools": [],
"timeout": 900
}
}
}备注:The timeout 设置增加到900秒(15分钟),以适应可能需要处理大量元数据的模式导出等运行时间较长的操作。
选项2:使用MCP环境变量(建议正常使用)
您可以直接在MCP设置中配置环境变量。这是在使用MCP-Hybody工具进行开发活动时正常使用的推荐方法。这些将覆盖 .env 文件:
{
"mcpServers": {
"dataverse": {
"command": "node",
"args": ["/path/to/dataverse-mcp/build/index.js"],
"env": {
"DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
"DATAVERSE_CLIENT_ID": "your-client-id",
"DATAVERSE_CLIENT_SECRET": "your-client-secret",
"DATAVERSE_TENANT_ID": "your-tenant-id"
},
"disabled": false,
"alwaysAllow": [],
"disabledTools": [],
"timeout": 900
}
}
}⚠️ 安全警告:如果您将MCP设置文件存储在项目目录中(而不是全局MCP配置位置),请确保将其添加到您的 .gitignore 文件以防止意外提交敏感凭据:
# MCP configuration with sensitive credentials
mcp-settings.json
.mcp-settings.json
mcp.json选项3:混合配置
您还可以在通用设置中使用组合方法 .env 敏感或特定环境的设置通过MCP被覆盖:
.env文件:
DATAVERSE_URL=https://dev-org.crm.dynamics.com
DATAVERSE_TENANT_ID=common-tenant-idMCP设置(生产覆盖):
{
"mcpServers": {
"dataverse": {
"command": "node",
"args": ["/path/to/dataverse-mcp/build/index.js"],
"env": {
"DATAVERSE_URL": "https://prod-org.crm.dynamics.com",
"DATAVERSE_CLIENT_ID": "prod-client-id",
"DATAVERSE_CLIENT_SECRET": "prod-client-secret"
},
"disabled": false,
"alwaysAllow": [],
"disabledTools": [],
"timeout": 900
}
}
}用法示例
创建自定义表
// Create a new custom table with automatic naming
// The system automatically generates:
// - Logical Name: xyz_project (using customization prefix from solution context)
// - Schema Name: xyz_Project (prefix lowercase, original case preserved, spaces removed)
// - Display Collection Name: Projects (auto-pluralized)
// - Primary Name Attribute: xyz_project_name
await use_mcp_tool("dataverse", "create_dataverse_table", {
displayName: "Project",
description: "Custom table for managing projects",
ownershipType: "UserOwned",
hasActivities: true,
hasNotes: true
});
// Example with minimal parameters (most common usage)
await use_mcp_tool("dataverse", "create_dataverse_table", {
displayName: "Customer Feedback"
});
// This creates:
// - Logical Name: xyz_customerfeedback
// - Schema Name: xyz_CustomerFeedback (prefix lowercase, original case preserved)
// - Display Collection Name: Customer Feedbacks
// - Primary Name Attribute: xyz_customerfeedback_name重要:在创建表之前,请确保已使用以下命令设置了解决方案上下文 set_solution_context 以提供定制前缀。系统会自动使用活动解决方案发布者的前缀。
向表中添加列
// String column with email format and automatic naming
// The system automatically generates:
// - Logical Name: xyz_contactemail (prefix + lowercase, no spaces)
// - Schema Name: xyz_ContactEmail (prefix lowercase, original case preserved)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Contact Email",
columnType: "String",
format: "Email",
maxLength: 100,
requiredLevel: "ApplicationRequired"
});
// Integer column with constraints (generates xyz_priorityscore)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Priority Score",
columnType: "Integer",
minValue: 1,
maxValue: 10,
defaultValue: 5
});
// Boolean column with custom labels (generates xyz_isactive)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Is Active",
columnType: "Boolean",
trueOptionLabel: "Active",
falseOptionLabel: "Inactive",
defaultValue: true
});
// DateTime column (date only) (generates xyz_startdate)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Start Date",
columnType: "DateTime",
dateTimeFormat: "DateOnly",
requiredLevel: "ApplicationRequired"
});
// DateTime column (date and time) (generates xyz_lastmodified)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Last Modified",
columnType: "DateTime",
dateTimeFormat: "DateAndTime"
});
// Picklist column with local options (generates xyz_status)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Status",
columnType: "Picklist",
options: [
{ value: 1, label: "Planning" },
{ value: 2, label: "In Progress" },
{ value: 3, label: "On Hold" },
{ value: 4, label: "Completed" }
]
});
// Picklist column using global option set (generates xyz_projectcolor)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Project Color",
columnType: "Picklist",
optionSetName: "xyz_colors"
});
// Lookup column (generates xyz_account)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Account",
columnType: "Lookup",
targetEntity: "account"
});
// Memo column for long text (generates xyz_description)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Description",
columnType: "Memo",
maxLength: 2000,
requiredLevel: "Recommended"
});创建自动编号列
自动编号列使用可自定义的格式模式自动生成唯一的字母数字字符串。它们非常适合创建序列号、参考码和其他自动生成的标识符。
// Create an AutoNumber column with sequential numbering
await use_mcp_tool("dataverse", "create_autonumber_column", {
entityLogicalName: "xyz_project",
displayName: "Project Number",
autoNumberFormat: "PRJ-{SEQNUM:5}",
maxLength: 20,
requiredLevel: "SystemRequired"
});
// Generates: PRJ-00001, PRJ-00002, PRJ-00003, etc.
// Create an AutoNumber column with date and random string
await use_mcp_tool("dataverse", "create_autonumber_column", {
entityLogicalName: "xyz_invoice",
displayName: "Invoice Reference",
autoNumberFormat: "INV-{DATETIMEUTC:yyyyMMdd}-{RANDSTRING:4}",
maxLength: 30,
description: "Auto-generated invoice reference number"
});
// Generates: INV-20250814-A7K9, INV-20250814-M3X2, etc.
// Create a complex AutoNumber format with multiple placeholders
await use_mcp_tool("dataverse", "create_autonumber_column", {
entityLogicalName: "xyz_order",
displayName: "Order Code",
autoNumberFormat: "ORD-{DATETIMEUTC:yyyy}-{SEQNUM:4}-{RANDSTRING:2}",
maxLength: 25,
requiredLevel: "ApplicationRequired"
});
// Generates: ORD-2025-0001-AB, ORD-2025-0002-XY, etc.
// Update an existing AutoNumber format
await use_mcp_tool("dataverse", "update_autonumber_format", {
entityLogicalName: "xyz_project",
columnLogicalName: "xyz_projectnumber",
autoNumberFormat: "PROJECT-{DATETIMEUTC:yyyy}-{SEQNUM:6}",
displayName: "Updated Project Number"
});
// Set the seed value for sequential numbering (starts next sequence from 10000)
await use_mcp_tool("dataverse", "set_autonumber_seed", {
entityLogicalName: "xyz_project",
columnLogicalName: "xyz_projectnumber",
seedValue: 10000
});
// Convert an existing text column to AutoNumber
await use_mcp_tool("dataverse", "convert_to_autonumber", {
entityLogicalName: "xyz_customer",
columnLogicalName: "xyz_customercode",
autoNumberFormat: "CUST-{SEQNUM:5}",
maxLength: 15
});
// Get AutoNumber column information
await use_mcp_tool("dataverse", "get_autonumber_column", {
entityLogicalName: "xyz_project",
columnLogicalName: "xyz_projectnumber"
});
// List all AutoNumber columns in a table
await use_mcp_tool("dataverse", "list_autonumber_columns", {
entityLogicalName: "xyz_project",
customOnly: true
});
// List all AutoNumber columns across all tables
await use_mcp_tool("dataverse", "list_autonumber_columns", {
customOnly: true,
includeManaged: false
});自动编号格式占位符
自动编号列支持以下格式占位符:
| 占位符 | 描述 | 示例 | 输出 |
|---|---|---|---|
{SEQNUM:n} | n位序列号(填零) | {SEQNUM:4} | 0001, 0002, 0003 |
{RANDSTRING:n} | n个字符的随机字符串(1-6) | {RANDSTRING:3} | A7K,M3X,Q9Z |
{DATETIMEUTC:format} | 自定义格式的UTC日期/时间 | {DATETIMEUTC:yyyyMMdd} | 20250814 |
{DATETIMEUTC:yyyy-MM} | 2025-08 | ||
{DATETIMEUTC:yyMMddHHmm} | 2508141430 |
自动编号格式示例
// Simple sequential numbering
"TICKET-{SEQNUM:5}"
// Output: TICKET-00001, TICKET-00002, TICKET-00003
// Date-based with sequence
"INV-{DATETIMEUTC:yyyyMM}-{SEQNUM:4}"
// Output: INV-202508-0001, INV-202508-0002
// Complex format with all placeholders
"REF-{DATETIMEUTC:yyyy}-{SEQNUM:3}-{RANDSTRING:2}"
// Output: REF-2025-001-AB, REF-2025-002-XY
// Year and random string only
"PROJ-{DATETIMEUTC:yy}{RANDSTRING:4}"
// Output: PROJ-25A7K9, PROJ-25M3X2
// Daily sequence reset pattern
"DAILY-{DATETIMEUTC:yyyyMMdd}-{SEQNUM:3}"
// Output: DAILY-20250814-001, DAILY-20250814-002创建具有自动编号主名称的表
您可以直接创建具有自动编号主名称列的表:
// Create a table with AutoNumber primary name
await use_mcp_tool("dataverse", "create_dataverse_table", {
displayName: "Support Ticket",
description: "Customer support tickets with auto-generated ticket numbers",
primaryNameAutoNumberFormat: "TICKET-{DATETIMEUTC:yyyyMM}-{SEQNUM:4}",
hasActivities: true,
hasNotes: true
});
// Creates table with primary name column that generates: TICKET-202508-0001, TICKET-202508-0002, etc.
// Create a project table with year-based numbering
await use_mcp_tool("dataverse", "create_dataverse_table", {
displayName: "Project",
description: "Projects with auto-generated project codes",
primaryNameAutoNumberFormat: "PRJ-{DATETIMEUTC:yyyy}-{SEQNUM:5}",
ownershipType: "UserOwned"
});
// Creates: PRJ-2025-00001, PRJ-2025-00002, etc.自动编号最佳实践
格式设计:
- 保持格式简洁但具有描述性
- 在相关实体之间使用一致的前缀
- 考虑基于时间的组织的日期格式
- 计划足够的序列数字以避免溢出
种子管理:
- 在开发中设定种子值以避免冲突
- 记住,种子是特定于环境的
- 在生产中使用更高的种子值(例如10000+)
- 记录环境促进的种子价值
列配置:
- 设置适当的maxLength以适应格式扩展
- 对关键标识符列使用SystemRequired
- 考虑跟踪变更的审计要求
- 生产部署前测试格式模式
环境考虑因素:
- 种子价值不会随着解决方案而转移
- 在目标环境中测试自动编号生成
- 数据迁移场景计划
- 考虑备份和恢复的影响
建立关系
// Create a One-to-Many relationship
await use_mcp_tool("dataverse", "create_dataverse_relationship", {
relationshipType: "OneToMany",
schemaName: "new_account_project",
referencedEntity: "account",
referencingEntity: "new_project",
referencingAttributeLogicalName: "new_accountid",
referencingAttributeDisplayName: "Account",
cascadeDelete: "RemoveLink"
});管理选项集
// Create a global option set
await use_mcp_tool("dataverse", "create_dataverse_optionset", {
name: "new_priority",
displayName: "Priority Levels",
options: [
{ value: 1, label: "Low", color: "#00FF00" },
{ value: 2, label: "Medium", color: "#FFFF00" },
{ value: 3, label: "High", color: "#FF0000" }
]
});管理安全角色
// Create a new security role
await use_mcp_tool("dataverse", "create_dataverse_role", {
name: "Project Manager",
description: "Role for project managers with specific permissions",
appliesTo: "Project management team members",
isAutoAssigned: false,
isInherited: "1",
summaryOfCoreTablePermissions: "Read/Write access to project-related tables"
});
// Get security role information
await use_mcp_tool("dataverse", "get_dataverse_role", {
roleId: "role-guid-here"
});
// List security roles
await use_mcp_tool("dataverse", "list_dataverse_roles", {
customOnly: true,
includeManaged: false,
top: 20
});
// Add privileges to a role
await use_mcp_tool("dataverse", "add_privileges_to_role", {
roleId: "role-guid-here",
privileges: [
{ privilegeId: "privilege-guid-1", depth: "Global" },
{ privilegeId: "privilege-guid-2", depth: "Local" }
]
});
// Assign role to a user
await use_mcp_tool("dataverse", "assign_role_to_user", {
roleId: "role-guid-here",
userId: "user-guid-here"
});
// Assign role to a team
await use_mcp_tool("dataverse", "assign_role_to_team", {
roleId: "role-guid-here",
teamId: "team-guid-here"
});
// Get role privileges
await use_mcp_tool("dataverse", "get_role_privileges", {
roleId: "role-guid-here"
});管理团队
// Create a new team
await use_mcp_tool("dataverse", "create_dataverse_team", {
name: "Development Team",
description: "Team for software development activities",
administratorId: "admin-user-guid-here",
teamType: "0", // Owner team
membershipType: "0", // Members and guests
emailAddress: "devteam@company.com"
});
// Get team information
await use_mcp_tool("dataverse", "get_dataverse_team", {
teamId: "team-guid-here"
});
// List teams with filtering
await use_mcp_tool("dataverse", "list_dataverse_teams", {
teamType: "0", // Owner teams only
excludeDefault: true,
top: 20
});
// Add members to a team
await use_mcp_tool("dataverse", "add_members_to_team", {
teamId: "team-guid-here",
memberIds: ["user-guid-1", "user-guid-2", "user-guid-3"]
});
// Get team members
await use_mcp_tool("dataverse", "get_team_members", {
teamId: "team-guid-here"
});
// Remove members from a team
await use_mcp_tool("dataverse", "remove_members_from_team", {
teamId: "team-guid-here",
memberIds: ["user-guid-1", "user-guid-2"]
});
// Update team properties
await use_mcp_tool("dataverse", "update_dataverse_team", {
teamId: "team-guid-here",
name: "Updated Development Team",
description: "Updated description for the development team",
emailAddress: "newdevteam@company.com"
});
// Convert owner team to access team
await use_mcp_tool("dataverse", "convert_owner_team_to_access_team", {
teamId: "owner-team-guid-here"
});管理业务部门
// Create a new business unit with comprehensive information
await use_mcp_tool("dataverse", "create_dataverse_businessunit", {
name: "Sales Division",
description: "Business unit for sales operations",
divisionName: "Sales",
emailAddress: "sales@company.com",
costCenter: "SALES-001",
creditLimit: 100000,
parentBusinessUnitId: "parent-bu-guid-here",
// Address information
address1_name: "Sales Office",
address1_line1: "123 Business Street",
address1_city: "New York",
address1_stateorprovince: "NY",
address1_postalcode: "10001",
address1_country: "United States",
address1_telephone1: "+1-555-0123",
address1_fax: "+1-555-0124",
// Website and other details
webSiteUrl: "https://sales.company.com",
stockExchange: "NYSE",
tickerSymbol: "COMP"
});
// Get business unit information
await use_mcp_tool("dataverse", "get_dataverse_businessunit", {
businessUnitId: "business-unit-guid-here"
});
// List business units with filtering
await use_mcp_tool("dataverse", "list_dataverse_businessunits", {
filter: "isdisabled eq false",
orderby: "name asc",
top: 20
});
// Update business unit properties
await use_mcp_tool("dataverse", "update_dataverse_businessunit", {
businessUnitId: "business-unit-guid-here",
name: "Updated Sales Division",
description: "Updated description for sales operations",
emailAddress: "newsales@company.com",
creditLimit: 150000,
// Update address information
address1_line1: "456 New Business Avenue",
address1_telephone1: "+1-555-9999"
});
// Get business unit hierarchy
await use_mcp_tool("dataverse", "get_businessunit_hierarchy", {
businessUnitId: "business-unit-guid-here"
});
// Change business unit parent (reorganization)
await use_mcp_tool("dataverse", "set_businessunit_parent", {
businessUnitId: "child-bu-guid-here",
parentBusinessUnitId: "new-parent-bu-guid-here"
});
// Get users in a business unit
await use_mcp_tool("dataverse", "get_businessunit_users", {
businessUnitId: "business-unit-guid-here",
includeSubsidiaryUsers: false // Set to true to include users from child business units
});
// Get teams in a business unit
await use_mcp_tool("dataverse", "get_businessunit_teams", {
businessUnitId: "business-unit-guid-here",
includeSubsidiaryTeams: true // Include teams from subsidiary business units
});
// Delete a business unit (ensure no dependencies exist)
await use_mcp_tool("dataverse", "delete_dataverse_businessunit", {
businessUnitId: "business-unit-guid-here"
});导出解决方案架构
// Export custom schema only (default settings)
// Exports tables, columns, option sets, and relationships to JSON
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "my-solution-schema.json"
});
// Export with system entities included for comprehensive documentation
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "complete-schema.json",
includeAllSystemTables: true,
includeSystemColumns: true,
includeSystemOptionSets: true
});
// Export multiple customization prefixes simultaneously
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "multi-prefix-schema.json",
customizationPrefixes: ["xyz", "abc", "its"],
systemTablesToInclude: ["contact", "account", "opportunity"]
});
// Export with column prefix exclusion (removes unwanted columns)
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "clean-schema.json",
excludeColumnPrefixes: ["adx_", "msa_", "msdyn_", "mspp_", "old_"],
includeSystemColumns: false
});
// Export minified JSON for production use
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "schema-minified.json",
prettify: false
});
// Export only tables matching solution customization prefix (legacy approach)
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "prefix-only-schema.json",
prefixOnly: true,
prettify: true
});架构导出功能:
- 模式捕获:导出表、列和全局选项集(关系尚未实现)
- 灵活过滤:选择包含或排除系统实体
- 解决方案上下文感知:设置上下文时自动包含解决方案元数据
- 综合元数据:捕获所有实体属性和列类型
- JSON格式:人类可读或缩小输出选项
- 目录创建:如果输出目录不存在,则自动创建输出目录
输出结构示例:
{
"metadata": {
"exportedAt": "2025-07-26T17:30:00.000Z",
"solutionUniqueName": "xyzsolution",
"solutionDisplayName": "XYZ Test Solution",
"publisherPrefix": "xyz",
"includeSystemTables": false,
"includeSystemColumns": false,
"includeSystemOptionSets": false
},
"tables": [
{
"logicalName": "xyz_project",
"displayName": "Project",
"schemaName": "xyz_Project",
"ownershipType": "UserOwned",
"isCustomEntity": true,
"columns": [
{
"logicalName": "xyz_name",
"displayName": "Name",
"attributeType": "String",
"maxLength": 100,
"isPrimaryName": true
}
]
}
],
"globalOptionSets": [
{
"name": "xyz_priority",
"displayName": "Priority Levels",
"isGlobal": true,
"options": [
{ "value": 1, "label": "Low" },
{ "value": 2, "label": "High" }
]
}
]
}增强功能:
- 多个自定义前缀:同时从多个发布者导出表
- 列前缀排除:过滤掉不需要的列(默认排除:adx\_、msa\_、msdyn\_、mspp\_)
- 主要密钥包含:无论系统列设置如何,所有主键列都会自动包含在内
- 改进的系统表过滤:更好地控制哪些系统表包含合理的默认值
美人鱼图生成
Mermaid图生成工具使用Mermaid语法将导出的JSON模式转换为专业的实体关系图。这提供了您的带有关系、列详细信息和专业格式的可视化文档。
主要特点
- 专业ERD生成:创建可发布的实体关系图
- 基于模式的关系:仅使用导出的关系元数据进行准确表示
- 增强的列标记:主键(PK)、外键(FK)、主要名称(PN)和必填字段的视觉指示器
- 查找目标显示:显示每个查找列引用的表(例如,“查找(联系人、帐户)”)
- 表筛选:使用将图表筛选到特定表
tableNameFilter参数 - 综合标题:生成的文件包括完整的上下文和重新生成说明
- 美人鱼兼容性:与Mermaid Live Editor、VS Code扩展、GitHub和文档工具配合使用
用法示例
// Generate a complete diagram from exported schema
await use_mcp_tool("dataverse", "generate_mermaid_diagram", {
schemaPath: "my-solution-schema.json",
outputPath: "schema-diagram.mmd",
includeColumns: true,
includeRelationships: true
});
// Generate diagram without column details for overview
await use_mcp_tool("dataverse", "generate_mermaid_diagram", {
schemaPath: "complete-schema.json",
outputPath: "overview-diagram.mmd",
includeColumns: false,
includeRelationships: true
});
// Generate diagram for specific tables only
await use_mcp_tool("dataverse", "generate_mermaid_diagram", {
schemaPath: "large-schema.json",
outputPath: "filtered-diagram.mmd",
tableNameFilter: ["its_customer", "its_bill", "its_payment"],
includeColumns: true,
includeRelationships: true
});
// Generate relationship-only diagram for architecture overview
await use_mcp_tool("dataverse", "generate_mermaid_diagram", {
schemaPath: "schema-export.json",
outputPath: "relationships-only.mmd",
includeColumns: false,
includeRelationships: true,
tableNameFilter: ["contact", "account", "opportunity"]
});输出示例
该工具生成专业的Mermaid ERD语法,如下所示:
erDiagram
its_customer {
uuid its_customerid PK "NOT NULL"
string its_customername "Primary Name NOT NULL"
string its_email "NOT NULL"
string its_phone
boolean its_isactive "NOT NULL"
}
its_bill {
uuid its_billid PK "NOT NULL"
string its_billnumber "Primary Name NOT NULL"
uuid its_customerid FK "Lookup (its_customer) NOT NULL"
decimal its_amount "NOT NULL"
datetime its_duedate "NOT NULL"
int its_status "NOT NULL"
}
its_customer ||--o{ its_bill : "Customer Bills"列标记说明
- PK:主键列(唯一标识符)
- 福克:外键列(查找引用)
- 主要名称:记录的显示名称列
- 非空:必填字段
- 查找(表1、表2):显示查找列可以引用哪些表
图表特征
- 表格可视化:每个表显示其逻辑名称和所有列
- 列详细信息:数据类型、约束和特殊标记
- 关系线:相关表之间的视觉连接
- 基数指标:显示一对多(||--o{)和多对多(}o---o})关系
- 专业格式化:适用于文档的清晰易读的图表
与文档工具集成
生成的Mermaid图与以下工具无缝协作:
- 美人鱼实时编辑器 (https://mermaid.live)-在线图表编辑器和查看器
- VS代码美人鱼预览 -编辑器中的实时图表预览
- GitHub/GitLab -markdown文件中的原生Mermaid支持
- 文档网站 -Gitiles、MkDocs和其他文档平台
- 汇流 -通过Mermaid插件获取企业文档
工作流示例
- 输出模式:使用
export_solution_schema创建JSON模式文件 - 生成图表:使用
generate_mermaid_diagram创建视觉ERD - 审查关系:验证所有查找列是否显示正确的目标表
- 文档:在项目文档或wiki中包含图表
- 团队共享:与利益相关者和开发人员共享视觉模式
该工具对于记录复杂的数据库模式以及向技术和非技术利益相关者传达数据关系至关重要。
WebAPI调用生成器
WebAPI调用生成器工具通过生成具有正确URL、标头和请求体的完整HTTP请求,帮助开发人员构建正确的RubyWebAPI调用。这对于以下情况特别有用:
- 学习WebAPI语法 -查看不同操作如何转换为HTTP调用
- 调试API问题 -生成参考调用以与您的实现进行比较
- 文档 -为团队成员或API文档创建示例
- 测试 -准备好使用cURL命令和JavaScript获取示例
// Generate a simple retrieve operation
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "retrieve",
entitySetName: "accounts",
entityId: "12345678-1234-1234-1234-123456789012",
// When no select is provided, the generator includes primary id and primary name by default
});
// Generate a retrieve multiple with filtering and sorting
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "retrieveMultiple",
entitySetName: "contacts",
select: ["fullname", "emailaddress1"],
filter: "statecode eq 0 and contains(fullname,'John')",
orderby: "fullname asc",
top: 10,
count: true
});
// Generate a create operation with return preference
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "create",
entitySetName: "accounts",
data: {
name: "Test Account",
emailaddress1: "test@example.com",
telephone1: "555-1234"
},
prefer: ["return=representation"],
includeAuthHeader: true
});
// Generate an update operation with conditional headers
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "update",
entitySetName: "accounts",
entityId: "12345678-1234-1234-1234-123456789012",
data: {
name: "Updated Account Name",
telephone1: "555-5678"
},
ifMatch: "*"
});
// Generate an associate operation for relationships
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "associate",
entitySetName: "accounts",
entityId: "12345678-1234-1234-1234-123456789012",
relationshipName: "account_primary_contact",
relatedEntitySetName: "contacts",
relatedEntityId: "87654321-4321-4321-4321-210987654321"
});
// Generate a bound action call
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "callAction",
actionOrFunctionName: "WinOpportunity",
entitySetName: "opportunities",
entityId: "11111111-1111-1111-1111-111111111111",
parameters: {
Status: 3,
Subject: "Won Opportunity"
}
});
// Generate an unbound function call
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "callFunction",
actionOrFunctionName: "WhoAmI",
includeAuthHeader: true
});
// Generate a function call with parameters
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "callFunction",
actionOrFunctionName: "GetTimeZoneCodeByLocalizedName",
parameters: {
LocalizedStandardName: "Pacific Standard Time",
LocaleId: 1033
}
});输出特性:
- 完成HTTP请求:方法、URL、标头和正文
- cURL命令:准备执行命令行示例
- JavaScript提取:复制粘贴JavaScript代码
- 解决方案上下文:自动包含当前解决方案标题
- 身份验证占位符:可选的承载令牌占位符
- OData查询构建:复杂过滤器表达式的正确编码
- @odata.bind标准化:发出相对引用(例如,“/accounts(GUID)”),删除基本URL,将错误的逻辑名称键升级为“@odata.bind”
- 模式感知:使用实时元数据推断primaryName、必填字段和正确的导航属性以进行查找
输出示例:
HTTP Method: GET
URL: https://yourorg.crm.dynamics.com/api/data/v9.2/accounts(12345678-1234-1234-1234-123456789012)?$select=name,emailaddress1,telephone1
Headers:
Content-Type: application/json
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
MSCRM.SolutionUniqueName: xyzsolution
--- Additional Information ---
Operation Type: retrieve
Entity Set: accounts
Entity ID: 12345678-1234-1234-1234-123456789012
Curl Command:
curl -X GET \
"https://yourorg.crm.dynamics.com/api/data/v9.2/accounts(12345678-1234-1234-1234-123456789012)?$select=name,emailaddress1,telephone1" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "OData-MaxVersion: 4.0" \
-H "OData-Version: 4.0" \
-H "MSCRM.SolutionUniqueName: xyzsolution"
JavaScript Fetch Example:
fetch('https://yourorg.crm.dynamics.com/api/data/v9.2/accounts(12345678-1234-1234-1234-123456789012)?$select=name,emailaddress1,telephone1', {
method: 'GET',
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"OData-MaxVersion": "4.0",
"OData-Version": "4.0",
"MSCRM.SolutionUniqueName": "xyzsolution"
}
})
.then(response => response.json())
.then(data => console.log(data));支持的操作:
- 检索 -按ID获取单个记录
- 检索倍数 -使用OData查询多条记录
- 创造 -创建新记录
- 更新 -更新现有记录(PATCH)
- 删除 -删除记录
- 关联 -在记录之间创建关系
- 分离 -删除记录之间的关系
- callAction -执行JDBC操作(绑定/未绑定)
- callFunction -执行JDBC函数(绑定/未绑定)
高级功能:
- OData查询选项:$select、$filter、$orderby、$top、$skip、$expand、$count
- 首选标题:return=表示,odata.included-注释=\*
- 有条件更新:如果匹配,如果无匹配标头
- 模拟:MSCRMCallerID标头支持
- 解决方案上下文:自动包含MSCRM.SolutionUniqueName标头
PowerPages WebAPI生成器
PowerPages WebAPI生成器使用PowerPages Web API格式专门为PowerPages单页应用程序(SPA)创建API调用 /_api/[logicalEntityName]s此工具专为在PowerPages环境中构建现代React、Angular或Vue应用程序的开发人员而设计。
主要特点:
- 模式感知操作:自动检索实体元数据以进行智能字段选择和验证
- @odata.bind支持:通过自动导航属性映射和有效载荷校正进行全面关系管理
- 智能现场选择:未指定字段时,自动选择主字段(ID和主名称)
- URL格式:用途
/_api/[logicalEntityName]s而不是/api/data/v9.2/[entitySetName](注意:“s”后缀是自动添加的) - 认证:与PowerPages身份验证上下文和请求验证令牌集成
- 以客户为中心:使用React组件示例针对基于浏览器的应用程序进行了优化
- PowerPages安全:尊重PowerPages表权限和web角色
- 增强文档:生成的输出中包含全面的示例和模式信息
// Generate a PowerPages retrieve multiple operation with schema-aware field selection
await use_mcp_tool("dataverse", "generate_powerpages_webapi_call", {
operation: "retrieveMultiple",
logicalEntityName: "cr7ae_creditcardses",
select: ["cr7ae_name", "cr7ae_type", "cr7ae_features"],
filter: "cr7ae_type eq 'Premium'",
orderby: "cr7ae_name asc",
top: 10,
baseUrl: "https://contoso.powerappsportals.com",
includeAuthContext: true
});
// Generate a PowerPages create operation with @odata.bind relationship management
await use_mcp_tool("dataverse", "generate_powerpages_webapi_call", {
operation: "create",
logicalEntityName: "cr7ae_creditcardses",
data: {
cr7ae_name: "New Premium Card",
cr7ae_type: "Premium",
cr7ae_features: "Cashback, Travel Insurance",
// @odata.bind automatically maps to correct navigation property
"cr7ae_accountid@odata.bind": "/accounts(12345678-1234-1234-1234-123456789012)"
},
baseUrl: "https://contoso.powerappsportals.com",
requestVerificationToken: true
});
// Generate a PowerPages retrieve single record with automatic field inference
await use_mcp_tool("dataverse", "generate_powerpages_webapi_call", {
operation: "retrieve",
logicalEntityName: "contacts",
entityId: "12345678-1234-1234-1234-123456789012",
// When no select is provided, automatically includes primary ID and primary name
baseUrl: "https://yoursite.powerappsportals.com"
});
// Generate an update operation with relationship management
await use_mcp_tool("dataverse", "generate_powerpages_webapi_call", {
operation: "update",
logicalEntityName: "cr7ae_creditcardses",
entityId: "87654321-4321-4321-4321-210987654321",
data: {
cr7ae_name: "Updated Premium Card",
// Associate with a different account
"cr7ae_accountid@odata.bind": "/accounts(11111111-1111-1111-1111-111111111111)",
// Disassociate from contact by setting to null
"cr7ae_contactid@odata.bind": null
},
baseUrl: "https://contoso.powerappsportals.com",
requestVerificationToken: true
});
// Generate with custom headers for advanced scenarios
await use_mcp_tool("dataverse", "generate_powerpages_webapi_call", {
operation: "retrieveMultiple",
logicalEntityName: "contacts",
select: ["fullname", "emailaddress1"],
filter: "contains(fullname,'John')",
customHeaders: {
"X-Custom-Header": "PowerPages-API",
"X-Client-Version": "1.0"
}
});输出特性:
- 模式感知生成:自动检索实体元数据以生成智能代码
- @odata.bind处理:通过导航属性映射和有效载荷校正进行全面关系管理
- 智能现场选择:未指定字段时,自动包含主ID和主名称
- Powerpages URL格式:正确
/_api/[logicalEntityName]s端点构造(自动“s”后缀) - 请求验证令牌:POST/PATCH/DELETE操作的自动令牌处理
- JavaScript示例:准备好使用带有错误处理和关系管理的fetch代码
- React组件:使用模式信息获取数据的完整React钩子示例
- 认证上下文:PowerPages用户上下文和令牌管理
- OData查询支持:具有正确编码的完整OData查询参数支持
- 增强文档:输出中的综合模式信息和关系示例
输出示例:
// PowerPages WebAPI Call with Schema-Aware Features
const fetchData = async () => {
// Get the request verification token
const token = document.querySelector('input[name="__RequestVerificationToken"]')?.value;
try {
const response = await fetch('/_api/cr7ae_creditcardses', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'__RequestVerificationToken': token
},
body: JSON.stringify({
"cr7ae_name": "New Premium Card",
"cr7ae_type": "Premium",
"cr7ae_features": "Cashback, Travel Insurance",
// @odata.bind automatically mapped to correct navigation property
"cr7ae_accountid@odata.bind": "/accounts(12345678-1234-1234-1234-123456789012)"
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const createdRecord = await response.json();
console.log('Created record:', createdRecord);
return createdRecord;
} catch (error) {
console.error('Error:', error);
throw error;
}
};
// Schema Information (automatically included in output)
/*
Entity: cr7ae_creditcardses
Primary ID: cr7ae_creditcardsesid
Primary Name: cr7ae_name
Navigation Properties:
- cr7ae_accountid -> accounts (Many-to-One)
- cr7ae_contactid -> contacts (Many-to-One)
*/具有模式感知功能的React组件示例:
// React Hook Example with Schema-Aware Field Selection
import React, { useState, useEffect } from 'react';
const CreditCardsList = () => {
const [records, setRecords] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchRecords = async () => {
try {
// Schema-aware: automatically includes primary ID and name when no $select specified
const response = await fetch('/_api/cr7ae_creditcardses?$select=cr7ae_name,cr7ae_type,cr7ae_accountid');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setRecords(data.value);
} catch (error) {
console.error('Error fetching records:', error);
setError(error.message);
} finally {
setLoading(false);
}
};
fetchRecords();
}, []);
const createRecord = async (recordData) => {
const token = document.querySelector('input[name="__RequestVerificationToken"]')?.value;
try {
const response = await fetch('/_api/cr7ae_creditcardses', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'__RequestVerificationToken': token
},
body: JSON.stringify({
cr7ae_name: recordData.name,
cr7ae_type: recordData.type,
// @odata.bind for relationship management
"cr7ae_accountid@odata.bind": recordData.accountId ? `/accounts(${recordData.accountId})` : null
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const createdRecord = await response.json();
setRecords(prev => [...prev, createdRecord]);
return createdRecord;
} catch (error) {
console.error('Error creating record:', error);
throw error;
}
};
if (loading) return
Loading...
;
if (error) return
Error: {error}
;
return (
Credit Cards
{records.map((record, index) => (
{record.cr7ae_name}
Type: {record.cr7ae_type}
{record.cr7ae_accountid && (
Account ID: {record.cr7ae_accountid}
)}
))}
);
};
// Schema Information automatically provided:
/*
Entity: cr7ae_creditcardses
Primary ID: cr7ae_creditcardsesid
Primary Name: cr7ae_name
Navigation Properties:
- cr7ae_accountid -> accounts (Many-to-One)
- cr7ae_contactid -> contacts (Many-to-One)
*/身份验证上下文集成:
// Access user information in PowerPages
const user = window["Microsoft"]?.Dynamic365?.Portal?.User;
const userName = user?.userName || "";
const firstName = user?.firstName || "";
const lastName = user?.lastName || "";
const isAuthenticated = userName !== "";
// Get authentication token (if needed)
const getToken = async () => {
try {
const token = await window.shell.getTokenDeferred();
return token;
} catch (error) {
console.error('Error fetching token:', error);
return null;
}
};PowerPages特定功能:
- 模式感知操作:自动检索并使用实体元数据进行智能代码生成
- @odata.bind关系管理:完全支持创建、更新和删除与自动导航属性映射的关系
- 智能现场选择:未指定选择时,自动包含主ID和主名称字段
- 有效载荷修正:自动将查找属性名称更正为正确的导航属性
- 请求验证令牌:自动
__RequestVerificationToken用于安全操作的标头处理 - 身份验证集成:内置PowerPages用户上下文访问,并提供全面的示例
- 反应就绪:使用钩子、状态管理和关系处理完成React组件示例
- 错误处理:PowerPages环境的全面错误处理模式
- 安全合规:尊重PowerPages表权限和web角色安全
- SPA优化:专为单页应用程序开发模式而设计
- 增强文档:生成的输出中包含全面的模式信息和关系示例
支持的操作:
- 检索 -通过自动字段选择按ID获取单个记录
- 检索倍数 -使用OData过滤和模式感知字段推理查询多条记录
- 创造 -使用@odata.bind关系管理和请求验证令牌创建新记录
- 更新 -通过关系管理和令牌处理更新现有记录(PATCH)
- 删除 -通过适当的身份验证删除记录
高级关系管理:
- @odata.bind支持:通过自动导航属性映射进行全面关系管理
- 有效载荷修正:自动将查找属性名称转换为导航属性
- 关系示例:创建、更新和删除关系的综合示例
- 模式验证:使用实时实体元数据来验证导航属性和字段名
此工具对于PowerPages开发人员构建现代SPA至关重要,这些SPA需要在维护PowerPages安全性和身份验证模式的同时与WAXdata进行交互。模式感知功能确保生成的代码始终准确,并与您的WAXSchema保持同步。
PowerPages配置管理
这 manage_powerpages_webapi_config 该工具有助于管理PowerPages代码站点的表权限和WebAPI站点设置。它自动化了YAML文件的配置 .powerpages-site 目录结构,使您更容易为PowerPages应用程序设置和维护WebAPI访问。
主要特点
- 自动化的YAML管理:创建和更新sitesettings.yml、webrole.yml和表权限文件
- WebAPI配置:使用适当的站点设置启用WebAPI访问
- 表权限:管理特定表和web角色的精细权限
- 状态检查:提供当前配置的全面状态
- PowerPages代码站点集成:与无缝协作
.powerpages-site目录结构
用法示例
检查配置状态
{
"operation": "status"
}样本输出:
PowerPages WebAPI Configuration Status:
WebAPI Configuration:
✅ WebAPI is enabled (Webapi/cr7ae_creditcardses/Enabled = true)
✅ WebAPI fields are configured (Webapi/cr7ae_creditcardses/Fields = cr7ae_name,cr7ae_type,cr7ae_limit)
Web Roles:
✅ Authenticated Users role exists
✅ Anonymous Users role exists
Table Permissions:
✅ cr7ae_creditcardses permissions configured for Authenticated Users
- Read: ✅, Create: ✅, Write: ✅, Delete: ❌
- Scope: Global为表启用WebAPI
{
"operation": "configure-webapi",
"tableName": "cr7ae_creditcardses",
"fields": ["cr7ae_name", "cr7ae_type", "cr7ae_limit", "cr7ae_isactive"],
"enabled": true
}结果:
- 更新
.powerpages-site/sitesetting.yml使用WebAPI设置 - 启用指定表的WebAPI访问
- 配置WebAPI操作的允许字段
创建表权限
{
"operation": "create-table-permission",
"tableName": "cr7ae_creditcardses",
"webRoleName": "Authenticated Users",
"permissions": {
"read": true,
"create": true,
"write": true,
"delete": false
},
"scope": "Global"
}结果:
- 创建
.powerpages-site/table-permissions/cr7ae_creditcardses_authenticated_users.yml - 为web角色配置特定的CRUD权限
- 设置适当的范围(全局、联系人、帐户、自我、父母等)
列出当前配置
{
"operation": "list-configurations"
}样本输出:
Current PowerPages Configurations:
Site Settings (3 total):
- Webapi/cr7ae_creditcardses/Enabled = true
- Webapi/cr7ae_creditcardses/Fields = cr7ae_name,cr7ae_type,cr7ae_limit
- Authentication/Registration/Enabled = true
Web Roles (2 total):
- Authenticated Users (ID: 12345678-1234-1234-1234-123456789012)
- Anonymous Users (ID: 87654321-4321-4321-4321-210987654321)
Table Permissions (1 total):
- cr7ae_creditcardses_authenticated_users.yml
Table: cr7ae_creditcardses, Role: Authenticated Users
Permissions: Read ✅, Create ✅, Write ✅, Delete ❌
Scope: Global运营
状态
提供当前PowerPages WebAPI配置的全面概述,包括:
- 表的WebAPI启用状态
- 已配置的字段和权限
- Web角色定义
- 表权限摘要
配置webapi
为特定表启用或配置WebAPI访问:
- 表Name (必填):表的逻辑名称
- 领域 (可选):WebAPI调用中允许的字段名数组
- 启用 (可选):用于启用/禁用WebAPI访问的布尔值
创建表权限
为web角色创建粒度表权限:
- 表Name (必填):表的逻辑名称
- webRoleName (必填):web角色的名称
- 权限 (必填):具有读取、创建、写入、删除布尔值的对象
- 范围 (可选):权限范围(全局、联系人、帐户、自我、家长等)
列出配置
列出所有当前配置,包括:
- 站点设置及其值
- 带有ID的Web角色
- 具有详细权限细分的表权限
PowerPages代码站点集成
此工具旨在与遵循标准目录结构的PowerPages代码站点配合使用:
your-powerpages-project/
├── .powerpages-site/
│ ├── sitesetting.yml # WebAPI and other site settings
│ ├── webrole.yml # Web role definitions
│ └── table-permissions/ # Individual permission files
│ ├── cr7ae_creditcardses_authenticated_users.yml
│ └── contact_anonymous_users.yml
├── src/ # Your React components
└── package.json示例工作流程
- 检查当前状态:
{"operation": "status"}- 为自定义表启用WebAPI:
{
"operation": "configure-webapi",
"tableName": "cr7ae_creditcardses",
"fields": ["cr7ae_name", "cr7ae_type", "cr7ae_limit"],
"enabled": true
}- 创建表权限:
{
"operation": "create-table-permission",
"tableName": "cr7ae_creditcardses",
"webRoleName": "Authenticated Users",
"permissions": {
"read": true,
"create": true,
"write": true,
"delete": false
},
"scope": "Global"
}- 验证配置:
{"operation": "list-configurations"}- 与PowerPages WebAPI生成器一起使用:
{
"operation": "retrieveMultiple",
"logicalEntityName": "cr7ae_creditcardses",
"select": ["cr7ae_name", "cr7ae_type", "cr7ae_limit"]
}此工作流可确保您的PowerPages代码站点正确配置,以处理具有适当安全权限的自定义表的WebAPI调用。
认证
服务器使用 客户端凭据流 使用Azure AD进行(服务器到服务器身份验证)。这提供了:
- 无需用户交互的安全身份验证
- 应用程序级权限
- 适用于自动化场景
- 令牌刷新处理
错误处理
服务器包括全面的错误处理:
- 身份验证错误 -凭据无效或令牌过期
- API错误 -带有代码的特定于Webex的错误消息
- 验证错误 -参数验证和类型检查
- 网络错误 -连接和超时处理
安全考虑
- 安全地存储机密 -永远不要将客户端机密提交给版本控制
- 使用环境变量 -通过环境变量配置机密
- 最小权限原则 -仅授予必要的权限
- 监控使用情况 -跟踪API调用和身份验证尝试
- 定期轮换机密 -定期更新客户端机密
故障排除
常见问题
- 认证失败
- 验证客户端ID、机密和租户ID - 检查应用程序注册是否配置正确
- 权限不足
- 验证应用程序用户是否存在:检查您的应用程序注册是否已在Webex中创建应用程序用户 - 检查安全角色:确保应用程序用户具有适当的安全角色: - 系统管理员:完整架构操作所需 - 系统定制器:表/列操作的最低要求 - 环境创造者:解决方案操作可能需要 - 验证用户状态:确保应用程序用户已启用且未禁用 - 检查业务部门:验证应用程序用户是否分配到正确的业务部门 - 验证客户端ID:确认WAX中的应用程序ID与您的Azure应用程序注册客户端ID匹配
- 未找到实体
- 验证实体逻辑名称是否正确 - 检查目标环境中是否存在实体
- 列类型无效
- 查看文档中支持的列类型 - 验证特定列类型所需的参数
调试模式
设置环境变量 DEBUG=true 对于详细日志记录:
DEBUG=true node build/index.jsapi参考
有关每个工具的详细参数信息,请参阅源代码中的工具定义:
src/tools/table-tools.ts-表操作src/tools/column-tools.ts-立柱操作src/tools/autonumber-tools.ts-自动编号列操作src/tools/relationship-tools.ts-关系操作src/tools/optionset-tools.ts-选项集操作src/tools/solution-tools.ts-解决方案和发行商运营src/tools/role-tools.ts-安全角色操作src/tools/team-tools.ts-团队运营src/tools/businessunit-tools.ts-业务部门运营src/tools/schema-tools.ts-架构导出操作src/tools/webapi-tools.ts-WebAPI调用生成器操作src/tools/powerpages-webapi-tools.ts-PowerPages WebAPI调用生成器操作src/tools/powerpages-config-tools.ts-PowerPages配置管理操作
解决方案管理最佳实践
发布服务器配置
创建发布者时,请遵循以下准则:
- 唯一前缀:使用2-8个字符的前缀来标识您的组织
- 选项值范围:使用不重叠的范围(例如,一个出版商10000-1999,另一个出版商20000-2999)
- 描述性名称:为出版商和解决方案使用清晰、专业的名称
解决方案上下文管理
// Check current context
await use_mcp_tool("dataverse", "get_solution_context", {});
// Switch to different solution
await use_mcp_tool("dataverse", "set_solution_context", {
solutionUniqueName: "anothersolution"
});
// Clear context (removes persistence file)
await use_mcp_tool("dataverse", "clear_solution_context", {});环境促进
- 发展:使用解决方案上下文在开发环境中创建和测试模式更改
- 出口:使用Power Platform CLI或管理中心导出解决方案
- 导入:将解决方案部署到测试/生产环境
- 验证:验证所有自定义设置是否使用了正确的前缀
Git集成
这 .dataverse-mcp 文件将自动从版本控制中排除:
# MCP Dataverse context file
.dataverse-mcp这允许每个开发人员维护自己的解决方案上下文,同时防止意外共享特定于环境的设置。
开发者笔记本
MCP配置建议
本节提供了配置RubyMCP服务器以加速开发工作流程的实际建议。
只读工具 alwaysAllow 配置
为了加快开发周期,请考虑将这些只读工具添加到MCP服务器的 alwaysAllow 配置。由于这些工具只读取数据,不会对您的Webex环境进行任何更改,因此可以安全地自动批准,不会造成任何副作用。
推荐 alwaysAllow 配置:
{
"mcpServers": {
"dataverse": {
"command": "cmd",
"args": ["/c", "node", "C:\\path\\to\\dataverse-mcp\\build\\index.js"],
"env": {
"DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
"DATAVERSE_CLIENT_ID": "your-client-id",
"DATAVERSE_CLIENT_SECRET": "your-client-secret",
"DATAVERSE_TENANT_ID": "your-tenant-id"
},
"alwaysAllow": [
"get_dataverse_table",
"list_dataverse_tables",
"get_dataverse_column",
"list_dataverse_columns",
"get_dataverse_relationship",
"list_dataverse_relationships",
"get_dataverse_optionset",
"list_dataverse_optionsets",
"get_dataverse_optionset_options",
"get_dataverse_solution",
"get_dataverse_publisher",
"list_dataverse_solutions",
"list_dataverse_publishers",
"get_solution_context",
"get_dataverse_role",
"list_dataverse_roles",
"get_role_privileges",
"get_dataverse_team",
"list_dataverse_teams",
"get_team_members",
"get_dataverse_businessunit",
"list_dataverse_businessunits",
"get_businessunit_hierarchy",
"get_businessunit_users",
"get_businessunit_teams",
"export_solution_schema",
"generate_mermaid_diagram",
"generate_webapi_call",
"generate_powerpages_webapi_call"
],
"timeout": 900
}
}
}此配置的好处
🚀 加速发展:
- 架构探索没有审批提示
- 即时访问表和列信息
- 快速解决方案和发布者查找
- 立即生成模式文档
🔒 零风险:
- 所有列出的工具都是只读操作
- 无数据修改或架构更改
- 生产环境连接安全
- 无副作用或意外后果
📊 提高生产率:
- 更快的调试和故障排除
- 即时模式验证和探索
- 快速关系和依赖性分析
- 无缝的文档生成工作流程
通用开发工作流
模式探索:
// These will execute immediately without approval prompts
await use_mcp_tool("dataverse", "list_dataverse_tables", { customOnly: true });
await use_mcp_tool("dataverse", "get_dataverse_table", { logicalName: "xyz_project" });
await use_mcp_tool("dataverse", "list_dataverse_columns", { entityLogicalName: "xyz_project" });解决方案分析:
// Instant solution context and publisher information
await use_mcp_tool("dataverse", "get_solution_context", {});
await use_mcp_tool("dataverse", "list_dataverse_solutions", { includeManaged: false });
await use_mcp_tool("dataverse", "get_dataverse_publisher", { uniqueName: "xyzpublisher" });文档生成:
// Generate schema documentation without approval delays
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "current-schema.json"
});
await use_mcp_tool("dataverse", "generate_mermaid_diagram", {
schemaPath: "current-schema.json",
outputPath: "schema-diagram.mmd"
});WebAPI代码生成:
// Generate API calls instantly for development
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "retrieveMultiple",
entitySetName: "xyz_projects",
select: ["xyz_name", "xyz_status"]
});开发人员安全注意事项
虽然这些工具是只读和安全的,但请考虑以下安全实践:
- 环境隔离:为开发/测试/生产环境使用不同的MCP配置
- 凭据管理:将敏感凭据存储在安全环境变量中
- 访问监控:定期审查哪些工具
alwaysAllow列表 - 团队指导方针:建立MCP配置管理的团队标准
高级配置提示
选择性工具启用: 如果您喜欢更精细的控制,请从最常用的只读工具开始:
"alwaysAllow": [
"get_dataverse_table",
"list_dataverse_tables",
"get_dataverse_column",
"list_dataverse_columns",
"get_solution_context",
"export_solution_schema"
]这种配置方法显著改善了开发人员体验,同时通过分离只读和写入操作来维护安全性。
贡献
- 分叉存储库
- 创建要素分支
- 进行更改
- 如果适用,添加测试
- 提交拉取请求
更新日志
有关更改、新功能和错误修复的详细历史记录,请参阅 更改日志.md 文件。
最近的更新
- v0.2.6:模式感知的WebAPI生成器、@odata.bind规范化和查找自动更正
- v0.1.2:添加了13个新工具的全面安全角色管理系统
- v0.1.1:引入了具有持久上下文的基于解决方案的架构
- v0.1.0:具有核心表、列、关系和选项集操作的初始版本
更改日志如下 保存变更日志 格式,包括:
- 添加:新特性和功能
- 改变:对现有功能的修改
- 固定的:错误修复和更正
- 安全:安全相关更新
释放
该项目包括维护人员的自动发布脚本:
创建发布
# Patch release (0.1.0 -> 0.1.1)
npm run release
# Minor release (0.1.0 -> 0.2.0)
npm run release:minor
# Major release (0.1.0 -> 1.0.0)
npm run release:major这些脚本将:
- 构建项目
- 将版本插入
package.json - 创建一个git标签
- 将更改和标签推送到GitHub
自动GitHub发布
当标签被推送到GitHub时,GitHub Actions工作流将自动:
- 构建项目
- 创建发布档案(
.tar.gz和.zip) - 创建附带存档的GitHub版本
- 在发行说明中包括安装说明
手动发布流程
如果您更喜欢手动创建版本:
- 构建项目:
npm run build - 更新版本:
npm version [patch|minor|major] - 推送更改:
git push && git push --tags - GitHub Actions工作流将处理其余部分
许可证
MIT许可证-有关详细信息,请参阅许可证文件。
支持
对于问题和疑问:
- 检查故障排除部分
- 查看Dataverse Web API文档
- 在存储库中创建问题
