Token导航 LogoToken导航TokenDH.com
D365fo MCP Server logo
数据服务stdio官方级别未说明来源级核验

D365fo MCP Server

MCP Server

@zhound/d365fo-mcp-server

一个连接Microsoft Dynamics 365 Finance & Operations环境的MCP服务器,支持元数据查询、数据操作和分析功能。

工具数

22

提示词数

0

GitHub Stars

5

资源数

0
TypeScriptClaude数据分析Claude DesktopClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

zhound420

提供方

zhound420

最后核验

2026/5/17 20:20

运行时

Node.js

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

npx @zhound/d365fo-mcp-server

详细介绍

D365财务与运营MCP服务器

MCP(模型上下文协议)服务器,提供对Microsoft Dynamics 365财务和运营环境的访问。使Claude等AI助手能够探索D365元数据、查询数据,并在非生产环境中执行写入操作。

特性

  • 多环境支持 -连接到多个D365环境(生产、UAT、开发)
  • 读/写操作 -查询所有环境的数据;仅在非生产环境下创建、更新、删除
  • 安全生产 -生产环境的设计始终是只读的
  • MCP资源 用于模式发现和元数据探索
  • 22专用工具 用于灵活的数据访问、聚合、批处理操作和分析
  • 环境仪表板 -健康监测、API统计和操作跟踪
  • 安全认证 通过Azure AD客户端凭据
  • 自动元数据缓存 (24小时TTL,每种环境)

建筑

资源

资源URI目的
实体列表`d365://entities?filter=
`列出所有具有可选通配符筛选的实体
实体架构d365://entity/{entityName}任何实体的完整架构(字段、键、导航属性)
导航属性d365://navigation/{entityName}实体关系和导航属性
枚举定义d365://enums所有枚举类型及其值
已保存的查询d365://queries列出已保存的查询模板
仪表板d365://dashboard所有环境的JSON指标(运行状况、API统计数据、最近的操作)

工具

所有工具都支持可选 environment 该参数针对特定的D365环境。

工具目的
list_environments列出所有已配置的D365环境及其连接状态
set_environment设置当前会话的工作环境
describe_entity实体的快速架构查找
execute_odata执行原始OData路径(查询、单个记录、计数)
aggregate对实体数据执行聚合(SUM、AVG、COUNT、MIN、MAX、COUNTDISTINCT、百分位数)
get_related遵循实体关系以检索相关记录
export将查询结果导出为CSV、JSON或TSV格式
compare_periods同比、季度、月环比比较及变化计算
trending基于增长率和移动平均线的时间序列分析
save_query保存具有参数支持的可重用查询模板
execute_saved_query使用参数替换执行已保存的查询模板
delete_saved_query删除已保存的查询模板
join_entities使用$expand或客户端连接进行跨实体连接
batch_query并行执行多个查询
search_entity具有自动回退策略的强大实体搜索
analyze_customer全面的单次通话客户分析
create_record创建新记录(仅限非生产环境)
update_record更新现有记录(仅限非生产环境)
delete_record删除记录(仅限非生产环境)
batch_crud在单个批处理请求中执行多个创建/更新/删除操作(仅限非生产)
compare_schemas比较两个环境之间的实体模式以检测模式漂移
dashboard显示包含运行状况状态、API统计信息和最近操作的环境仪表板

安装

来自npm(推荐)

npx @zhound/d365fo-mcp-server

或全局安装:

npm install -g @zhound/d365fo-mcp-server
d365fo-mcp

源自源头

git clone https://github.com/zhound420/D365FO-claude-connector.git
cd D365FO-claude-connector
npm install
npm run build

快速入门(推荐)

运行交互式安装向导:

npm run setup

向导将:

  1. 检查先决条件(Node.js 18+,依赖关系)
  2. 指导您完成D365环境配置
  3. 测试与D365环境的连接
  4. 生成配置文件
  5. 配置克劳德桌面和/或克劳德代码

安装后,重新启动Claude Desktop(Cmd+Q然后在macOS上重新打开,或在Windows上Ctrl+Q)或启动新的Claude Code会话。

配置

多环境配置(推荐)

创建一个 d365-environments.json 项目根目录或工作目录中的文件:

{
  "environments": [
    {
      "name": "production",
      "displayName": "Production",
      "type": "production",
      "tenantId": "your-tenant-id",
      "clientId": "your-client-id",
      "clientSecret": "your-client-secret",
      "environmentUrl": "https://your-company.operations.dynamics.com",
      "default": true
    },
    {
      "name": "uat",
      "displayName": "UAT (Tier 2)",
      "type": "non-production",
      "tenantId": "your-tenant-id",
      "clientId": "your-client-id",
      "clientSecret": "your-client-secret",
      "environmentUrl": "https://your-company-uat.sandbox.operations.dynamics.com"
    },
    {
      "name": "dev",
      "displayName": "Dev Sandbox",
      "type": "non-production",
      "tenantId": "your-tenant-id",
      "clientId": "your-client-id",
      "clientSecret": "your-client-secret",
      "environmentUrl": "https://your-company-dev.sandbox.operations.dynamics.com"
    }
  ]
}

环境类型:

  • type: "production" -只读访问(所有写入操作都被阻止)
  • type: "non-production" -完全读/写访问权限(启用创建、更新、删除)

复制 d365-environments.example.json 作为一个起点。

单一环境(遗留)

服务器还支持以下环境变量(如果没有JSON配置,则回退):

变量描述
D365_TENANT_IDAzure AD租户ID
D365_CLIENT_IDAzure AD应用程序(客户端)ID
D365_CLIENT_SECRETAzure AD客户端机密
D365_ENVIRONMENT_URLD365 F&O环境URL(例如。, https://contoso.operations.dynamics.com)
D365_ENVIRONMENT_TYPE可选:“生产”或“非生产”(安全默认为“生产”)

可选:

变量默认值描述
D365_TRANSPORTstdio运输方式(stdiohttp)
D365_HTTP_PORT3000HTTP端口(使用HTTP传输时)
D365_LOG_LEVELinfo日志记录级别
D365_PAGINATION_TIMEOUT_MS60000大型数据集上分页请求的超时(毫秒)
D365_CONFIG_FILE配置文件的路径(如果不在默认位置)

Azure AD应用程序注册

步骤1:创建Azure AD应用程序

  1. 首选 Azure 门户 >Azure Active Directory>应用程序注册
  2. 点击“新建注册”
  3. 命名它(例如,“D365 MCP服务器”)
  4. 选择“仅此组织目录中的帐户”
  5. 点击注册

步骤2:配置API权限

  1. 转到“API权限”>“添加权限”
  2. 选择“Dynamics 365财务和运营”
  3. 选择“应用程序权限”> CustomService.ReadWrite.All
  4. 单击“授予\[您的组织\]管理员同意”

步骤3:创建客户端密码

  1. 转到“证书和机密”>“新客户机密”
  2. 添加描述和有效期
  3. 立即复制机密值(仅显示一次)
  4. 记下:

- 租户ID:在概述页面上找到 - 客户端ID:概述页面上的应用程序(客户端)ID - 客户端密钥:您刚才复制的值

步骤4:在D365环境中注册应用程序

重要提示: 此步骤必须在您要连接的每个D365环境(生产、UAT、开发)中完成。

  1. 在D365 F&O中,导航到:

系统管理>设置>Azure Active Directory应用程序

  1. 点击“新建”添加记录:
字段
客户端IDAzure AD中的应用程序(客户端)ID
名称描述性名称(例如“MCP服务器集成”)
用户ID应用程序运行的D365用户帐户
  1. 用户ID 确定应用程序可以访问哪些数据:

- 使用具有适当安全角色的服务帐户 - 对于只读访问:分配“查看所有数据”等角色 - 对于非生产环境下的写访问:分配允许创建/更新/删除的角色

  1. 对要连接的每个环境重复此操作
注: 如果跳过此步骤,即使Azure AD身份验证成功,API调用也将失败,并出现401个未授权错误或403个禁止错误。

设置

克劳德桌面版

添加到您的Claude Desktop配置文件中:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json 视窗: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "Microsoft D365": {
      "command": "node",
      "args": ["/path/to/d365fo-mcp-server/dist/index.js"],
      "env": {
        "D365_TENANT_ID": "your-tenant-id",
        "D365_CLIENT_ID": "your-client-id",
        "D365_CLIENT_SECRET": "your-client-secret",
        "D365_ENVIRONMENT_URL": "https://your-env.operations.dynamics.com"
      }
    }
  }
}

克劳德代码(CLI)

添加 ~/.claude/settings.json:

{
  "mcpServers": {
    "Microsoft D365": {
      "command": "node",
      "args": ["/path/to/d365fo-mcp-server/dist/index.js"],
      "env": {
        "D365_TENANT_ID": "your-tenant-id",
        "D365_CLIENT_ID": "your-client-id",
        "D365_CLIENT_SECRET": "your-client-secret",
        "D365_ENVIRONMENT_URL": "https://your-env.operations.dynamics.com"
      }
    }
  }
}

添加配置后,重新启动Claude Desktop或Claude Code。

环境可见性配置

使用多个D365环境时,您可以配置它们在Claude中的显示方式:

选项A:每个环境单独的服务器(推荐)

此选项在Claude的侧栏中将每个环境显示为单独的MCP服务器:

{
  "mcpServers": {
    "D365-production": {
      "command": "node",
      "args": ["/path/to/d365fo-mcp-server/dist/index.js"],
      "env": {
        "D365_CONFIG_FILE": "/path/to/d365fo-mcp-server/d365-environments.json",
        "D365_SINGLE_ENV": "production"
      }
    },
    "D365-uat": {
      "command": "node",
      "args": ["/path/to/d365fo-mcp-server/dist/index.js"],
      "env": {
        "D365_CONFIG_FILE": "/path/to/d365fo-mcp-server/d365-environments.json",
        "D365_SINGLE_ENV": "uat"
      }
    },
    "D365-dev": {
      "command": "node",
      "args": ["/path/to/d365fo-mcp-server/dist/index.js"],
      "env": {
        "D365_CONFIG_FILE": "/path/to/d365fo-mcp-server/d365-environments.json",
        "D365_SINGLE_ENV": "dev"
      }
    }
  }
}

赞成的意见:

  • 环境在Claude的侧边栏中立即可见
  • 查询所针对的环境没有歧义
  • 在所有平台上可靠工作

它是如何工作的:D365_SINGLE_ENV 环境变量告诉服务器从 d365-environments.jsonThe D365_CONFIG_FILE 确保无论工作目录如何,都能找到配置。

选项B:单个多环境服务器

使用具有以下功能的单个服务器 environment 每个查询上的参数:

{
  "mcpServers": {
    "d365": {
      "command": "node",
      "args": ["/path/to/d365fo-mcp-server/dist/index.js"],
      "env": {
        "D365_CONFIG_FILE": "/path/to/d365fo-mcp-server/d365-environments.json"
      }
    }
  }
}

然后在查询中指定环境:

{ "entity": "CustomersV3", "top": 10, "environment": "uat" }

赞成的意见:

  • 单服务器进程
  • 在一次会话中灵活查询任何环境

交互式设置脚本(node setup.js)可以为您生成任一配置。

与克劳德交谈-示例提示

配置后,您可以向Claude自然语言提问有关D365环境的问题。以下是按能力组织的示例:

发现实体

你: D365中有哪些与客户相关的实体?

克劳德将使用 d365://entities?filter=*Cust* 查找匹配实体的资源。

你: 显示CustomersV3实体的架构

克劳德将使用 describe_entityd365://entity/CustomersV3 资源。

查询数据

你: 给我前10个客户的账号和姓名

克劳德将使用 execute_odata 与路径 CustomersV3?$top=10&$select=CustomerAccount,CustomerName

你: 系统中有多少个销售订单?

克劳德将使用 execute_odata 与路径 SalesOrderHeaders/$count

你: 查找客户组“US”中信用额度超过50000的所有客户

Claude将自动构造OData过滤器查询。

聚合和分析

你: 按总支出计算,我们的前20位客户是谁?

克劳德将使用 aggregate 使用groupBy、orderBy和top:

{
  "entity": "SalesOrderLinesV2",
  "aggregations": [{"function": "SUM", "field": "LineAmount"}],
  "groupBy": ["OrderingCustomerAccountNumber"],
  "orderBy": "sum_LineAmount desc",
  "top": 20
}
你: 订单中值是多少?也给我看看第90和第95百分位数

克劳德将使用 aggregate 使用百分位数函数:

{
  "entity": "SalesOrderLinesV2",
  "aggregations": [
    {"function": "P50", "field": "LineAmount", "alias": "median"},
    {"function": "P90", "field": "LineAmount"},
    {"function": "P95", "field": "LineAmount"}
  ],
  "accurate": true
}
你: 按产品类别细分总收入

克劳德将使用 aggregate 使用groupBy:

{
  "entity": "SalesOrderLinesV2",
  "aggregations": [{"function": "SUM", "field": "LineAmount"}],
  "groupBy": ["ItemGroup"]
}

基于时间的分析

你: 显示过去12个月的月度销售趋势和增长率

克劳德将使用 trending:

{
  "entity": "SalesOrderLinesV2",
  "dateField": "CreatedDateTime",
  "valueField": "LineAmount",
  "granularity": "month",
  "periods": 12,
  "includeGrowthRate": true
}
你: 将今年的销售额与去年进行比较

克劳德将使用 compare_periods 与去年同期相比:

{
  "entity": "SalesOrderLinesV2",
  "dateField": "CreatedDateTime",
  "comparisonType": "YoY",
  "aggregations": [{"function": "SUM", "field": "LineAmount"}]
}
你: 第四季度的销售额与第三季度相比如何?

克劳德将使用 compare_periods 与QoQ比较:

{
  "entity": "SalesOrderLinesV2",
  "dateField": "CreatedDateTime",
  "comparisonType": "QoQ",
  "aggregations": [{"function": "SUM", "field": "LineAmount"}]
}

客户智能

你: 请给我一份完整的客户US-001分析,包括客户概况、订单、支出和趋势

克劳德将使用 analyze_customer 为了进行全面的单次通话分析:

{
  "customerAccount": "US-001",
  "includeOrders": true,
  "includeSpend": true,
  "includeTrending": true
}
你: 查找名为“S&S Industries”的客户

克劳德将使用 search_entity 它处理违反标准OData的特殊字符:

{
  "entity": "CustomersV3",
  "searchTerm": "S&S Industries",
  "searchField": "CustomerName"
}

多查询和联接

你: 给我一个仪表板视图:总客户数、本月总订单数和按销售额排名的前5名产品

克劳德将使用 batch_query 并行运行所有三个查询:

{
  "queries": [
    {"name": "total_customers", "entity": "CustomersV3", "top": 1},
    {"name": "orders_this_month", "entity": "SalesOrderHeadersV2", "filter": "OrderCreatedDateTime ge 2024-01-01"},
    {"name": "top_products", "entity": "SalesOrderLinesV2", "top": 5, "orderby": "LineAmount desc"}
  ]
}
你: 显示最近的订单,包括客户名称及其客户群

克劳德将使用 join_entities 将订单与客户详细信息相关联:

{
  "primaryEntity": "SalesOrderHeadersV2",
  "primaryKey": "OrderingCustomerAccountNumber",
  "secondaryEntity": "CustomersV3",
  "secondaryKey": "CustomerAccount",
  "primarySelect": ["SalesOrderNumber", "OrderCreatedDateTime"],
  "secondarySelect": ["CustomerName", "CustomerGroup"]
}

数据导出

你: 将信用额度超过10万美元的所有客户导出为CSV

克劳德将使用 export 使用格式和过滤器:

{
  "entity": "CustomersV3",
  "format": "csv",
  "filter": "CreditLimit gt 100000",
  "select": ["CustomerAccount", "CustomerName", "CreditLimit"]
}

理解枚举

你: 销售订单状态的可能值是什么?

克劳德会检查 d365://enums 资源以查找枚举定义。

最佳结果提示

  1. 直接问商业问题 -MCP工具为您处理复杂性。只需问:“按支出计算,我们的前20大客户是谁?”或“第四季度与第三季度相比如何?”
  1. 使用自然日期格式 -克劳德理解“上个月”、“2024年第四季度”、“过去12个月”或“2024月1日”等特定日期
  1. 不要担心特殊人物 -搜索“S&S Industries”或“O'Brien Corp”会自动运行。这些工具为违反标准OData的角色提供了回退策略。
  1. 请求趋势和比较 -内置的时间智能可以处理复杂性:“显示每月的销售趋势和增长率”或“将今年的收入与去年进行比较”
  1. 合并多个问题 -询问仪表板风格的视图:“获取我的总客户数、本月订单数和前5名产品”-查询并行运行。
  1. 需要时导出数据 -直接请求CSV、JSON或TSV导出:“将信用额度超过10万美元的所有客户导出为CSV”
  1. 要求解释 -如果你想学习OData语法,请Claude解释查询:“向美国组中的客户展示并解释OData查询”

API 参考

资源

d365://entities

列出具有可选过滤功能的可用D365实体。

查询参数:

  • filter (可选):通配符模式(* 对于任何字符, ? 对于单个字符)

示例:

d365://entities                    # List all entities
d365://entities?filter=Cust*       # Entities starting with "Cust"
d365://entities?filter=*Header*    # Entities containing "Header"

d365://entity/{entityName}

获取实体的完整架构。

示例:

d365://entity/CustomersV3
d365://entity/SalesOrderHeaders

答复包括:

  • 实体名称和描述
  • 主要关键字段
  • 所有具有类型、约束和枚举引用的字段
  • 导航属性(关系)

d365://navigation/{entityName}

获取实体的导航属性(关系)。

示例:

d365://navigation/SalesOrderHeadersV2
d365://navigation/CustomersV3

答复包括:

  • 导航属性名称
  • 目标实体类型
  • 关系基数(一对多,多对一)

d365://enums

列出所有枚举类型定义。

答复包括:

  • 枚举名称和完整命名空间
  • 所有成员值及其数字代码

工具

list_environments

列出所有已配置的D365环境及其连接状态和权限。

参数:

  • 无需

例子:

{}

答复包括:

  • 环境名称和显示名称
  • 类型(生产/非生产)
  • 连接状态
  • 读/写权限

set_environment

设置当前会话的工作环境。默认情况下,后续的工具调用将使用此环境。

参数:

  • environment (string,必填):要设置为活动的环境的名称

例子:

{
  "environment": "uat"
}

describe_entity

以人类可读的格式获取实体模式。

参数:

  • entity (字符串,必填):实体名称

例子:

{
  "entity": "CustomersV3"
}

execute_odata

对D365执行原始OData路径。

参数:

  • path (字符串,必填):OData路径附加到 /data/

示例:

// Query with parameters
{ "path": "CustomersV3?$top=5&$select=CustomerAccount,CustomerName" }

// Single record by key
{ "path": "CustomersV3('US-001')" }

// Compound key
{ "path": "CustomersV3(DataAreaId='usmf',CustomerAccount='US-001')" }

// Count
{ "path": "CustomersV3/$count" }

// Filtered count
{ "path": "CustomersV3/$count?$filter=CustomerGroup eq 'US'" }

// With expansion
{ "path": "SalesOrderHeaders?$expand=SalesOrderLines&$top=3" }

aggregate

对D365实体数据执行聚合。使用速度快 /$count 对于简单的COUNT操作,否则进行客户端聚合。

参数:

  • entity (字符串,必填):要聚合的实体名称
  • aggregations (array,必填):聚合规范数组:

- function:“SUM”|“AVG”|“COUNT”|“MIN”|“MAX”|“COUNTDISTINCT”|“P50”|“P90”|“p65”|“P99” - field:要聚合的字段(COUNT使用“\*”) - alias (可选):自定义结果名称

  • filter (字符串,可选):OData$筛选器表达式
  • groupBy (数组,可选):分组依据的字段
  • accurate (布尔值,可选):获取所有记录以获得确切的总计(默认值:false)
  • sampling (布尔值,可选):使用统计抽样对非常大的数据集进行快速估计(默认值:false)
  • orderBy (字符串,可选):按聚合别名对结果进行排序(例如,“sum_LineAmount-desc”)
  • top (数字,可选):排序后仅返回前N个结果

百分位数函数:

  • P50 -中位数(第50百分位)
  • P90 -第90百分位数
  • P95 -第95百分位数
  • P99 -第99百分位数

业绩说明:

  • 默认模式上限为5K记录,以便快速估算
  • accurate=true 获取所有记录,每页超时60秒,并自动重试(2次重试,指数回退)
  • sampling=true 使用约10K的记录样本对非常大的数据集(100K+条记录)进行统计估计

示例:

// Count all customers
{ "entity": "CustomersV3", "aggregations": [{"function": "COUNT", "field": "*"}] }

// Sum with filter
{ "entity": "SalesOrderLines", "aggregations": [{"function": "SUM", "field": "LineAmount"}], "filter": "SalesOrderNumber eq 'SO-001'" }

// Accurate mode for exact totals
{ "entity": "SalesOrderLines", "aggregations": [{"function": "SUM", "field": "LineAmount"}], "accurate": true }

// Group by
{ "entity": "SalesOrderLines", "aggregations": [{"function": "SUM", "field": "LineAmount"}], "groupBy": ["ItemNumber"] }

// Median order value (requires accurate=true for percentiles)
{ "entity": "SalesOrderLines", "aggregations": [{"function": "P50", "field": "LineAmount"}], "accurate": true }

// Fast estimate on very large dataset (100K+ records)
{ "entity": "BatchJobs", "aggregations": [{"function": "COUNT", "field": "*"}], "sampling": true }

// Top 20 customers by spend
{ "entity": "SalesOrderLines", "aggregations": [{"function": "SUM", "field": "LineAmount"}], "groupBy": ["CustomerAccount"], "orderBy": "sum_LineAmount desc", "top": 20 }

get_related

遵循实体关系,在一次调用中检索相关记录。

参数:

  • entity (字符串,必填):源实体名称
  • key (string | object,必填):源记录的主键
  • relationship (字符串,必填):要遵循的导航属性名称
  • select (string\[\],可选):要从相关实体中包含的字段
  • filter (字符串,可选):应用于相关记录的筛选器
  • top (数字,可选):最大相关记录数(默认值:1000)

示例:

// Get order lines for an order
{ "entity": "SalesOrderHeaders", "key": "SO-001", "relationship": "SalesOrderLines" }

// With compound key
{ "entity": "SalesOrderHeaders", "key": {"DataAreaId": "usmf", "SalesOrderNumber": "SO-001"}, "relationship": "SalesOrderLines" }

// With field selection and filter
{ "entity": "SalesOrderHeaders", "key": "SO-001", "relationship": "SalesOrderLines", "select": ["ItemNumber", "LineAmount"], "filter": "LineAmount gt 1000" }

export

将D365实体数据导出为CSV、JSON或TSV格式。

参数:

  • entity (string,必填):要导出的实体
  • format (“json”|“csv”|“tsv”,可选):输出格式(默认:“json”)
  • select (string\[\],可选):要包含的字段
  • filter (字符串,可选):OData$筛选器表达式
  • orderBy (字符串,可选):OData$orderby表达式
  • maxRecords (数字,可选):最大记录数(默认值:10000)
  • includeHeaders (布尔值,可选):包括CSV/TSV的标题行(默认值:true)

示例:

// JSON export with field selection
{ "entity": "CustomersV3", "format": "json", "select": ["CustomerAccount", "CustomerName"] }

// CSV export with filter
{ "entity": "SalesOrderLines", "format": "csv", "filter": "SalesOrderNumber eq 'SO-001'" }

// TSV with ordering and limit
{ "entity": "Products", "format": "tsv", "orderBy": "ProductName asc", "maxRecords": 500 }

compare_periods

比较两个时间段(同比、季度、月环比或自定义范围)之间的聚合。

参数:

  • entity (string,必填):要分析的实体
  • dateField (字符串,必填):用于筛选的日期/日期时间字段
  • aggregations (数组,必填):与聚合工具相同
  • comparisonType (“YoY”|“QoQ”|“MoM”|“custom”,必填):比较类型
  • referenceDate (字符串,可选):计算参考日期(默认值:今天)
  • period1, period2 (对象,可选):自定义期间范围
  • filter (字符串,可选):附加OData筛选器
  • groupBy (string\[\],可选):分组依据的字段

示例:

// Year-over-Year comparison
{ "entity": "SalesOrderLines", "dateField": "CreatedDateTime", "comparisonType": "YoY", "aggregations": [{"function": "SUM", "field": "LineAmount"}] }

// Month-over-Month with grouping
{ "entity": "SalesOrderLines", "dateField": "CreatedDateTime", "comparisonType": "MoM", "aggregations": [{"function": "COUNT", "field": "*"}], "groupBy": ["ItemGroup"] }

// Custom date ranges
{ "entity": "SalesOrderLines", "dateField": "CreatedDateTime", "comparisonType": "custom", "aggregations": [{"function": "SUM", "field": "LineAmount"}], "period1": {"start": "2024-01-01", "end": "2024-03-31"}, "period2": {"start": "2023-01-01", "end": "2023-03-31"} }

trending

时间序列分析,包括聚合、增长率和移动平均线。

参数:

  • entity (string,必填):要分析的实体
  • dateField (字符串,必填):用于分组的日期/日期时间字段
  • valueField (字符串,必填):要聚合的数字字段
  • aggregation (“SUM”|“AVG”|“COUNT”|“MIN”|“MAX”,可选):默认值:“SUM”
  • granularity (“天”|“周”|“月”|“季度”|“年”,可选):默认值:“月”
  • periods (数字,可选):要分析的周期数(默认值:12)
  • endDate (字符串,可选):分析结束日期(默认值:今天)
  • filter (字符串,可选):附加OData筛选器
  • movingAverageWindow (数字,可选):MA计算的窗口大小
  • includeGrowthRate (布尔值,可选):包括增长率(默认值:true)

示例:

// Monthly revenue trend
{ "entity": "SalesOrderLines", "dateField": "CreatedDateTime", "valueField": "LineAmount", "granularity": "month", "periods": 12 }

// Weekly order count with moving average
{ "entity": "SalesOrderHeaders", "dateField": "OrderDate", "valueField": "*", "aggregation": "COUNT", "granularity": "week", "movingAverageWindow": 4 }

// Quarterly with filter
{ "entity": "SalesOrderLines", "dateField": "CreatedDateTime", "valueField": "LineAmount", "granularity": "quarter", "filter": "ItemGroup eq 'Electronics'" }

save_query

保存可重用的查询模板以供以后执行。使用 {{paramName}} 对于可替换的参数。

参数:

  • name (字符串,必填):查询的唯一名称
  • description (字符串,可选):查询描述
  • entity (字符串,必填):要查询的实体
  • select (string\[\],可选):要选择的字段
  • filter (字符串,可选):OData$filter(使用 {{paramName}} 参数)
  • orderBy (字符串,可选):OData$orderby表达式
  • top (数字,可选):最大记录数
  • expand (字符串,可选):OData$expand表达式

示例:

// Basic query
{ "name": "active_customers", "entity": "CustomersV3", "filter": "IsActive eq true" }

// With parameters
{ "name": "customer_orders", "entity": "SalesOrderHeaders", "filter": "CustomerAccount eq '{{customerId}}'" }

// Complex query with description
{ "name": "recent_sales", "description": "Recent sales for analysis", "entity": "SalesOrderLines", "select": ["ItemNumber", "LineAmount"], "filter": "CreatedDateTime ge {{startDate}}", "orderBy": "CreatedDateTime desc", "top": 100 }

execute_saved_query

执行以前保存的查询模板。

参数:

  • name (字符串,必填):已保存查询的名称
  • params (对象,可选):要替换的参数值
  • fetchAll (boolean,可选):获取所有页面(默认值:false)
  • maxRecords (number,可选):fetchAll=true时的最大记录数(默认值:50000)

示例:

// Simple execution
{ "name": "active_customers" }

// With parameters
{ "name": "customer_orders", "params": {"customerId": "US-001"} }

// Multiple parameters with pagination
{ "name": "date_range_sales", "params": {"startDate": "2024-01-01", "endDate": "2024-12-31"}, "fetchAll": true }

delete_saved_query

删除已保存的查询模板。

参数:

  • name (字符串,必填):要删除的查询的名称

join_entities

使用OData$expand或客户端连接进行跨实体连接。

参数:

  • primaryEntity (字符串,必填):主要实体名称
  • primaryKey (字符串,必填):要加入的主键字段
  • secondaryEntity (字符串,必填):次要实体名称
  • secondaryKey (字符串,必填):要加入的次要关键字字段
  • primarySelect (string\[\],可选):主实体中的字段
  • secondarySelect (string\[\],可选):来自辅助实体的字段
  • primaryFilter (字符串,可选):主实体筛选器
  • joinType (“内部”|“左侧”,可选):连接类型(默认:“内部”)
  • maxRecords (数字,可选):最大记录数(默认值:5000)

示例:

// Join orders with customers
{ "primaryEntity": "SalesOrderHeadersV2", "primaryKey": "OrderingCustomerAccountNumber", "secondaryEntity": "CustomersV3", "secondaryKey": "CustomerAccount", "primarySelect": ["SalesOrderNumber", "OrderCreatedDateTime"], "secondarySelect": ["CustomerName", "CustomerGroup"] }

batch_query

并行执行多个D365 OData查询,在单个响应中返回所有结果。

参数:

  • queries (array,必填):查询规范数组(1-10个查询):

- name (字符串,可选):此查询结果的标签 - entity (字符串,必填):实体名称 - filter (字符串,可选):OData$筛选器表达式 - select (string\[\],可选):要包含的字段 - top (数字,可选):限制记录(默认值:100) - orderby (字符串,可选):OData$orderby表达式 - fetchAll (布尔值,可选):自动分页所有页面 - maxRecords (number,可选):fetchAll=true时的最大记录数

  • stopOnError (布尔值,可选):第一次失败时停止(默认值:false)

示例:

// Multiple parallel queries
{
  "queries": [
    { "name": "recent_orders", "entity": "SalesOrderHeadersV2", "top": 10, "orderby": "CreatedDateTime desc" },
    { "name": "customers", "entity": "CustomersV3", "filter": "CustomerGroup eq 'US'", "select": ["CustomerAccount", "CustomerName"] },
    { "name": "all_invoices", "entity": "SalesInvoiceHeadersV2", "fetchAll": true, "maxRecords": 1000 }
  ]
}

search_entity

具有自动回退策略的强大实体搜索。处理特殊字符(如 & 在公司名称中)导致标准OData出现问题 contains().

搜索策略(按顺序尝试):

  1. contains() -标准OData文本搜索(最快)
  2. startswith() -前缀匹配(在D365上更可靠)
  3. exact -精确的字段匹配
  4. client_filter -Fetch+客户端过滤器(始终有效)

参数:

  • entity (字符串,必填):要搜索的实体
  • searchTerm (字符串,必填):要搜索的文本
  • searchField (字符串,必填):要搜索的字段
  • select (string\[\],可选):结果中返回的字段
  • top (数字,可选):最大结果(默认值:10)

示例:

// Search customers with special characters
{ "entity": "CustomersV3", "searchTerm": "S&S", "searchField": "CustomerName" }

// Search with specific fields
{ "entity": "CustomersV3", "searchTerm": "Contoso", "searchField": "CustomerName", "select": ["CustomerAccount", "CustomerName", "CustomerGroup"], "top": 5 }

// Search vendors
{ "entity": "VendorsV3", "searchTerm": "Microsoft", "searchField": "VendorName" }

analyze_customer

在一次通话中进行全面的客户分析。运行并行查询以收集配置文件、订单、支出和趋势数据。

特征:

  • 客户资料查找(使用回退搜索策略)
  • 订单统计(计数、总支出、平均订单价值)
  • 订单日期范围(第一个和最后一个订单)
  • 最近订单列表
  • 月度订单趋势

在线路级别使用高效聚合(SalesOrderLinesV2)为了准确计算支出,避免了标题总计为0美元的问题。

参数:

  • customerAccount (字符串,可选):客户账号
  • customerName (字符串,可选):要搜索的客户名称(处理特殊字符)
  • includeOrders (布尔值,可选):包括最近的订单列表(默认值:true)
  • includeSpend (布尔值,可选):包括总支出计算(默认值:true)
  • includeTrending (布尔值,可选):包括月度趋势分析(默认值:true)
  • recentOrdersLimit (number,可选):要显示的最近订单数(默认值:10)
  • trendPeriods (数字,可选):趋势的月数(默认值:12)

示例:

// Analyze by account number
{ "customerAccount": "SS0011" }

// Analyze by name (handles special characters like &)
{ "customerName": "S&S" }

// Quick analysis without trending (faster)
{ "customerAccount": "US-001", "includeTrending": false }

// Full analysis with custom periods
{ "customerName": "Contoso", "recentOrdersLimit": 20, "trendPeriods": 24 }

输出包括:

  • 客户资料(姓名、帐户、组、地址)
  • 汇总统计数据(总订单、总支出、平均订单价值、首次/最后一次订单日期)
  • 最近订单列表
  • 月度订单趋势表,包括订单数量和收入

d365://queries

列出所有已保存查询模板的资源。

答复包括:

  • 查询计数和列表
  • 每个查询的名称、描述、实体和参数
  • 使用说明

dashboard

显示包含运行状况状态、API统计信息和最近操作的环境仪表板。

参数:

  • checkHealth (布尔值,可选):执行实时连接检查(默认值:false)

例子:

{
  "checkHealth": true
}

答复包括:

  • 根据环境健康状况
  • API呼叫统计数据(呼叫总数、成功率)
  • 最近的操作日志
  • 环境配置摘要

OData查询语法

筛选器示例

// Equality
$filter=CustomerAccount eq 'US-001'

// Comparison
$filter=CreditLimit gt 10000

// String functions
$filter=startswith(CustomerName, 'Contoso')
$filter=contains(CustomerName, 'Inc')

// Logical operators
$filter=CustomerGroup eq 'US' and CreditLimit gt 5000

// Enum values
$filter=Status eq Microsoft.Dynamics.DataEntities.SalesStatus'Invoiced'

// Date comparison
$filter=OrderDate gt 2024-01-01

选择并展开

// Select specific fields
$select=CustomerAccount,CustomerName,CreditLimit

// Expand navigation property
$expand=SalesOrderLines

// Expand with nested select
$expand=SalesOrderLines($select=ItemId,Quantity)

排序和分页

// Sort ascending
$orderby=CustomerName asc

// Sort descending
$orderby=OrderDate desc

// Multiple sort columns
$orderby=CustomerGroup asc,CustomerName asc

// Pagination
$top=50&$skip=100

发展

# Build
npm run build

# Watch mode
npm run dev

# Run directly (requires environment variables)
npm start

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

项目结构

src/
├── index.ts                # Entry point and server setup
├── config-loader.ts        # Configuration loading (JSON + env var fallback)
├── environment-manager.ts  # Multi-environment management and write guards
├── auth.ts                 # Azure AD OAuth2 authentication
├── d365-client.ts          # D365 OData API client with read/write methods
├── metadata-cache.ts       # EDMX metadata parser and cache (24h TTL)
├── progress.ts             # Progress reporting for long operations
├── types.ts                # TypeScript type definitions
├── metrics/
│   ├── index.ts            # Metrics module exports
│   ├── metrics-tracker.ts  # API call statistics tracking
│   ├── health-checker.ts   # Environment connectivity health checks
│   └── operation-log.ts    # Operation history tracking
├── resources/
│   ├── index.ts            # Resource registration
│   ├── entities.ts         # d365://entities resource
│   ├── entity.ts           # d365://entity/{name} resource
│   ├── navigation.ts       # d365://navigation/{name} resource
│   ├── enums.ts            # d365://enums resource
│   ├── queries.ts          # d365://queries resource
│   └── dashboard.ts        # d365://dashboard resource
├── utils/
│   ├── date-utils.ts       # Date period calculations
│   ├── csv-utils.ts        # CSV/TSV formatting
│   ├── env-utils.ts        # Environment variable parsing with validation
│   └── pagination.ts       # Shared pagination utilities (fetchPageWithRetry, paginatedFetch)
└── tools/
    ├── index.ts            # Tool registration
    ├── common.ts           # Shared tool utilities and error formatting
    ├── list-environments.ts
    ├── set-environment.ts
    ├── describe-entity.ts
    ├── execute-odata.ts
    ├── aggregate.ts
    ├── get-related.ts
    ├── export.ts
    ├── compare-periods.ts
    ├── trending.ts
    ├── saved-queries.ts    # save/execute/delete query templates
    ├── join-entities.ts
    ├── batch-query.ts
    ├── batch-crud.ts       # Batch create/update/delete via $batch (non-production only)
    ├── compare-schemas.ts  # Cross-environment schema comparison
    ├── search-entity.ts
    ├── analyze-customer.ts
    ├── create-record.ts    # Write operation (non-production only)
    ├── update-record.ts    # Write operation (non-production only)
    ├── delete-record.ts    # Write operation (non-production only)
    └── dashboard.ts
tests/
├── auth.test.ts            # Token caching, refresh dedup, invalidation
├── d365-client.test.ts     # Retry logic, key formatting, CRUD operations
├── config-loader.test.ts   # JSON loading, env var fallback, validation
├── pagination.test.ts      # Shared pagination utilities
└── env-utils.test.ts       # parseInt validation utility

写入操作(仅限非生产)

写入操作仅在以下环境中可用 type: "non-production"生产环境始终是只读的。

create_record

在D365实体中创建新记录。

参数:

  • entity (字符串,必填):实体名称
  • data (object,必填):新记录的字段值
  • environment (字符串,可选):目标环境

例子:

{
  "entity": "CustomersV3",
  "data": {
    "CustomerAccount": "CUST-001",
    "CustomerName": "Contoso Ltd",
    "CustomerGroup": "US"
  },
  "environment": "uat"
}

update_record

更新现有记录。

参数:

  • entity (字符串,必填):实体名称
  • key (string | object,必填):记录键
  • data (对象,必填):要更新的字段值
  • etag (字符串,可选):ETag用于乐观并发
  • environment (字符串,可选):目标环境

例子:

{
  "entity": "CustomersV3",
  "key": "CUST-001",
  "data": {
    "CustomerName": "Contoso Corporation"
  },
  "environment": "dev"
}

delete_record

从实体中删除记录。

参数:

  • entity (字符串,必填):实体名称
  • key (string | object,必填):记录键
  • etag (字符串,可选):ETag用于乐观并发
  • environment (字符串,可选):目标环境

例子:

{
  "entity": "CustomersV3",
  "key": "CUST-001",
  "environment": "dev"
}

安全

凭证保护

此项目实现了多个层来保护您的Azure AD凭据:

保护说明
.gitignore.envd365-environments.json 被排除在版本控制之外
.gitattributes敏感文件排除在外 git archive 出口
预提交钩子在允许提交之前扫描暂存文件中的秘密模式
山宁泰错误Azure AD错误响应会在内部记录,但不会暴露给调用者

保护文件

以下文件包含凭据并受保护:

  • .env -环境变量(传统的单一环境配置)
  • d365-environments.json -具有秘密的多环境配置
  • *.local.json -本地配置覆盖

安全文件 (包含占位符,可以提交):

  • .env.example -带有占位符值的模板
  • d365-environments.example.json -配置示例

如果凭据被暴露

如果您意外提交或公开凭据:

  1. 立即轮换Azure AD客户端机密:

- 首选 Azure 门户 >Azure Active Directory>应用程序注册 - 选择您的D365应用程序注册 - 转到“证书和机密” - 创建新的客户端密钥 - 更新您的本地 .envd365-environments.json 新的秘密 - 从Azure AD中删除旧密钥

  1. 查看Azure AD登录日志:

- 检查是否存在未经授权的访问尝试 - Azure门户>Azure AD>登录日志>按应用程序筛选

  1. 如果使用git:

- 即使你在新的提交中删除了这个秘密,它也会保留在git历史中 - 考虑使用 git filter-branch 或BFG Repo Cleaner清除历史记录 - 强制推送已清理的存储库(与合作者协调)

旋转Azure AD秘密

最佳做法是定期轮换机密(每90-180天一次):

  1. 在Azure门户中创建新密钥 (旧版到期前)
  2. 更新配置文件:
   # Edit .env or d365-environments.json with new secret
  1. 测试连接性:
   npm start  # Verify authentication works
  1. 从Azure门户删除旧密钥

预提交钩子

预提交钩子会扫描以下模式:

  • Azure AD客户端机密(后30多个字符串 clientSecret)
  • 租户ID(UUID格式在后面 tenantId)
  • 带有机密的环境变量赋值

要绕过(仅适用于误报):

git commit --no-verify

运行时保护

  • 生产环境只读:生产环境下的写入操作在结构上被阻止
  • 非生产写访问:创建、更新、删除仅适用于 type: "non-production" 环境
  • 无证书风险:凭据在服务器端进行管理
  • OData注射预防:参数已正确编码

故障排除

MCP服务器未出现

  1. 完全重新启动克劳德桌面 -macOS上的Cmd+Q(不仅仅是关闭窗口),然后重新打开。在Windows上,使用Ctrl+Q或退出系统托盘。
  1. 检查服务器配置 -验证配置文件路径是否正确:
   D365_CONFIG_FILE=./d365-environments.json D365_SINGLE_ENV=uat node dist/index.js
  1. 验证配置路径 -确保 D365_CONFIG_FILE 在Claude配置中,指向的是 d365-environments.json.
  1. 检查克劳德日志 -在macOS上: ~/Library/Logs/Claude/;在Windows上: %APPDATA%\Claude\logs\

身份验证错误

  • 验证租户ID、客户端ID和密钥是否正确
  • 确保Azure AD应用程序具有所需的API权限
  • 检查是否已授予管理员同意

未找到实体

  • 使用 d365://entities 发现可用实体
  • 实体名称区分大小写
  • 某些实体可能不会通过OData公开

超时错误

  • 通过以下方式缩小查询范围 $top$filter
  • 对于大型数据集,使用分页 $skip
  • 使用 batch_query 并行运行多个查询

大型数据集聚合改进:

  • 分页请求现在使用60秒超时,并自动重试(2次重试,指数回退)
  • 通过配置超时 D365_PAGINATION_TIMEOUT_MS 环境变量
  • 对于非常大的数据集(100K+条记录),请使用 sampling=trueaggregate 快速统计估计工具
  • accurate=true 如果分页中途中断,模式现在会报告部分结果

许可证

麻省理工学院

目录标签

目录标签

TypeScriptClaude数据分析企业资源规划本地部署数据查询元数据管理业务分析财务系统

支持客户端

Claude DesktopClaude

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

token

运行时(runtime,运行环境)

Node.js

来源包(packageName,安装包名)

@zhound/d365fo-mcp-server

工具数量(toolCount,工具数)

22

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiotoken部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP