Dataverse MCP 服务器是一款专为 Microsoft Dataverse 打造的模型上下文协议(MCP)服务器。借助 Dataverse Web API,它能够实现模式操作,包括创建和更新表、列、关系以及选项集等功能。
/_api/[logicalEntityName] 格式生成 PowerPages 特定的 WebAPI 调用,并提供 React 示例。npm install
npm run build
index.js 文件的完整路径:
build/ 目录中。/Users/yourname/path/to/mcp-dataverse/build/index.js)。// 创建一个带有自动命名的新自定义表
// 系统自动生成:
// - 逻辑名称:xyz_project(使用解决方案上下文中的定制前缀)
// - 架构名称:xyz_Project(前缀小写,保留原始大小写,去除空格)
// - 显示集合名称:Projects(自动复数化)
// - 主名称属性: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
});
// 带有最少参数的示例(最常见的用法)
await use_mcp_tool("dataverse", "create_dataverse_table", {
displayName: "Customer Feedback"
});
// 这将创建:
// - 逻辑名称:xyz_customerfeedback
// - 架构名称:xyz_CustomerFeedback(前缀小写,保留原始大小写)
// - 显示集合名称:Customer Feedbacks
// - 主名称属性:xyz_customerfeedback_name
重要提示:在创建表之前,请确保使用 set_solution_context 设置了解决方案上下文,以便提供定制前缀。系统将自动使用活动解决方案发布者的前缀。
// 具有电子邮件格式和自动命名的字符串列
// 系统自动生成:
// - 逻辑名称:xyz_contactemail(前缀 + 小写,无空格)
// - 架构名称:xyz_ContactEmail(前缀小写,保留原始大小写)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Contact Email",
columnType: "String",
format: "Email",
maxLength: 100,
requiredLevel: "ApplicationRequired"
});
// 具有约束的整数列(生成 xyz_priorityscore)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Priority Score",
columnType: "Integer",
minValue: 1,
maxValue: 10,
defaultValue: 5
});
// 具有自定义标签的布尔列(生成 xyz_isactive)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Is Active",
columnType: "Boolean",
trueOptionLabel: "Active",
falseOptionLabel: "Inactive",
defaultValue: true
});
// 日期时间列(仅日期)(生成 xyz_startdate)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Start Date",
columnType: "DateTime",
dateTimeFormat: "DateOnly",
requiredLevel: "ApplicationRequired"
});
// 日期时间列(日期和时间)(生成 xyz_lastmodified)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Last Modified",
columnType: "DateTime",
dateTimeFormat: "DateAndTime"
});
// 具有本地选项的选择列表列(生成 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" }
]
});
// 使用全局选项集的选择列表列(生成 xyz_projectcolor)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Project Color",
columnType: "Picklist",
optionSetName: "xyz_colors"
});
// 查找列(生成 xyz_account)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Account",
columnType: "Lookup",
targetEntity: "account"
});
// 用于长文本的备注列(生成 xyz_description)
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
displayName: "Description",
columnType: "Memo",
maxLength: 2000,
requiredLevel: "Recommended"
});
// 创建一对多关系
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"
});
// 创建全局选项集
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" }
]
});
// 创建新的安全角色
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"
});
// 获取安全角色信息
await use_mcp_tool("dataverse", "get_dataverse_role", {
roleId: "role-guid-here"
});
// 列出安全角色
await use_mcp_tool("dataverse", "list_dataverse_roles", {
customOnly: true,
includeManaged: false,
top: 20
});
// 向角色添加权限
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" }
]
});
// 将角色分配给用户
await use_mcp_tool("dataverse", "assign_role_to_user", {
roleId: "role-guid-here",
userId: "user-guid-here"
});
// 将角色分配给团队
await use_mcp_tool("dataverse", "assign_role_to_team", {
roleId: "role-guid-here",
teamId: "team-guid-here"
});
// 获取角色权限
await use_mcp_tool("dataverse", "get_role_privileges", {
roleId: "role-guid-here"
});
// 创建新团队
await use_mcp_tool("dataverse", "create_dataverse_team", {
name: "Development Team",
description: "Team for software development activities",
administratorId: "admin-user-guid-here",
teamType: "0", // 所有者团队
membershipType: "0", // 成员和来宾
emailAddress: "devteam@company.com"
});
// 获取团队信息
await use_mcp_tool("dataverse", "get_dataverse_team", {
teamId: "team-guid-here"
});
// 列出团队并进行过滤
await use_mcp_tool("dataverse", "list_dataverse_teams", {
teamType: "0", // 仅所有者团队
excludeDefault: true,
top: 20
});
// 向团队添加成员
await use_mcp_tool("dataverse", "add_members_to_team", {
teamId: "team-guid-here",
memberIds: ["user-guid-1", "user-guid-2", "user-guid-3"]
});
// 获取团队成员
await use_mcp_tool("dataverse", "get_team_members", {
teamId: "team-guid-here"
});
// 从团队中移除成员
await use_mcp_tool("dataverse", "remove_members_from_team", {
teamId: "team-guid-here",
memberIds: ["user-guid-1", "user-guid-2"]
});
// 更新团队属性
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"
});
// 将所有者团队转换为访问团队
await use_mcp_tool("dataverse", "convert_owner_team_to_access_team", {
teamId: "owner-team-guid-here"
});
// 创建具有综合信息的新业务部门
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",
// 地址信息
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",
// 网站和其他详细信息
webSiteUrl: "https://sales.company.com",
stockExchange: "NYSE",
tickerSymbol: "COMP"
});
// 获取业务部门信息
await use_mcp_tool("dataverse", "get_dataverse_businessunit", {
businessUnitId: "business-unit-guid-here"
});
// 列出业务部门并进行过滤
await use_mcp_tool("dataverse", "list_dataverse_businessunits", {
filter: "isdisabled eq false",
orderby: "name asc",
top: 20
});
// 更新业务部门属性
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,
// 更新地址信息
address1_line1: "456 New Business Avenue",
address1_telephone1: "+1-555-9999"
});
// 获取业务部门层次结构
await use_mcp_tool("dataverse", "get_businessunit_hierarchy", {
businessUnitId: "business-unit-guid-here"
});
// 更改业务部门父级(重组)
await use_mcp_tool("dataverse", "set_businessunit_parent", {
businessUnitId: "child-bu-guid-here",
parentBusinessUnitId: "new-parent-bu-guid-here"
});
// 获取业务部门中的用户
await use_mcp_tool("dataverse", "get_businessunit_users", {
businessUnitId: "business-unit-guid-here",
includeSubsidiaryUsers: false // 设置为 true 以包括子业务部门的用户
});
// 获取业务部门中的团队
await use_mcp_tool("dataverse", "get_businessunit_teams", {
businessUnitId: "business-unit-guid-here",
includeSubsidiaryTeams: true // 包括子业务部门的团队
});
// 删除业务部门(确保不存在依赖项)
await use_mcp_tool("dataverse", "delete_dataverse_businessunit", {
businessUnitId: "business-unit-guid-here"
});
// 仅导出自定义模式(默认设置)
// 将表、列和选项集导出到 JSON 文件
// 注意:关系导出尚未实现
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "my-solution-schema.json"
});
// 包含系统实体进行全面文档导出
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "complete-schema.json",
includeSystemTables: true,
includeSystemColumns: true,
includeSystemOptionSets: true
});
// 导出用于生产的压缩 JSON
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "schema-minified.json",
prettify: false
});
// 导出到特定目录并使用自定义设置
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "exports/solution-backup.json",
includeSystemTables: false,
includeSystemColumns: false,
includeSystemOptionSets: false,
prettify: true
});
// 仅导出与解决方案定制前缀匹配的表
await use_mcp_tool("dataverse", "export_solution_schema", {
outputPath: "prefix-only-schema.json",
includeSystemTables: false,
includeSystemColumns: false,
includeSystemOptionSets: false,
prefixOnly: true,
prettify: true
});
模式导出功能:
示例输出结构:
{
"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" }
]
}
]
}
注意:关系导出功能计划在未来版本中发布。
WebAPI 调用生成器工具可帮助开发人员通过生成具有正确 URL、标头和请求正文的完整 HTTP 请求来构建正确的 Dataverse WebAPI 调用。这对于以下方面特别有用:
// 生成简单的检索操作
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "retrieve",
entitySetName: "accounts",
entityId: "12345678-1234-1234-1234-123456789012",
select: ["name", "emailaddress1", "telephone1"]
});
// 生成带有过滤和排序的多记录检索操作
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
});
// 生成带有返回首选项的创建操作
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
});
// 生成带有条件标头的更新操作
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: "*"
});
// 生成关系关联操作
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"
});
// 生成绑定操作调用
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"
}
});
// 生成未绑定函数调用
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "callFunction",
actionOrFunctionName: "WhoAmI",
includeAuthHeader: true
});
// 生成带有参数的函数调用
await use_mcp_tool("dataverse", "generate_webapi_call", {
operation: "callFunction",
actionOrFunctionName: "GetTimeZoneCodeByLocalizedName",
parameters: {
LocalizedStandardName: "Pacific Standard Time",
LocaleId: 1033
}
});
输出特性:
示例输出:
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
--- 附加信息 ---
操作类型: retrieve
实体集: accounts
实体 ID: 12345678-1234-1234-1234-123456789012
Curl 命令:
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 示例:
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));
支持的操作:
高级特性:
PowerPages WebAPI 生成器使用 PowerPages WebAPI 格式 /_api/[logicalEntityName]s 为 PowerPages 单页应用程序(SPA)创建 API 调用。此工具专为在 PowerPages 环境中构建现代 React、Angular 或 Vue 应用程序的开发人员而设计。
与标准 Dataverse WebAPI 的主要区别:
/_api/[logicalEntityName]s 而不是 /api/data/v9.2/[entitySetName](注意:自动添加 's' 后缀)。// 生成 PowerPages 多记录检索操作
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
});
// 生成带有请求验证令牌的 PowerPages 创建操作
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"
},
baseUrl: "https://contoso.powerappsportals.com",
requestVerificationToken: true
});
// 生成 PowerPages 单记录检索操作
await use_mcp_tool("dataverse", "generate_powerpages_webapi_call", {
operation: "retrieve",
logicalEntityName: "contacts",
entityId: "12345678-1234-1234-1234-123456789012",
select: ["fullname", "emailaddress1", "telephone1"],
baseUrl: "https://yoursite.powerappsportals.com"
});
// 生成带有自定义标头的高级场景调用
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"
}
});
输出特性:
/_api/[logicalEntityName]s 端点(自动添加 's' 后缀)。示例输出:
// PowerPages WebAPI 调用
const fetchData = async () => {
// 获取请求验证令牌
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"
})
});
if (!response.ok) {
throw new Error(`HTTP 错误!状态码:${response.status}`);
}
const createdRecord = await response.json();
console.log('创建的记录:', createdRecord);
return createdRecord;
} catch (error) {
console.error('错误:', error);
throw error;
}
};
React 组件示例:
// React 钩子示例
import React, { useState, useEffect } from 'react';
const CreditCardsList = () => {
const [records, setRecords] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchRecords = async () => {
try {
const response = await fetch('/_api/cr7ae_creditcardses?$select=cr7ae_name,cr7ae_type');
const data = await response.json();
setRecords(data.value);
} catch (error) {
console.error('获取记录时出错:', error);
} finally {
setLoading(false);
}
};
fetchRecords();
}, []);
if (loading) return <div>加载中...div>;
return (
<div>
<h2>信用卡列表h2>
{records.map((record, index) => (
<div key={record.cr7ae_creditcardsesid || index}>
<h3>{record.cr7ae_name}h3>
<p>类型:{record.cr7ae_type}p>
div>
))}
div>
);
};
身份验证上下文集成:
// 访问 PowerPages 中的用户信息
const user = window["Microsoft"]?.Dynamic365?.Portal?.User;
const userName = user?.userName || "";
const firstName = user?.firstName || "";
const lastName = user?.lastName || "";
const isAuthenticated = userName !== "";
// 获取身份验证令牌(如果需要)
const getToken = async () => {
try {
const token = await window.shell.getTokenDeferred();
return token;
} catch (error) {
console.error('获取令牌时出错:', error);
return null;
}
};
PowerPages 特定特性:
__RequestVerificationToken 标头,以确保安全操作。此工具对于需要在维护 PowerPages 安全和身份验证模式的同时与 Dataverse 数据进行交互的 PowerPages 开发人员构建现代 SPA 至关重要。
本 MCP 服务器为 Dataverse 模式管理提供了全面的工具:
/_api/[logicalEntityName] 格式生成 PowerPages 特定的 WebAPI 调用。包括请求验证令牌处理、身份验证上下文、React 组件示例以及 PowerPages 特定的单页应用程序开发功能。.powerpages-site 目录结构中的 YAML 文件,包括 sitesetting.yml、webrole.yml 和 table-permissions/*.yml 文件,并提供全面的状态检查和配置管理。MCP 服务器遵循 Microsoft Dataverse 最佳实践,实现了企业级解决方案管理。
.mcp-dataverse 文件在服务器重启后仍然保留。// 1. 创建带有 "xyz" 前缀的发布者
await use_mcp_tool("dataverse", "create_dataverse_publisher", {
friendlyName: "XYZ Test Publisher",
uniqueName: "xyzpublisher",
customizationPrefix: "xyz",
customizationOptionValuePrefix: 20000,
description: "Publisher for XYZ organization"
});
// 2. 创建与发布者关联的解决方案
await use_mcp_tool("dataverse", "create_dataverse_solution", {
friendlyName: "XYZ Test Solution",
uniqueName: "xyzsolution",
publisherUniqueName: "xyzpublisher",
description: "Main solution for XYZ customizations"
});
// 3. 设置解决方案上下文(在服务器重启后仍然保留)
await use_mcp_tool("dataverse", "set_solution_context", {
solutionUniqueName: "xyzsolution"
});
// 4. 创建模式对象 - 它们自动使用 "xyz" 前缀
await use_mcp_tool("dataverse", "create_dataverse_table", {
logicalName: "xyz_project", // 自动使用 xyz 前缀
displayName: "XYZ Project",
displayCollectionName: "XYZ Projects"
});
await use_mcp_tool("dataverse", "create_dataverse_column", {
entityLogicalName: "xyz_project",
logicalName: "xyz_description", // 自动使用 xyz 前缀
displayName: "Description",
columnType: "Memo"
});
服务器自动将解决方案上下文持久化到项目根目录中的 .mcp-dataverse 文件:
{
"solutionUniqueName": "xyzsolution",
"solutionDisplayName": "XYZ Test Solution",
"publisherUniqueName": "xyzpublisher",
"publisherDisplayName": "XYZ Test Publisher",
"customizationPrefix": "xyz",
"lastUpdated": "2025-07-26T08:27:56.966Z"
}
持久化的好处:
MCP 服务器支持所有主要的 Dataverse 列类型,并提供全面的配置选项。下表显示了实现状态和测试验证:
| 列类型 | 状态 | 测试情况 | 描述 | 关键参数 |
|---|---|---|---|---|
| 字符串 | ✅ 已实现 | ✅ 已验证 | 具有格式选项的文本字段 | maxLength, format (电子邮件、文本、文本区域、URL、电话) |
| 整数 | ✅ 已实现 | ✅ 已验证 | 具有约束的整数 | minValue, maxValue, defaultValue |
| 小数 | ✅ 已实现 | ⚠️ 未测试 | 具有精度的小数 | precision, minValue, maxValue, defaultValue |
| 货币 | ✅ 已实现 | ⚠️ 未测试 | 货币值 | precision, minValue, maxValue |
| 布尔值 | ✅ 已实现 | ✅ 已验证 | 具有自定义标签的真/假值 | trueOptionLabel, falseOptionLabel, defaultValue |
| 日期时间 | ✅ 已实现 | ✅ 已验证 | 日期和时间字段 | dateTimeFormat (仅日期、日期和时间) |
| 选择列表 | ✅ 已实现 | ✅ 已验证 | 选择字段(本地和全局) | options (本地),optionSetName (全局) |
| 查找 | ✅ 已实现 | ✅ 已验证 | 对其他表的引用 | targetEntity |
| 备注 | ✅ 已实现 | ⚠️ 未测试 | 长文本字段 | maxLength |
| 双精度浮点数 | ✅ 已实现 | ⚠️ 未测试 | 浮点数 | precision, minValue, maxValue |
| 大整数 | ✅ 已实现 | ⚠️ 未测试 | 大整数值 | 无 |
以下特定场景已成功测试和验证:
| 操作 | 状态 | 描述 |
|---|---|---|
| 创建 | ✅ 完全测试 | 所有列类型及特定类型的参数 |
| 读取 | ✅ 已实现 | 检索列元数据和配置 |
| 更新 | ✅ 已实现 | 修改显示名称、描述、必需级别 |
| 删除 | ✅ 已测试 | 从表中移除自定义列 |
| 列表 | ✅ 已实现 | 列出表的所有列并支持过滤 |
关键步骤:您必须在 Dataverse 环境中创建应用程序用户并分配适当的权限。
您将需要:
https://yourorg.crm.dynamics.com)。服务器支持灵活的环境变量配置,优先级如下(从高到低):
.env 文件变量(最低优先级).env 文件(推荐用于 MCP 服务器开发)服务器会自动从项目根目录的 .env 文件中加载环境变量。这是在为 MCP 服务器做出贡献或进行修改时推荐的方法。
.env 文件:cp .env.example .env
{
"mcpServers": {
"dataverse": {
"command": "node",
"args": ["/path/to/mcp-dataverse/build/index.js"],
"disabled": false,
"alwaysAllow": [],
"disabledTools": [],
"timeout": 900
}
}
}
注意:timeout 设置增加到 900 秒(15 分钟),以适应较长时间运行的操作,如模式导出,可能需要处理大量元数据。
您可以直接在 MCP 设置中配置环境变量。这是在使用 MCP Dataverse 工具进行开发活动时推荐的正常使用方法。这些变量将覆盖 .env 文件中的任何值:
{
"mcpServers": {
"dataverse": {
"command": "node",
"args": ["/path/to/mcp-dataverse/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
}
}
}
您还可以使用组合方法,将常见设置放在 .env 文件中,而敏感或特定于环境的设置通过 MCP 进行覆盖:
.env 文件:
DATAVERSE_URL=https://dev-org.crm.dynamics.com
DATAVERSE_TENANT_ID=common-tenant-id
MCP 设置(生产覆盖):
{
"mcpServers": {
"dataverse": {
"command": "node",
"args": ["/path/to/mcp-dataverse/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
}
}
}
manage_powerpages_webapi_config 工具可帮助管理 PowerPages 代码站点的表权限和 WebAPI 站点设置。它自动配置 .powerpages-site 目录结构中的 YAML 文件,使您更轻松地为 PowerPages 应用程序设置和维护 WebAPI 访问权限。
.powerpages-site 目录结构无缝协作。{
"operation": "status"
}
示例输出:
PowerPages WebAPI 配置状态:
WebAPI 配置:
✅ WebAPI 已启用 (Webapi/cr7ae_creditcardses/Enabled = true)
✅ WebAPI 字段已配置 (Webapi/cr7ae_creditcardses/Fields = cr7ae_name,cr7ae_type,cr7ae_limit)
Web 角色:
✅ 已存在经过身份验证的用户角色
✅ 已存在匿名用户角色
表权限:
✅ 已为经过身份验证的用户配置 cr7ae_creditcardses 权限
- 读取: ✅, 创建: ✅, 写入: ✅, 删除: ❌
- 范围: 全局
{
"operation": "configure-webapi",
"tableName": "cr7ae_creditcardses",
"fields": ["cr7ae_name", "cr7ae_type", "cr7ae_limit", "cr7ae_isactive"],
"enabled": true
}
结果:
.powerpages-site/sitesetting.yml。{
"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。{
"operation": "list-configurations"
}
示例输出:
当前 PowerPages 配置:
站点设置 (共 3 项):
- Webapi/cr7ae_creditcardses/Enabled = true
- Webapi/cr7ae_creditcardses/Fields = cr7ae_name,cr7ae_type,cr7ae_limit
- Authentication/Registration/Enabled = true
Web 角色 (共 2 项):
- 经过身份验证的用户 (ID: 12345678-1234-1234-1234-123456789012)
- 匿名用户 (ID: 87654321-4321-4321-4321-210987654321)
表权限 (共 1 项):
- cr7ae_creditcardses_authenticated_users.yml
表: cr7ae_creditcardses, 角色: 经过身份验证的用户
权限: 读取 ✅, 创建 ✅, 写入 ✅, 删除 ❌
范围: 全局
提供当前 PowerPages WebAPI 配置的全面概述,包括:
为特定表启用或配置 WebAPI 访问:
为 Web 角色创建细粒度的表权限:
列出所有当前配置,包括:
此工具旨在与遵循标准目录结构的 PowerPages 代码站点配合使用:
your-powerpages-project/
├── .powerpages-site/
│ ├── sitesetting.yml # WebAPI 和其他站点设置
│ ├── webrole.yml # Web 角色定义
│ └── table-permissions/ # 单个权限文件
│ ├── cr7ae_creditcardses_authenticated_users.yml
│ └── contact_anonymous_users.yml
├── src/ # 您的 React 组件
└── package.json
{"operation": "status"}
{
"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"}
{
"operation": "retrieveMultiple",
"logicalEntityName": "cr7ae_creditcardses",
"select": ["cr7ae_name", "cr7ae_type", "cr7ae_limit"]
}
此工作流程可确保您的 PowerPages 代码站点正确配置为处理自定义表的 WebAPI 调用,并具有适当的安全权限。
服务器使用 客户端凭据流(服务器到服务器身份验证)与 Azure AD 进行身份验证。这提供了:
服务器包括全面的错误处理:
设置环境变量 DEBUG=true 以进行详细日志记录:
DEBUG=true node build/index.js
有关每个工具的详细参数信息,请参考源代码中的工具定义:
创建发布者时,请遵循以下准则:
// 检查当前上下文
await use_mcp_tool("dataverse", "get_solution_context", {});
// 切换到不同的解决方案
await use_mcp_tool("dataverse", "set_solution_context", {
solutionUniqueName: "anothersolution"
});
// 清除上下文(移除持久化文件)
await use_mcp_tool("dataverse", "clear_solution_context", {});
.mcp-dataverse 文件会自动从版本控制中排除:
# MCP Dataverse 上下文文件
.mcp-dataverse
这允许每个开发人员维护自己的解决方案上下文,同时防止意外共享特定于环境的设置。
服务器采用 Azure AD 的客户端凭据流(服务器到服务器身份验证),具备安全认证、应用级权限、适配自动化场景以及处理令牌刷新等特性,确保无需用户交互即可实现安全认证。
服务器设置了全面的错误处理机制,涵盖身份验证错误(如无效凭证或过期令牌)、API 错误(Dataverse 特定错误消息及代码)、验证错误(参数验证和类型检查)以及网络错误(连接和超时处理)。
为保障系统安全,需安全存储密钥,避免提交至版本控制;通过环境变量配置密钥;遵循最小权限原则,仅授予必要权限;监控 API 调用和认证尝试;定期更新客户端密钥。
服务器借助 .mcp-dataverse 文件持久化解决方案上下文,确保服务器重启后上下文依然保留,为开发人员提供持续的工作环境,避免上下文丢失。
本项目采用 MIT 许可证,详情请参阅 LICENSE 文件。
若您遇到问题或有疑问,请按以下步骤操作: