Dynamics 365财务与运营MCP服务器
这个项目是一个基于TypeScript的服务器,它实现了 模型上下文协议(MCP) 为Dynamics 365财务与运营(F&O)OData API提供安全高效的网关。它将各种D365 F&O数据实体和操作作为一组工具公开,可供大型语言模型(LLM)、Microsoft Copilot Studio或其他MCP兼容客户端使用。
服务器使用Azure AD处理身份验证,包括缓存承载令牌,以通过避免对每个API调用进行重新身份验证来优化性能。
特性
- 符合MCP标准: 使用官方
@modelcontextprotocol/sdk. - 已验证: 使用OAuth 2.0客户端凭据流安全地连接到D365 F&O OData API。
- 高效: 自动缓存身份验证令牌,并仅在其即将过期时刷新。它还缓存OData实体列表以进行快速查找。
- 用户友好: 这
odataQuery该工具使用模糊匹配算法(fuse.js)即使用户的输入大小写错误或拼写有点错误,也能找到正确的实体。 - 结构良好: 该项目按关注点组织,分离Express服务器、MCP工具定义、API通信层和身份验证逻辑。
- 测试: 包括一个带有Jest的测试套件,用于单元和集成测试,以确保可靠性和可维护性。
- 可扩展: 轻松添加新工具以显示更多D365 F&O实体或操作。
______________________________________________________________________
先决条件
- (建议使用v18或更高版本)
- 具有访问Dynamics 365 F&O环境权限的Azure Active Directory(Azure AD)应用程序注册。
- 您的D365 F&O环境URL。
______________________________________________________________________
设置和安装
按照以下步骤启动并运行服务器。
1.获取代码
将此存储库克隆到本地计算机。
git clone
cd 2.配置环境变量
此项目使用 .env 用于管理秘密凭据的文件。
- 创建一个
.env文件 通过复制示例模板:
cp .env.example .env- 编辑
.env文件 并用您的Azure AD和Dynamics 365详细信息填充它。
# .env - Your secret credentials
# Azure AD and App Registration Details
TENANT_ID=your-azure-ad-tenant-id
CLIENT_ID=your-application-client-id
CLIENT_SECRET=your-client-secret-value
# Dynamics 365 F&O Environment URL
DYNAMICS_RESOURCE_URL=[https://your-d365-environment.operations.dynamics.com](https://your-d365-environment.operations.dynamics.com)
# Optional Port for the server
# PORT=30003.安装依赖项
在项目的根目录中打开一个终端并运行:
npm install______________________________________________________________________
运行服务器
您可以在两种模式下运行服务器:
发展模式
对于开发,请使用 dev 脚本。这使用 tsx 要以热重新加载的方式运行服务器,请在更改源代码时自动重新启动。
npm run dev生产模式
对于生产环境,您应该首先将TypeScript代码构建到JavaScript中,然后运行编译后的输出。
- 构建项目:
npm run build这将编译 src 目录到a dist 目录。
- 启动服务器:
npm run start运行后,服务器将在以下时间可用 http://localhost:3000 (或您在 .env 文件)。MCP端点为 http://localhost:3000/mcp.
______________________________________________________________________
测试策略
此项目使用 开玩笑 测试位于它们正在测试的源文件旁边(例如。, auth.test.ts 测试 auth.ts).
测试策略包括:
- 单元测试: 测试单个模块,如
AuthManager,孤立。这些测试使用mocking来模拟外部依赖关系,例如fetch. - 集成测试: 测试MCP服务器的不同部分如何协同工作。这些测试使用SDK
InMemoryTransport模拟客户端-服务器连接,而无需进行真正的网络调用,从而可以快速可靠地验证工具定义和行为。
运行测试
要运行整个测试套件,请执行以下命令:
npm test______________________________________________________________________
项目架构
服务器代码在 src/ 促进关注点分离的目录:
index.ts:应用程序的主要入口点。它负责设置和启动Express web服务器,并处理传入的MCP请求。mcp-server.ts:定义MCP服务器本身,并注册包装Dynamics 365 API终结点的所有可用工具。api.ts:充当服务层或网关,用于与外部Dynamics 365 OData API进行所有通信。它包含makeApiCall辅助功能。auth.ts:包含AuthManager类,它负责整个身份验证生命周期,包括获取和缓存承载令牌。entityManager.ts:包含EntityManager类,它处理获取、缓存和模糊匹配OData实体名称,以提高可用性。
______________________________________________________________________
可用工具
此MCP服务器公开了以下工具。MCP客户端可以调用这些来与Dynamics 365交互。
| 工具名称 | 描述 | 参数 |
|---|---|---|
odataQuery | 对任何D365 OData实体执行通用GET请求。实体名称不需要大小写完美。如果满足以下条件,它还可以智能地实现跨公司搜索 dataAreaId 是过滤器的一部分。 | entity, select (可选), filter (可选), expand (可选), top (可选), crossCompany (可选) |
getEntityCount | 获取给定实体的记录总数。 | entity, crossCompany (可选) |
getODataMetadata | 检索服务的OData$元数据文档。 | _无_ |
createCustomer | 在中创建新的客户记录 CustomersV3 实体。 | customerData (JSON对象) |
updateCustomer | 更新现有客户记录。 | dataAreaId, customerAccount, updateData (JSON对象) |
createSystemUser | 创建新的系统用户记录。 | userData (JSON对象) |
assignUserRole | 为用户分配安全角色。 | associationData (JSON对象) |
updatePositionHierarchy | 更新层次结构中的位置。 | positionId, hierarchyTypeName, validFrom, validTo, updateData (JSON对象) |
action_initializeDataManagement | 执行特定的OData操作以初始化数据管理框架 | _无_ |
______________________________________________________________________
扩展服务器(添加新工具)
添加新工具很简单。
- 打开
src/mcp-server.ts. - 里面
getServer函数,添加新server.tool()定义。 - 遵循现有模式:
- 提供a toolName. - 提供a description 对于LLM。 - 定义 arguments 模式使用 zod. - 在回调函数中,使用 context 访问参数 sendNotification 以及其他特定于请求的数据。打电话给 makeApiCall 助手来自 api.ts 使用正确的方法、URL和正文。
示例:添加获取供应商组的工具
// Inside src/mcp-server.ts, within the getServer function
import { RequestHandlerExtra } from '@modelcontextprotocol/sdk/server/protocol.js';
import { ServerRequest, ServerNotification } from '@modelcontextprotocol/sdk/types.js';
// ...
server.tool(
'getVendorGroups',
'Retrieves a list of all vendor groups.',
{
crossCompany: z.boolean().optional().describe("Set to true to query across all companies."),
},
async ({ crossCompany }, context: RequestHandlerExtra) => {
const url = new URL(`${process.env.DYNAMICS_RESOURCE_URL}/data/VendorGroups`);
if (crossCompany) url.searchParams.append('cross-company', 'true');
return makeApiCall('GET', url.toString(), null, context.sendNotification);
}
);______________________________________________________________________
安全考虑
- 秘密管理:The
.env文件包含敏感凭据(CLIENT_ID,CLIENT_SECRET等等)。此文件应 从不 致力于源头控制。确保您的.gitignore文件包括.env. - Azure部署:部署到Azure时,请使用 配置>应用程序设置 面板来存储你的秘密。这些在运行时作为环境变量安全地注入,不会存储在代码存储库中。
- 网络安全:对于生产环境,考虑将Azure Web App放置在防火墙后面或虚拟网络中,并使用私有端点限制访问。
______________________________________________________________________
部署到Azure
您可以将此应用程序直接部署到Azure Web App服务。该存储库包括一个示例GitHub Actions工作流文件,位于 .github/workflows/main_fno-mcp.yml 这可以适应您的部署管道。
步骤1:创建Azure Web应用程序
首先,您需要在Azure门户中创建Web App资源。
- 转到 Azure门户 然后单击 创建资源.
- 搜索“Web App”并单击 创建.
- 填写 基础 选项卡,具有以下设置:
- 订阅: 选择您的Azure订阅。 - 资源组: 创建一个新的或选择一个现有的。 - 姓名: 给你的应用程序一个全球唯一的名称(例如。, fno-mcp-server-yourname).此名称将构成您的URL的一部分。 - 发布: 选择 代码. - 运行时堆栈: 选择 节点22 LTS. - 操作系统: 选择 Linux. - 地区: 选择一个离你近的地区。
- 配置 应用服务计划 根据您的需求(免费F1级别足以进行测试)。
- 点击 审核+创建那么 创建 提供资源。 记下默认URL (例如。,
https://fno-mcp-server-yourname.azurewebsites.net).
步骤2:配置GitHub部署
创建Web应用程序后,将其配置为从GitHub存储库自动部署。
- 导航到Azure门户中新创建的Web应用程序资源。
- 在左侧菜单的“部署”下,单击 部署中心.
- 对于 源,选择 GitHub.
- 如果你还没有授权Azure访问你的GitHub帐户。
- 配置生成设置:
- 组织机构: 选择您的GitHub用户名或组织。 - 存储库: 选择您的 fno-mcp-server 存储库。 - 分行: 选择 main.
- Azure将检测Node.js项目并建议工作流。查看设置并单击 保存。这将把工作流文件提交到您的存储库中
.github/workflows/目录。任何后续推送main分支将自动触发对Azure Web App的新部署。
步骤3:在Azure中配置环境变量
部署的应用程序需要访问与本地环境相同的机密。
- 在Web应用程序的菜单中,转到 配置 > 应用程序设置.
- 在“应用程序设置”下,单击 +新应用程序设置 从本地添加每个变量
.env文件:
- TENANT_ID - CLIENT_ID - CLIENT_SECRET - DYNAMICS_RESOURCE_URL - PORT (可选,Azure会自动提供此功能,但您可以将其设置为 8080)
- 点击 保存。应用程序将使用新设置重新启动。
步骤4:配置会话关联性(必需)
此MCP服务器是 有状态的.它保持在内存中 transports 对象跟踪每个活动的客户端会话。为了在应用程序跨多个实例扩展时正常工作,您必须启用会话关联。
- 在Web应用程序的菜单中,转到 配置 > 通用设置.
- 在“平台设置”选项卡下,找到 会话亲和性 设置。
- 设置为 在…上.
- 点击 保存.
完成这些步骤后,您的服务器将在Azure上运行,并在您将更改推送到您的服务器时自动更新 main 支。
______________________________________________________________________
与Microsoft Copilot Studio集成
部署MCP服务器后,您可以将其注册为 自定义连接器 让你的副驾驶可以使用它的工具。此过程在Copilot Studio中启动,并在Power Apps中完成。
该过程使用 OpenAPI规范 文件来描述服务器的API。
1.创建OpenAPI定义文件
首先,创建一个OpenAPI(Swagger)定义,描述服务器的单个 /mcp 终点。关键属性 x-ms-agentic-protocol: mcp-streamable-1.0 告诉平台这个端点说出模型上下文协议。
将以下YAML代码另存为名为 swagger.yaml 在您的本地机器上。
重要: 您必须更换 host 值与部署的Azure Web应用程序的URL。
swagger: '2.0'
info:
title: 'Dynamics 365 F&O MCP Server'
description: 'Connects to a server that implements the Model Context Protocol (MCP) to provide a secure and efficient gateway to the Dynamics 365 Finance & Operations (F&O) OData API.'
version: '1.0.0'
host: 'your-app-name.azurewebsites.net' # <-- IMPORTANT: REPLACE THIS
basePath: /
schemes:
- https
paths:
/mcp:
post:
summary: 'Invoke D365 F&O MCP Server'
description: 'The single endpoint for all MCP communications.'
x-ms-agentic-protocol: mcp-streamable-1.0
operationId: 'InvokeMcpServer'
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 'Successful MCP response.'
schema:
type: object
default:
description: 'Error response.'
schema:
type: object2.创建自定义连接器
- 在中导航到副驾驶 微软复制品工作室.
- 选择 主题和插件 在左侧导航中。
- 选择 +添加插件.
- 选择 添加自定义连接器。您将被带到Power Apps门户以创建连接器。
- 在Power Apps的“自定义连接器”页面上,选择 +新的自定义连接器.
- 从下拉列表中选择 导入OpenAPI文件.
- 为您的连接器命名(例如,“D365 F&O MCP连接器”)。
- 点击 导入 按钮并选择
swagger.yaml您在上一步中创建的文件。 - 点击 继续.
- 查看导入的设置(常规、安全、定义),然后单击 创建连接器.
保存连接器后,返回Copilot Studio。现在,它将作为您可以为副驾驶启用的工具提供,允许它使用MCP服务器上的工具。
