Dynamics 365 Finance & Operations MCP 服务器
这个项目是一个基于TypeScript的服务器,实现了 模型上下文协议(MCP) 提供一个安全高效的网关,用于访问Dynamics 365 Finance & Operations(F&O)的OData API。它将各种D365 F&O数据实体和操作作为一组工具暴露出来,供大型语言模型(LLMs)、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 Finance and Operations(F&O)环境权限的Azure Active Directory(Azure AD)应用程序注册。
- 您的D365 Finance and Operations环境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 将目录转换为(或:将目录变成) dist 目录。
- 启动服务器:
npm run start一旦运行,服务器将可通过 http://localhost:3000 (或您在(配置中)指定的端口 .env 文件)。MCP终端是 http://localhost:3000/mcp。
______________________________________________________________________
测试策略
这个项目使用了 Jest(在波兰语中意为“存在”或“是”) 作为其测试框架。测试文件与它们所测试的源文件位于同一位置(例如。, auth.test.ts 测试 auth.ts)。
测试策略包括:
- 单元测试: 为了测试各个模块,比如
AuthManager(这些测试)在隔离环境下进行。这些测试使用模拟技术来模拟外部依赖,如fetch. - 集成测试: 为了测试MCP服务器的不同部分如何协同工作。这些测试使用了SDK的(功能/工具)
InMemoryTransport在不进行实际网络调用的情况下,模拟客户端-服务器连接,以便快速可靠地验证工具定义和行为。
运行测试
要运行整个测试套件,请执行以下命令:
npm test______________________________________________________________________
项目架构
服务器代码被组织成几个文件,位于 src/ 目录以促进关注点分离:
index.ts应用程序的主要入口点。它负责设置并启动Express网络服务器,并处理传入的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 $metadata文档。 | _无_ |
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()定义。 - 遵循现有模式:
- 提供一个 toolName. - 提供一个 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);
}
);______________________________________________________________________
安全考虑因素
- 密钥管理(或“机密管理”):该
.env文件包含敏感凭据(CLIENT_ID,CLIENT_SECRET等)。此文件应 从不 致力于源头控制。确保您的.gitignore文件包含.env。 - Azure 部署在部署到 Azure 时,请使用 配置 > 应用程序设置 面板用于存储您的机密信息。这些信息在运行时作为环境变量安全注入,不会存储在您的代码仓库中。
- 网络安全对于生产环境,建议将Azure Web App置于防火墙后或虚拟网络(VNet)中,并使用私有端点来限制访问。
______________________________________________________________________
部署到 Azure
您可以直接将此应用程序部署到Azure Web App服务。该存储库包含一个GitHub Actions工作流文件示例,位于 .github/workflows/main_fno-mcp.yml 这可以适应您的部署流程。
步骤1:创建Azure Web应用
首先,您需要在Azure门户中创建Web应用资源。
- 前往 Azure 门户 并点击 创建一个资源。
- 搜索“Web App”并点击 创造。
- 填写 基础 具有以下设置的选项卡:
- 订阅: 选择您的 Azure 订阅。 - 资源组: 创建一个新的或选择一个现有的。 - 姓名: 为您的应用起一个全球唯一的名字(例如。, fno-mcp-server-yourname)。 这个名字将成为您URL的一部分。 - 发布: 选择 代码。 - 运行时栈: 选择 Node 22 LTS(长期支持版)。 - 操作系统: 选择 Linux。 - 地区: 选择一个离你较近的地区。
- 配置 应用服务计划 根据您的需求(免费F1层级足以满足测试需求)。
- 点击 回顾 + 创建,然后 创建 为资源提供配置/供应资源。 记下默认的URL (例如。,
https://fno-mcp-server-yourname.azurewebsites.net)。
步骤2:配置GitHub部署
创建网页应用后,将其配置为自动从您的GitHub仓库进行部署。
- 在 Azure 门户中导航到您新创建的 Web 应用资源。
- 在左侧菜单中,点击“部署”下的 部署中心。
- 对于 来源,选择 GitHub。
- 如果您尚未授权,请允许 Azure 访问您的 GitHub 账户。
- 配置构建设置:
- 组织: 选择您的GitHub用户名或组织。 - 仓库: 选择您的 fno-mcp-server 仓库。 - 分店/分支机构: 选择 main。
- Azure 将检测到 Node.js 项目并建议一个工作流程。请查看设置并点击 保存这将在你的仓库中提交一个工作流文件
.github/workflows/目录。之后对您的(仓库)的任何推送main分支将自动触发对您的 Azure Web App 的新部署。
步骤3:在Azure中配置环境变量
您部署的应用程序需要访问与本地环境相同的密钥。
- 在您的网页应用菜单中,前往 配置 > 应用程序设置。
- 在“应用程序设置”下,点击 + 新的应用程序设置 将你本地的每个变量添加进来
.env文件:
- TENANT_ID - CLIENT_ID - CLIENT_SECRET - DYNAMICS_RESOURCE_URL - PORT (可选,Azure 会自动提供此设置,但您也可以将其设置为 8080)
- 点击 保存应用程序将以新设置重新启动。
步骤4:配置会话亲和性(必需)
这台MCP服务器是 有状态的它在内存中维护着(数据/状态) transports 用于跟踪每个活跃的客户端会话的对象。为了确保在应用程序跨多个实例扩展时能够正常工作,您必须启用会话粘性。
- 在您的网页应用菜单中,前往 配置 > 通用设置。
- 在“平台设置”选项卡下,找到 会话亲和性 设定。
- 将其设置为 开启。
- 点击 保存。
完成这些步骤后,您的服务器将在Azure上运行,并且每当您推送更改时,它将自动更新 main 分支。
______________________________________________________________________
与 Microsoft Copilot Studio 集成
一旦您的MCP服务器部署完成,您就可以将其注册为 自定义连接器 使其工具可供您的协作者使用。此过程在Copilot Studio中启动,并在Power Apps中完成。
该过程使用了一个 开放API规范 文件用于描述您服务器的API。
1. 创建OpenAPI定义文件
首先,创建一个OpenAPI(Swagger)定义,用于描述您服务器的单个(API)端点 /mcp 端点。关键属性 x-ms-agentic-protocol: mcp-streamable-1.0 告知平台此端点支持模型上下文协议。
将以下YAML代码保存为一个名为 swagger.yaml 在你的本地机器上。
重要提示: 你必须更换 host 将(此处的)值替换为您已部署的 Azure Web App 的 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. 创建自定义连接器
- 导航至你的副驾驶(或:向你的副驾驶靠拢) Microsoft Copilot Studio(可译为“微软Copilot工作室”或根据具体语境简化为“微软Copilot平台”,但“Copilot Studio”本身已足够表达其作为开发或设计平台的含义,因此直接翻译为“微软Copilot Studio”即可,保持原名以体现品牌特色).
- 选择 主题与插件 在左侧导航栏中。
- 选择 + 添加一个插件。
- 选择 添加自定义连接器您将被引导至 Power Apps 门户以创建连接器。
- 在 Power Apps 的自定义连接器页面上,选择 + 新定制连接器。
- 从下拉菜单中选择 导入OpenAPI文件。
- 为您的连接器提供一个名称(例如,“D365 F&O MCP 连接器”)。
- 点击 进口 点击按钮并选择
swagger.yaml你在上一步中创建的文件。 - 点击 继续。
- 检查导入的设置(常规、安全、定义),然后点击 创建连接器。
连接器保存后,返回Copilot Studio。现在,该连接器将作为工具可用,您可以为您的Copilot启用此工具,使其能够使用来自MCP服务器的工具。
