内容
# TIE MCP 服务器
Tenable Identity Exposure API 的模型上下文协议(MCP)服务器。
## 功能特点
- 完全覆盖所有 131 个 TIE API 操作(每个端点一个 MCP 工具)
- 额外的便捷工具,用于发现、导航、内存 AD 对象搜索、权限解码、控制图攻击路径分析和每个身份的 **偏差 360 度视图** (9 个自定义工具)
- 客户端凭证管理,用于安全
- 多租户支持(多个 TIE 环境)
- 粒度工具级安全控制
- 从 OpenAPI 规范自动生成的工具定义
## 为什么选择 MCP 服务器而不是原始 API 调用?
薄的“调用端点”包装器只会将原始 TIE API 提供给模型,继承 API 的形状和粗糙的边缘。该服务器添加了一层,使 API 变成模型可以有效使用的东西:
- **内存 AD 对象搜索,基于缓存的快照**。TIE API 在 `/api/ad-objects` 上 *没有服务器端过滤器* - 唯一一种按属性查找对象的方法是通过分页遍历整个目录(数万个对象,数十个请求)。如果天真地通过模型执行,则意味着获取数兆字节的 JSON 进入上下文窗口,并为每个问题再次分页。相反,`query_ad_objects` 只需扫描目录 **一次**,构建一个键入内存索引,并根据它回答表达式查询,几毫秒后即可使用 - 重用约 10 分钟,因此后续问题实际上是免费的。否则需要 ~50 个顺序 API 调用(甚至不能作为过滤器表达)的查找变成一个工具调用。参见 [AD 对象搜索](#ad-object-search)。
- **真正的查询语言**。属性被解码为键入值(数字、布尔值、数组),因此 `admincount>0`、`badpwdcount>=5` 和 `member:"dcadmin"` 的含义正如您所期望的那样,并且可以与 `AND`/`OR`/`NOT` 组合使用。API 返回所有内容为字符串,并且不提供任何方式组合条件。
- **安全描述符解码**。AD 权限存储在 `ntSecurityDescriptor` 中,作为密集的 SDDL 字符串 (`O:...G:...D:(A;;CCDC...;;;S-1-...)`),对于模型来说是不可读的,也无助于推理。`get_ad_object` 可以在请求时将其解码为结构化的 ACE,具有 **信任 SID 解析为名称** (来自驻留快照)、**命名权限** (`GenericAll`、`WriteDacl`、`ForceChangePassword`...) 和 **对象类型通过实时模式解析** - 将“谁可以控制此对象?”变成可读的答案,而不是 15 KB 的 blob。参见 [权限解码](#权限解码)。
## 示例用例
由于搜索在内存中运行,因此那些原本 impractical 作为 ad-hoc API 分页的问题变成了单个自然语言问题。几个可以直接映射到 `query_ad_objects` 表达式的示例:
- **具有弱卫生习惯的特权帐户** - “具有不良密码尝试的管理员”:`admincount>0 AND badpwdcount>0`。
- **Kerberoast 暴露** - “设置了 SPN 的用户帐户”:`serviceprincipalname:"/" AND type=LDAP` (任何 SPN 都包含 `/`)。
- **特权帐户中弱口令或泄露口令** - “具有泄露口令的特权帐户”:`admincount>0 AND isbreached=true`,或在任何配置文件策略下的弱口令:`admincount>0 AND isweak=true`。(这些来自 TIE 的口令哈希分析,与主体连接 - 参见 [凭证弱点](#credential-weakness)。)
## 结合功能的能力
真正的杠杆作用是将搜索、权限解码、控制图和凭证弱点在一条问题中结合起来。自然语言提示可以由编排器通过组合这些工具来回答:
- *"哪些非特权用户可以访问域管理员,以及如何访问?"* - `get_asset_exposure` 从 Tier-0 预设(反向),每个都有其最短的控制路径。
- *"如果 `bob` 被钓鱼,爆炸半径是多少?"* - `get_blast_radius({ principal: "bob" })`;遵循组成员资格、ACL 控制、委派、SID 历史、GPO 和密码重用。
- *"什么是我们的真正 Tier-0 - 每个可以成为管理员的用户,而不仅仅是组成员?"* - `get_tier0`,它返回内置特权组 **加上** 具有每个升级路径的实际 Tier-0。
- *"谁可以 DCSync 域,并且他们中是否有任何人有弱密码?"* - `query_ad_objects("isweak=true")` 与 `get_tier0` / 路径到域节点上的 DCSync 能力主体相交。
### 权限解码
`ntSecurityDescriptor` 是 AD 存储谁可以执行什么操作的地方,但它作为原始 SDDL 到达 - 一堵 ACE 代币和 SID 的墙,模型无法理解。向 `get_ad_object` 传递 `decodeSecurityDescriptor: true` 以将其作为结构化、已解析的事实取回:
```jsonc
get_ad_object({ samAccountName: "Domain Admins", decodeSecurityDescriptor: true })
// -> securityDescriptor:
{
"owner": { "sid": "S-1-5-...-512", "name": "Domain Admins" },
"aces": [
{ "effect": "Allow", "trustee": { "sid": "S-1-1-0", "name": "Everyone", "broad": true },
"rights": ["ReadProperty"], "appliesTo": null, "inherited": true },
{ "effect": "Allow", "trustee": { "sid": "S-1-5-...-1105", "name": "bob.shaft", "broad": false },
"rights": ["ControlAccess"], "appliesTo": "DS-Replication-Get-Changes-All" }
]
}
```
解码器执行原始字符串无法执行的操作:
- **将受托人 SID 解析为名称**,使用内存快照(每个对象的 SID 都已编制索引),并用 `broad: true` 标记广泛的主体(`Everyone`、`Authenticated Users`、`Anonymous`)。
- **命名权限** - `GenericAll`、`WriteDacl`、`WriteOwner`、`ForceChangePassword`、`AddMember` 等 - 并将完整控制令牌运行到 `GenericAll`。
- **通过实时模式解析对象类型 GUID** (例如,构成 DCSync 的两个复制权限),扩展权限和属性按名称显示。
- 区分 **允许/拒绝**,标记 **继承** 的 ACE,并且永远不会抛出格式错误的描述符。
这是 **事实,而不是判决** - 它报告 **谁具有哪些权限**,并将严重性留给您或 Tenable 的暴露指标。它也是下面控制图分析的基础;参见 [docs/CONTROL_GRAPH_DESIGN.md](docs/CONTROL_GRAPH_DESIGN.md)。
### 凭证弱点
TIE 运行密码哈希分析,并为每个分析的主体发出 `passwordHashScan` 配套对象。服务器将该信号加入主体(按 distinguished name),因此凭证弱点可以直接查询:
- `isbreached` - 密码出现在泄露的密码集中。
- `islmblank` / `isntblank` - 空 LM / NT 哈希。
- `isweak` - 派生布尔值:**至少一个** 配置文件的策略下的弱点。底层信号是每个配置文件(配置文件是配置镜头),并且如果密码与配置的弱/字典密码匹配或为空/等于 samAccountName,则密码为“弱”。原始配置文件分解保留为 `isweakByProfile` (`{ profileId: bool }`)以备细致查询。
```typescript
query_ad_objects({ expression: "isweak=true AND admincount>0" }) // 弱密码管理员
query_ad_objects({ expression: "isbreached=true" }) // 泄露密码
// 弱口令仅在配置文件 2 下(字段不区分大小写;原始映射作为子字符串匹配):
query_ad_objects({ expression: 'isweakByProfile:"\\"2\\":true"' })
```
事实,而不是判决 - TIE 的暴露指标已经评估了这些发现;这只是使它们可以与其他属性一起查询(并在计划步骤中作为攻击路径入口点使用)。
### 攻击路径分析(控制图)
单个对象问题(“此对象是否配置错误?”)是暴露指标回答的内容。更难的跨对象问题 - “通过权限和组成员资格的链接,**此帐户可以最终访问什么**,以及 **谁可以访问我的核心资产**?” - 是图问题。从驻留快照中,服务器构建一个有向 **控制图**,其边来自普通属性和解码的 SDDL:
- 成员资格(`MemberOf`,包括 `primaryGroupID`,`member` 忽略)
- `GenericAll` / `GenericWrite` / `WriteDacl` / `WriteOwner`,`AddMember`,`ForceChangePassword`,`AddKeyCredentialLink`(影子凭证)
- `DCSync`(两个复制权限,作用于域头),约束委派和 RBCD,`SIDHistory`
- `Contains`(容器→子)和 `GpoAppliesTo`(GPO→链接 OU),因此基于 GPO 的控制链降级到受影响的对象,以及
- `Controls`(域→域内主体):域妥协拥有域内所有对象的基本要素,在查询时合成路径 *通过* 域妥协到特定目标。例如:`unpriv → owns GPO → GpoAppliesTo OU → Contains user → DCSync → domain → Controls → Administrator`,以及
- `ReusedPassword`(主体 ↔ 共享密码中心):共享密码哈希的主体(来自 TIE 的重用分析)在中心节点集群,因此破坏一个主体可以访问所有共享凭证的主体。
三个工具遍历它 - 都是最短路径(BFS),深度/广度上限和无环:
```typescript
// 前向:若此帐户被泄露,它能访问什么?
get_blast_radius({ principal: "bob", maxDepth: 6 })
// 有针对性:X 如何访问 Y?返回边链。
get_control_paths({ from: "bob", to: "Domain Admins" })
// -> bob -MemberOf-> Helpdesk -GenericAll-> dcadmin -MemberOf-> Domain Admins
// 反向:谁可以访问此资产/ Tier-0 集?
get_asset_exposure({}) // Tier-0 预设(特权组)
get_asset_exposure({ targets: ["CN=FileServer01,..."] })
// 派生 Tier-0:特权组 + 所有可以成为特权的用户,每个都有其升级路径。“什么是我的真正 Tier-0 攻击面?”
get_tier0({})
```
注意和诚实的限制:
- **仅目录控制边**。这是无凭证切片 - 它 *不* 包括登录会话或本地管理员(那些需要实时主机收集器,如 BloodHound)。这里的路径是目录控制路径,因此 0 路径结果意味着“没有控制路径”,而不是“任何类型的攻击路径”。
- **事实,而不是判决**。结果报告可达性和确切的边链,而不是严重性评分。
- **防护栏**。`maxDepth`(默认 6)和 `maxNodes` 限制遍历,并且报告命中上限为 `truncated: "depth" | "nodes"` - 永远不会默默地,因为安全工具中的低报告是危险的。
- **按需构建**。图形从内存快照中构建,无需额外的 API 调用。设置 `TIE_BUILD_GRAPH=true` 以在启动时在后台构建它;否则,第一个图形查询会构建它(可能需要大型租户的几十秒)。参见 [docs/CONTROL_GRAPH_DESIGN.md](docs/CONTROL_GRAPH_DESIGN.md)。
### 身份 360(偏差视图)
暴露指标是 Tenable 如何标记配置错误,但每个偏差都针对 **一个** 对象 - 通常是 **受害者**。这使得从控制台“此身份暴露了什么?”的问题变得令人惊讶,因为同一个身份可以通过三种不同的方式成为危险或暴露,而每个对象的视图都无法统一。`get_identity_360` 为一个对象解析所有 **层**:
1. **`target`** - Tenable 直接在对象上记录的偏差(其自己的视图)。
2. **`trustee`** - 偏差对象是 **嵌入另一个对象发现中的风险主体**(例如,受害者上的危险 ACE 列表,或根分区)。这些永远不会出现在 Tenable 下,因为偏差属于受害者。
3. **`inherited`** - 对象所处的容器/分区的偏差,其暴露继承下来;通过控制图的 `Contains` 边构建(在第一次使用时构建)。
每个返回的偏差都是 **自包含且丰富的**:校验器 + 原因元数据,**严重性**(原始 `O-CRITICITY` *和* 关键/高/中/低频段),**补救成本**(原始 *和* 低/中/高频段),相关 `counterpart` 对象(适用于受托人/继承层),授予的权限,解析/忽略状态,以及指向 Tenable IOE 页面的 **deeplink**,以及 `deeplinkFilterHint`(`id:"<adObjectId>"`)以将页面过滤器缩小到确切的对象。结果按严重性频段排序,然后是原始临界值,然后是补救成本。
```typescript
// 完整、排序、深链接的某个身份的所有发现(所有三个层)。
get_identity_360({ samAccountName: "jaime.lannister" })
// 批量汇总:每个身份的严重性频段计数(用于报告徽章),
// 不显示完整的列表。混合 DN / SID / samAccountName / objectId;未解析的输入
// 返回时标记为失败而不是失败。
get_identity_360_summary({ identities: ["jaime.lannister", "S-1-5-...", 44656] })
```
注意:
- **严重性特定于配置文件**。`O-CRITICITY` 和 `O-ENABLED` 是特定于配置文件的(并且可以按目录覆盖);省略 `profileId` 使用您首选的配置文件。配置文件/目录中禁用的检查器默认情况下被排除,并且在单独的 `summary.suppressed` 计数中报告 - 因此不会默默地删除任何内容。
- **缓存的偏差索引**。所有偏差都扫描一次(配置文件范围),并在与对象快照相同的 TTL 后缓存;`refresh: true` 强制重新扫描。摘要和详细信息工具共享索引,因此 `get_identity_360_summary` 的徽章始终与扩展的 `get_identity_360` 视图匹配。
- **事实,而不是判决**。工具将 Tenable 自己的数字转换为频段并显示关系;它们不会重新评估风险。
### 新鲜度和缓存
快照**默认缓存 1 天**(`TIE_CACHE_TTL_MS` 可修改)并且**不是实时的** —— 它反映了上一次扫描时的目录状态。这是故意的:完整的扫描代价高昂,而 AD/TIE 状态变化相对于工作会话来说缓慢,因此廉价的重用是合适的默认设置。需要注意的后果:
- 每个查询/查找响应都包含一个 `snapshot` 块,报告缓存的 对象 `count`、`ageMs` 和 `ttlMs`,并且两个工具描述都告诉模型数据可能已过时 —— 因此它可以决定何时需要最新数据。
- **要强制使用当前数据,请在 `query_ad_objects` 或 `get_ad_object` 上传递 `refresh: true`**。经典陷阱:运行查询,修复 TIE 中的某些内容,重新查询,并看到 *旧* 数据,因为您没有刷新。
- 当 TTL 失效时,下一个查询会透明地重新扫描(无需采取任何操作)。
> **启动预热(默认启用):** 完整的目录扫描可能需要数十秒到 ~100 秒,针对大型租户。为了避免影响关键路径,服务器在**后台启动时预热快照** —— 在 `connect()` 之后,因此它从不会延迟启动,并且在扫描过程中到达的查询会简单地加入正在进行的构建(不会重复扫描)。到您运行第一个搜索时,缓存通常已经预热。还有两点:
>
> - **进度通知。** 如果 MCP 客户端将 `progressToken` 附加到触发扫描的调用中,服务器会发出 `notifications/progress`,每获取一页就通知一次(例如 "Scanning AD objects: 12000 loaded (12 pages)"),因此长时间扫描不会保持沉默。未请求进度的客户端只会看到一个更长的工具调用。
> - **禁用预热。** 设置 `TIE_WARM_CACHE=false` 以跳过启动扫描 —— 在从未搜索的租户上或在运行许多服务器实例时减少负载时很有用。然后,快照会在第一个查询时延迟构建。后台预热失败(例如启动时 TIE 不可达)会被捕获并记录,并且也会回退到延迟构建 —— 它永远不会使服务器崩溃。
## 安装
服务器作为您的 MCP 客户端的本地子进程运行,并通过标准输入/输出进行通信。请选择以下选项之一。
### 选项 A — npx(推荐,一次发布)
无需本地克隆或构建。在您的 MCP 客户端配置中直接引用它(参见 [配置](#配置)):
```json
{ "command": "npx", "args": ["-y", "tie-mcp-server"] }
```
### 选项 B — 从源代码
```bash
git clone <repo-url> tie-mcp-server
cd tie-mcp-server
npm install # 也会通过 `prepare` 脚本构建
npm run build # (在任何源代码更改后重新运行)
```
然后将您的客户端指向构建的入口点,例如 `node /absolute/path/to/tie-mcp-server/build/index.js`。
### 选项 C — Docker
为不希望在本地安装 Node 的用户提供了一个多阶段 `Dockerfile`。构建镜像:
```bash
docker build -t tie-mcp-server .
```
由于服务器通过标准输入/输出使用 MCP,因此容器必须交互式运行(`-i`)并将凭证作为环境变量传递:
```json
{
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "TIE_BASE_URL",
"-e", "TIE_API_KEY",
"tie-mcp-server"
],
"env": {
"TIE_BASE_URL": "https://customer.tenable.ad",
"TIE_API_KEY": "your-api-key-here"
}
}
```
> **注意:** 这是一个每个用户本地工具,使用 **stdio** 传输,因此 Docker Compose 不适用(没有要编排的长期运行的网络服务)。Docker 仅用于捆绑 Node 运行时。如果您需要一个集中托管的、多客户端的网关,则需要切换到 MCP 的 HTTP/SSE 传输 —— 参见 [作为共享服务托管](#作为共享服务托管)。
## 配置
MCP 服务器需要两个环境变量:
- `TIE_BASE_URL` - 您的 TIE 实例 URL(例如 `https://customer.tenable.ad`)
- `TIE_API_KEY` - 您的 TIE API 密钥
可选环境变量:
- `TIE_ALLOWED_SAFETY` - 以逗号分隔的安全性层级列表,用于宣传(`read`、`read,write`);参见 [服务器端安全性过滤器](#服务器端安全性过滤器)。
- `TIE_WARM_CACHE` - 在启动时构建 AD 对象搜索快照,而不是在第一个查询时。默认启用;设置为 `false` 以禁用(参见 [AD 对象搜索](#ad对象搜索))。
- `TIE_CACHE_TTL_MS` - AD 对象快照保持新鲜的时间(毫秒)(默认为 `86400000`,即 1 天)。降低它以权衡扫描成本和新鲜度。
- `TIE_BUILD_GRAPH` - `true` 以在快照预热后在后台构建控制图(攻击路径 / 影响范围 / 资产暴露边缘)。默认为关闭;增加 CPU + 内存。查询工具将在后续版本中发布。
- `TIE_TIMEOUT` - 每个请求的超时时间(毫秒)(默认为 `30000`)。
- `TIE_MAX_RETRIES` - 最大请求重试次数(默认为 `3`)。
### 单环境设置
添加到您的 MCP 客户端配置中(例如 `~/.claude/settings.json`):
```json
{
"mcpServers": {
"tie": {
"command": "node",
"args": ["/path/to/tie-mcp-server/build/index.js"],
"env": {
"TIE_BASE_URL": "https://customer.tenable.ad",
"TIE_API_KEY": "your-api-key-here"
}
}
}
}
```
### 多环境设置
对于多个 TIE 环境,请添加多个服务器实例:
```json
{
"mcpServers": {
"tie-prod": {
"command": "node",
"args": ["/path/to/tie-mcp-server/build/index.js"],
"env": {
"TIE_BASE_URL": "https://prod.tenable.ad",
"TIE_API_KEY": "prod-key"
}
},
"tie-staging": {
"command": "node",
"args": ["/path/to/tie-mcp-server/build/index.js"],
"env": {
"TIE_BASE_URL": "https://staging.tenable.ad",
"TIE_API_KEY": "staging-key"
}
}
}
}
```
## 开发
```bash
# 安装依赖
npm install
# 从 OpenAPI 规范重新生成工具定义(写入 src/generated/tools.ts)
npm run generate:tools
# (可选)从 OpenAPI 规范生成 TypeScript API 类型
npm run generate:client
# 构建项目
npm run build
# 开发模式的监视
npm run watch
# 不构建运行(开发)
npm run dev
# 类型检查
npm run typecheck
# linting
npm run lint
```
## 安全
### 客户端凭证
凭证**永远不会存储**在 MCP 服务器代码中。它们必须在客户端配置中配置(MCP 客户端配置)并作为环境变量传递给服务器进程。
### 工具级过滤
组织可以通过操作类型过滤工具,以实现粒度安全控制:
```json
{
"mcpServers": {
"tie": {
"command": "node",
"args": ["/path/to/tie-mcp-server/build/index.js"],
"env": {
"TIE_BASE_URL": "https://customer.tenable.ad",
"TIE_API_KEY": "key"
},
"allowedTools": ["get_*", "list_*", "search_*"],
"deniedTools": ["delete_*"]
}
}
}
```
工具按风险级别分类(每个生成的描述符上的 `safety` 字段):
- **绿色** **read** (70 个工具):`get_*`、`list_*`、`search_*`、`export_*`
- **黄色** **write** (51 个工具):`create_*`、`update_*`、`set_*`,以及诸如 `commit_*`、`login` 之类的操作
- **红色** **destructive** (10 个工具):`delete_*`、`unstage_*`
#### 服务器端安全性过滤器
除了客户端的 `allowedTools`/`deniedTools` 之外,服务器本身还遵循 `TIE_ALLOWED_SAFETY` 环境变量。将其设置为以逗号分隔的层级列表,以仅宣传这些工具 —— 例如 `read` 用于严格只读部署,或 `read,write` 以完全禁用破坏性操作:
```json
{
"mcpServers": {
"tie-readonly": {
"command": "node",
"args": ["/path/to/tie-mcp-server/build/index.js"],
"env": {
"TIE_BASE_URL": "https://customer.tenable.ad",
"TIE_API_KEY": "key",
"TIE_ALLOWED_SAFETY": "read"
}
}
}
}
```
## 架构
工具定义不是通过为每个端点编写处理程序生成的,而是从 OpenAPI 规范生成到单个数据文件中,一个通用调度器将任何描述符 + 参数转换为 HTTP 请求。
```
scripts/
└── generate-tools.mjs # 解析 OpenAPI 规范 -> src/generated/tools.ts
src/
├── index.ts # MCP 服务器:注册工具,路由调用
├── config.ts # 环境配置
├── client.ts # TIE API 的 HTTP 客户端(axios)
├── dispatch.ts # 通用描述符 -> HTTP 请求调度器
├── custom-tools.ts # 手写便利/发现工具
└── generated/ # 自动生成 - 请勿手动编辑
└── tools.ts # 131 个 ToolDescriptor 条目(名称、方法、路径、模式)
```
### 生成的工具与自定义工具
**生成的工具** (`src/generated/tools.ts`):TIE API 端点的逐一映射。只要 TIE API 规范发生变化,就重新生成:
```bash
npm run generate:tools
```
**自定义工具** (`src/custom-tools.ts`):手写的便利工具,组合多个 API 调用或提供发现/导航助手。这些工具在重新生成后仍然存在,并在服务器启动时与生成的工具合并。
当前自定义工具:
- **`get_topology`** - 返回 Infrastructure→Directory 层次结构树
- **`get_preferred_profile`** - 从首选项返回用户的默认配置文件
- **`query_ad_objects`** - 使用筛选表达式搜索所有 AD 对象,在内存中运行缓存快照(参见 [AD 对象搜索](#ad对象搜索))
- **`get_ad_object`** - 按 DN、SID 或 SAM 账户名称查找单个 AD 对象
自定义工具遵循相同的 `CustomTool` 接口(`{name, description, category, safety, inputSchema, handler}`),并与生成的工具一起调度。
## 可用工具
服务器总共公开 **139 个工具**:
- **131 个生成的工具** 来自 `src/generated/tools.ts`(每个 TIE API 端点一个)
- **8 个自定义工具** 来自 `src/custom-tools.ts`(`get_topology`、`get_preferred_profile`、`query_ad_objects`、`get_ad_object`、`get_blast_radius`、`get_control_paths`、`get_asset_exposure`、`get_tier0`)
参见 [TOOL_NAMING_CONVENTION.md](docs/TOOL_NAMING_CONVENTION.md),了解命名方案和(历史)88 端点参考列表。
### 发现工具
```typescript
// 获取用户的首选配置文件(来自首选项)
get_preferred_profile()
// 返回:{ preferredProfileId: 2, preferredProfileName: "Contoso" }
// 获取基础设施→目录拓扑树
get_topology()
// 返回:[{ id, name, directories: [{id, name, status}] }]
```
### AD 对象搜索
`query_ad_objects` 和 `get_ad_object` 解决了真正的限制:TIE API 在 `/api/ad-objects` 上没有服务器端过滤器,因此查找属性的唯一方法是遍历整个目录(数万个对象)。这些工具执行一次**扫描**,构建一个类型化的内存快照,并重用它(TTL 缓存,默认为 10 分钟),因此后续搜索在几毫秒内运行,无需重新分页。
```typescript
// 过滤表达式:FIELD OP VALUE,以 AND / OR / NOT 和括号组合
query_ad_objects({
expression: '(admincount>0 AND useraccountcontrol:"NORMAL") OR badpwdcount>=5',
limit: 50, // 可选;0 = 全部。总匹配计数始终报告。
})
// 按 DN、SID 或 SAM 账户名称查找单个 AD 对象。
get_ad_object({ distinguishedName: "CN=Domain Admins,CN=Users,DC=alsid,DC=corp" })
get_ad_object({ sid: "S-1-5-21-...-512" })
get_ad_object({ samAccountName: "Domain Admins" })
```
**运算符**
| 运算符 | 含义 |
| --- | --- |
| `=` `!=` | 等于 / 不等于 —— 数值时双方均为数值,否则大小写不敏感的字符串 |
| `>` `>=` `<` `<=` | 排序 —— 数值时双方均为数值,否则词法(大小写不敏感) |
| `:` | 包含 —— 字符串的子字符串,多值属性的成员资格 |
| `&` `\|` | 数值位测试:`(attr OP value) != 0` |
| `AND` `OR` `NOT` | 布尔组合器;优先级 `NOT` > `AND` > `OR`,使用 `()` 覆盖 |
**字段** 是属性名称(不区分大小写),例如 `admincount`、`cn`、`member`、`useraccountcontrol`、`isbreached`,以及标识字段 `type`(`LDAP`/`SYSVOL`)、`directoryId`、`objectId`、`id`。引用包含空格的值:`cn:"Domain Admins"`。多值属性如果 **任何** 值匹配则匹配;缺少的属性永远不会匹配。传递 `refresh: true` 以强制进行新鲜扫描。
> **注意:** `useraccountcontrol` 以解码的标志名称公开(`"NORMAL DONT_EXPIRE"`),而不是原始整数位掩码 —— 使用 `:` 包含运算符测试标志(例如 `useraccountcontrol:"DONT_EXPIRE"`),而不是 `&`。
### 生成的工具示例
```typescript
// 获取系统信息
get_about()
// 列出配置文件的攻击
list_attacks({ profileId: "profile-123" })
// 搜索事件
search_events({
query: { /* 搜索条件 */ }
})
// 创建基础设施
create_infrastructure({
name: "Production",
description: "生产环境"
})
// 更新偏差
update_deviance({
infrastructureId: "infra-1",
directoryId: "dir-1",
devianceId: "dev-1",
data: { status: "resolved" }
})
```
## 作为共享服务托管
此服务器当前使用 **stdio** 传输:MCP 客户端将其作为本地子进程启动。那种模式适用于每用户桌面工具,因此分发方式是通过 npm/npx(或普通 Docker 镜像),而不是 Docker Compose。
要改为运行一个**集中式**实例以供多个远程客户端连接,服务器需要切换到 MCP 的可流式 **HTTP/SSE** 传输(用 `StdioServerTransport` 替换 `src/index.ts` 中的 HTTP 服务器传输,并添加侦听端口)。此时,它成为一个独立的网络服务,Docker —— 可选地使用 Compose 在反向代理后面提供 TLS 和身份验证 —— 成为合适的部署方式。这是刻意的单独更改,今天尚未实现。
## API 文档
- [API 端点](docs/API_ENDPOINTS.md)
- [工具命名约定](docs/TOOL_NAMING_CONVENTION.md)
- [身份验证](docs/AUTHENTICATION.md)
- [架构选项](docs/ARCHITECTURE_OPTIONS.md)
## 许可证
MIT —— 参见 [LICENSE](LICENSE)。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器