fieldeffect-mcp
by MSPbotsAI
README.md
# fieldeffect-mcp
MCP server for **Field Effect** (Covalence MDR — managed detection &
response). Exposes the Field Effect MDR Portal REST API's organization,
endpoint device, and Active Response reporting endpoints as MCP tools.
> Naming note: MSPbots' own integration is registered as "Field Effect"
> (`subjectCode=FIELDEFFECT`); the vendor's product name is "Covalence" /
> "Field Effect MDR". This MCP covers exactly the 4 GET endpoints MSPbots
> itself has configured — see **Known Gaps** below for why the scope stops
> there.
## Overview
- Stateless HTTP service. No credentials are ever persisted — each request
supplies its own API key via a header, used only for the lifetime of
that single request.
- Supports concurrent requests; per-request credential isolation is done via
Python `contextvars`, not a global/shared client instance.
- Entry points: `POST /mcp` (MCP protocol) and `GET /health` (health check).
- Default port: `8080` (configurable via `MCP_HTTP_PORT`).
## Authentication
Field Effect authenticates with a static **API key**, created in the API
section of the Field Effect MDR Portal. MSPbots' own integration convention
sends this key as an `Authorization: Bearer <api-key>` header, and this
server forwards it exactly that way.
### HEADER 授权参数说明
| Header | 类型 | 是否必填 | 默认值 | 枚举值 | 字段描述 | Example |
|---|---|---|---|---|---|---|
| `X-FieldEffect-Api-Key` | string | 是 | 无 | 无 | Field Effect MDR Portal API Key,转发为上游 `Authorization: Bearer <key>` 请求头 | `a1b2c3d4e5f6...` |
Missing the header returns `401`:
```json
{
"error": "Missing credentials",
"message": "This server requires the X-FieldEffect-Api-Key header",
"required_headers": ["X-FieldEffect-Api-Key"],
"optional_headers": []
}
```
## Environment Variables
| Variable | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| `MCP_HTTP_PORT` | int | 否 | `8080` | HTTP 监听端口 |
| `MCP_HTTP_HOST` | string | 否 | `0.0.0.0` | HTTP 监听地址 |
| `FIELDEFFECT_BASE_URL` | string | 否 | `https://services.fieldeffect.net/v1` | Field Effect API 基础 URL |
## MCP Endpoint
- `POST /mcp` — MCP protocol (streamable HTTP transport)
- `GET /health` — health check, returns `{"status": "ok"}` (pure local probe, does not depend on the Field Effect API)
## Tool List
All 4 tools are plain `GET` calls, matching exactly how MSPbots itself
calls this integration today. All are read-only (`readOnlyHint=True`).
| Tool | 功能 | 参数 |
|---|---|---|
| `fieldeffect_get_organizations` | 列出该 API Key 可见的所有组织(客户) | 无 |
| `fieldeffect_get_endpoint_devices` | 列出所有端点设备(含风险等级/分数),分页返回 | `page`(可选), `per_page`(可选,默认 50,硬上限 200,见 Known Gaps) |
| `fieldeffect_get_endpoint_device_antivirus_details` | 获取指定端点设备的杀毒软件状态详情 | `device_id`(必填) |
| `fieldeffect_get_active_response_actions` | 列出 Active Response 响应事件(如设备隔离),分页返回 | `page`(可选), `per_page`(可选,默认 50,硬上限 200,见 Known Gaps) |
工具返回值统一为紧凑 JSON 字符串(`ensure_ascii=False`,无 `indent`),单次返回超过 20,000
字符时会自动截断最大的列表字段并附带 `truncated`/`original_count` 标记。出错时返回结构化
错误信封 `{"error": {"code", "message", "retryable"}}`(`code` 取自固定词汇表:
`not_configured` / `unauthorized` / `not_found` / `invalid_argument` / `rate_limited` /
`upstream_error`),不抛异常。
## 测试示例
```bash
# Health check
curl -s http://localhost:8080/health
# Call a tool via the MCP protocol (streamable HTTP) — requires an
# initialize handshake first per the MCP spec; abbreviated example below
# shows the tool-call request body only:
curl -s -X POST http://localhost:8080/mcp \
-H "X-FieldEffect-Api-Key: <your-fieldeffect-api-key>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: <session-id-from-initialize>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "fieldeffect_get_organizations",
"arguments": {}
}
}'
```
**Live-verified** (2026-07-29) against a real MDR Portal API key: all 4
tools were called end-to-end through this running server —
`fieldeffect_get_organizations` returned 41 real organizations,
`fieldeffect_get_endpoint_devices` returned a paginated list (1719 devices
total across 18 pages), `fieldeffect_get_endpoint_device_antivirus_details`
returned successfully (204, no AV data for that particular device — not an
error), and `fieldeffect_get_active_response_actions` returned 200.
## API Reference
- Overview (public, no login required): https://support.fieldeffect.com/en/support/solutions/articles/16000206018-field-effect-apis-overview
- The full interactive Swagger/OpenAPI documentation is only accessible
from inside the MDR Portal's own Support section — it requires being
logged into a Field Effect MDR Portal account, not just having an API
key. No public Swagger/OpenAPI spec was found, and probing common
spec paths (`/swagger.json`, `/v1/openapi.json`, `/v1/api-docs`, etc.)
directly against `services.fieldeffect.net` all returned `404`.
## Known Gaps
- **Scope is exactly MSPbots' 4 configured endpoints, not the vendor's
full API surface** — same situation as `bvoip-mcp`/`contactscience-mcp`/
`dropsuite-mcp` earlier in this program: the vendor's fuller API
reference requires a portal login this session doesn't have, so there
was no larger accessible spec to weigh a broader scope against.
- **`page`/`per_page` parameters on `get_endpoint_devices` and
`get_active_response_actions` are inferred, not confirmed** — the vendor
doesn't publish these endpoints' accepted query parameters anywhere
accessible. They were added because the live response shape
(`{"items": [...], "page": 1, "per_page": 100, "total": ..., "pages": ...,
"has_next": ..., "has_prev": ...}`) strongly suggests a standard
page/per_page pagination scheme, but this has not been verified by
actually passing those parameters and confirming a changed result.
Because the vendor's own real per-page maximum is unconfirmed, this
server does not defer to it and instead applies the Vendor MCP SOP's own
fallback ceiling: `per_page` defaults to 50 when omitted and is clamped
to 200 server-side regardless of what's requested.
- Response field shapes are whatever the live API returns — not
independently verified against a schema, since none is publicly
available.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues