@chkp/harmony-email-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": ["../../.eslintrc.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "overrides": [
5
+ {
6
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
+ "rules": {}
8
+ },
9
+ {
10
+ "files": ["*.ts", "*.tsx"],
11
+ "rules": {}
12
+ },
13
+ {
14
+ "files": ["*.js", "*.jsx"],
15
+ "rules": {}
16
+ }
17
+ ]
18
+ }
package/.gitattributes ADDED
@@ -0,0 +1,3 @@
1
+ # MIME messages are CRLF by definition; normalising line endings would change
2
+ # what the parser sees and make the structure tests depend on checkout settings.
3
+ *.eml -text
package/.prettierrc ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "trailingComma": "es5",
3
+ "tabWidth": 4,
4
+ "semi": true,
5
+ "singleQuote": true
6
+ }
package/README.md ADDED
@@ -0,0 +1,243 @@
1
+ # Check Point Harmony Email & Collaboration MCP
2
+
3
+ ## What is MCP?
4
+
5
+ Model Context Protocol (MCP) servers expose a structured, machine-readable API for your enterprise data, designed for AI-powered automation, copilots and decision engines. By delivering a clear, contextual slice of your security environment, MCP lets you query, analyze and act on complex systems without building custom SDKs or parsing raw exports.
6
+
7
+ ## Why MCP for Harmony Email & Collaboration?
8
+
9
+ Harmony Email & Collaboration (HEC) protects email and the SaaS apps around it. Answering an everyday question - "did phishing go up this week?", "why was this message quarantined?", "who is waiting on a restore?" - usually means several console screens and a working knowledge of which engine produced which verdict.
10
+
11
+ This server puts that behind an MCP interface, with a SOC-analyst persona and a glossary so the assistant speaks HEC's own vocabulary. Broad questions are answered by server-side aggregators that return counts rather than message bodies, so a month-wide question stays cheap and keeps personal data out of the transcript. Remediation is available, and every remediation tool previews before it acts.
12
+
13
+ ## Features
14
+
15
+ ### 21 tools
16
+
17
+ **Investigate a single message**
18
+
19
+ 1. **get_entity** - the structured record: per-engine verdicts, restore flags, action history, available actions
20
+ 2. **read_email_headers** - key headers plus every `X-CLOUD-SEC-AV-*` the pipeline stamped on, and the verbatim block
21
+ 3. **read_email_body** - decoded body, every link target with its anchor text, attachment names
22
+ 4. **read_email_structure** - the MIME tree, with an optional still-encoded sample of one part
23
+ 5. **download_entity** - the raw `.eml`, inline or via a short-lived presigned URL
24
+
25
+ **Search and summarize**
26
+
27
+ 6. **query_events** - security events by window, type, state, severity, SaaS or free text
28
+ 7. **query_entities** - emails and files by SaaS and window, with server-side predicates
29
+ 8. **summarize_events** - counts grouped by type, severity, state, SaaS or day, with previous-window comparison
30
+ 9. **summarize_entities** - counts grouped by verdict, restore state, remediation mode, entity type, SaaS or day
31
+ 10. **get_event** - one event by id
32
+ 11. **list_scopes** - which tenant this server is bound to
33
+
34
+ **Restore requests and remediation**
35
+
36
+ 12. **action_quarantine** / 13. **action_quarantine_batch**
37
+ 13. **action_restore** / 15. **action_restore_batch**
38
+ 14. **action_deny_restore** / 17. **action_deny_restore_batch**
39
+ 15. **report_misclassification** - feed back a wrong verdict, false positive or false negative
40
+ 16. **get_task** - poll the background job a bulk action created
41
+
42
+ **Anti-Phishing exceptions**
43
+
44
+ 20. **list_ap_exceptions** - the whitelist, blacklist or spam whitelist
45
+ 21. **get_ap_exception** - one entry by id
46
+
47
+ ### 4 prompts and a glossary
48
+
49
+ - **analyst_persona** - the voice, vocabulary and refusal stances the assistant should adopt
50
+ - **security_activity_summary** - "did phishing increase this week?", "recap the last 24 hours"
51
+ - **restore_request_report** - the pending queue, resolved counts, or the manual-vs-automatic trend
52
+ - **single_email_investigation** - explain one detection end to end
53
+ - **hec://glossary** - 27 canonical terms: entity vs event vs verdict, the five engines, event types, states and severities, the restore lifecycle
54
+
55
+ ## Example Use Cases
56
+
57
+ ### Daily activity recap
58
+
59
+ **"Summarize email security activity over the last 24 hours"**
60
+ One `summarize_events` call returns counts by type, severity and day. Nothing but numbers reaches the model.
61
+
62
+ ### Trend question
63
+
64
+ **"Did phishing increase this week?"**
65
+ `summarize_events` with `compare_to_previous_window` returns both windows in a single call.
66
+
67
+ ### Single-message investigation
68
+
69
+ **"Why was this email quarantined?"**
70
+ `get_entity` gives the combined verdict, which engines flagged it and what was already done. `read_email_headers` shows the SPF, DKIM and DMARC results; `read_email_body` shows where the links actually pointed.
71
+
72
+ ### Restore-request triage
73
+
74
+ **"Show me all pending restore requests"**
75
+ `summarize_entities` grouped by `restore_state`, filtered to requested-but-unresolved, with a sample of rows to render.
76
+
77
+ ### Remediation with a preview
78
+
79
+ **"Quarantine this message"**
80
+ The first call is a dry run: it echoes the exact payload and changes nothing. Only after explicit go-ahead does a second call with `confirm: true` submit the action and return a `task_id`.
81
+
82
+ ## Configuration
83
+
84
+ Every setting can be given as a CLI flag, an environment variable, or an HTTP request header. `src/server-config.json` is the authoritative list.
85
+
86
+ | Setting | Flag | Environment variable | Required |
87
+ | ------------------------- | -------------------------- | ------------------------ | -------- |
88
+ | Tenant domain | `--hec-domain` | `HEC_DOMAIN` | yes |
89
+ | API client id | `--hec-client-id` | `HEC_CLIENT_ID` | yes |
90
+ | API secret | `--hec-secret` | `HEC_SECRET` | yes |
91
+ | Auth flow override | `--hec-auth-method` | `HEC_AUTH_METHOD` | no |
92
+ | Region override | `--hec-region` | `HEC_REGION` | no |
93
+ | Tenant scope override | `--hec-scope` | `HEC_SCOPE` | no |
94
+ | Request timeout, seconds | `--hec-request-timeout` | `HEC_REQUEST_TIMEOUT` | no (30) |
95
+ | Max retries | `--hec-max-retries` | `HEC_MAX_RETRIES` | no (3) |
96
+ | Backoff base, seconds | `--hec-retry-base-seconds` | `HEC_RETRY_BASE_SECONDS` | no (1) |
97
+ | Max concurrent requests | `--hec-max-concurrency` | `HEC_MAX_CONCURRENCY` | no (10) |
98
+ | Batch action cap | `--hec-action-batch-limit` | `HEC_ACTION_BATCH_LIMIT` | no (50) |
99
+
100
+ The equivalent `SMARTAPI_MCP_*` environment variable names are also accepted.
101
+
102
+ ### Credentials
103
+
104
+ - **Check Point tenants** (`*.checkpointcloudsec.com`): the Infinity Portal API key. `HEC_CLIENT_ID` is its `clientId`, `HEC_SECRET` its `accessKey`. Create one under Global Settings, API Keys.
105
+ - **Avanan tenants** (`*.avanan.net`): the SmartAPI `appId` and `secretKey`.
106
+
107
+ Region, tenant scope and API gateway are derived from `HEC_DOMAIN` automatically, by resolving the tenant's farm over DNS. The farm selects the gateway, not the AWS region: QA and production farms share AWS regions, but each environment has its own gateway, so a region-keyed lookup would send a QA tenant to the production host.
108
+
109
+ Resolution recognises the farms listed in `FARM_TO_REGION` (`src/core/resolver.ts`). A tenant on any other farm fails with a `ConfigError` naming the farms it knows; onboarding that farm means adding it to the table and releasing. There is no gateway URL override, by design: the gateway is always one of the hosts this package ships, so no request can point the server at an arbitrary host. Setting `HEC_REGION`, `HEC_SCOPE` and `HEC_AUTH_METHOD` together skips DNS resolution, still deriving the gateway from the shipped table. `HEC_AUTH_METHOD` also forces a flow when the credentials do not match the domain type, which is the usual case when Avanan-style credentials are issued against a Check Point tenant for testing.
110
+
111
+ ### Verifying the configuration
112
+
113
+ ```bash
114
+ # credentials, DNS resolution and the auth handshake
115
+ npx @chkp/harmony-email-mcp --check
116
+
117
+ # additionally exercise every read-only endpoint and report per step
118
+ npx @chkp/harmony-email-mcp --check --all
119
+ ```
120
+
121
+ Both write their JSON report to stderr, since stdout is reserved for the MCP stdio channel. `--check --all` reports each endpoint as `ok`, `degraded` (upstream is unhappy, but the client is fine), `fail` or `skipped`, and only `fail` sets a non-zero exit code.
122
+
123
+ ## Client Configuration
124
+
125
+ ### Prerequisites
126
+
127
+ Install Node.js 20+ from [nodejs.org](https://nodejs.org/en/download/) if required, then verify with `node -v`.
128
+
129
+ ### Supported Clients
130
+
131
+ This server has been tested with Claude Desktop, Cursor, GitHub Copilot, and Windsurf clients.
132
+ It is expected to work with any MCP client that supports the Model Context Protocol.
133
+
134
+ ### Configuring the Claude Desktop App
135
+
136
+ #### Using a Bundled MCPB (formerly DXT)
137
+
138
+ 1. Download the MCPB file: **[📥 harmony-email.mcpb](https://github.com/CheckPointSW/mcp-servers/releases/latest/download/harmony-email.mcpb)**
139
+ 2. Open Claude Desktop App → Settings → Extensions
140
+ 3. Drag the MCPB file and configure per the instructions.
141
+
142
+ #### Or Configure Manually
143
+
144
+ ```json
145
+ {
146
+ "mcpServers": {
147
+ "harmony-email": {
148
+ "command": "npx",
149
+ "args": ["-y", "@chkp/harmony-email-mcp"],
150
+ "env": {
151
+ "HEC_DOMAIN": "your-tenant.avanan.net",
152
+ "HEC_CLIENT_ID": "your-client-id",
153
+ "HEC_SECRET": "your-secret"
154
+ }
155
+ }
156
+ }
157
+ }
158
+ ```
159
+
160
+ ### VS Code
161
+
162
+ ```json
163
+ {
164
+ "mcp": {
165
+ "servers": {
166
+ "harmony-email": {
167
+ "command": "npx",
168
+ "args": ["-y", "@chkp/harmony-email-mcp"],
169
+ "env": {
170
+ "HEC_DOMAIN": "your-tenant.avanan.net",
171
+ "HEC_CLIENT_ID": "your-client-id",
172
+ "HEC_SECRET": "your-secret"
173
+ }
174
+ }
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ Cursor and Windsurf use the same shape.
181
+
182
+ ## HTTP Transport
183
+
184
+ The server also speaks Streamable HTTP, which lets one process serve several tenants:
185
+
186
+ ```bash
187
+ npx @chkp/harmony-email-mcp --transport http --transport-port 3010
188
+ ```
189
+
190
+ The endpoint is `http://localhost:3010/mcp`; `GET /health` reports the active session count. Each session supplies its own tenant through headers:
191
+
192
+ ```
193
+ Hec-Domain: your-tenant.avanan.net
194
+ Hec-Client-Id: your-client-id
195
+ Hec-Secret: your-secret
196
+ ```
197
+
198
+ **Send those headers on every request, not only on `initialize`.** Session settings are rebuilt from each request's headers, and a request that omits them fails with a configuration error. There is deliberately no fallback to the server process's own `HEC_*` environment: a client must never be able to act as whichever tenant the operator configured.
199
+
200
+ VS Code:
201
+
202
+ ```json
203
+ "harmony-email": {
204
+ "url": "http://localhost:3010/mcp",
205
+ "type": "http",
206
+ "headers": {
207
+ "Hec-Domain": "your-tenant.avanan.net",
208
+ "Hec-Client-Id": "your-client-id",
209
+ "Hec-Secret": "your-secret"
210
+ }
211
+ }
212
+ ```
213
+
214
+ ## Development
215
+
216
+ ```bash
217
+ npm run build # esbuild bundle to dist/
218
+ npm run build:tsc # plain tsc, for chasing type errors
219
+ npm test # jest
220
+ npm run dev # tsc --watch
221
+ ```
222
+
223
+ ## ⚠️ Security Notice
224
+
225
+ **Credentials.** The client id and secret authenticate as your API key against a real tenant. Supply them through environment variables, a secret manager, or per-request headers. Never hardcode them, never commit them, and never paste them into a chat. Under HTTP transport a session is built from its own request headers alone, with no fallback to the server's environment, so a header-less request fails rather than borrowing the operator's tenant.
226
+
227
+ **Gateway.** The API gateway is always one of the hosts this package ships, chosen from the tenant's farm. No flag, environment variable or header can point the server at another host.
228
+
229
+ **Least privilege.** This server can read message content and can quarantine, restore and deny-restore mail. Issue it an API key scoped to the smallest set of permissions your use case needs.
230
+
231
+ **Customer data.** `get_entity`, the `read_email_*` tools and `download_entity` return message content: subjects, addresses, headers, links and attachment metadata. Anything a tool returns is passed to your MCP client and, from there, to whichever model provider you have configured. Review that posture before pointing this at a production tenant. The two `summarize_*` tools are the counts-only path and return no message content at all: `summarize_entities` with `sample_limit` adds entity ids, timestamps, restore state and the scalar fields of the combined verdict, and still no subject, addresses, headers or attachment names.
232
+
233
+ **Destructive actions.** Quarantine, restore, deny-restore and misclassification reporting all default to a dry run that makes no upstream call. They act only when called again with `confirm: true`. Batch variants are capped (default 50) and an oversized batch is rejected outright, never silently truncated.
234
+
235
+ **No duplicated actions.** Read-only calls retry on 408, 429 and 5xx. State-changing calls retry only on 429, which upstream returns instead of running the request; a 408 or 5xx there is ambiguous, since the action may already have been enqueued, so it fails once as `AmbiguousActionError` telling you to check the task or entity state rather than silently submitting it twice.
236
+
237
+ **Logging.** Credentials, tokens and message content are never written to the log. Structured log fields pass through a redactor that scrubs known-sensitive keys and anything JWT-shaped, and upstream response diagnostics are allowlisted rather than redacted: status, request ids and a few fixed headers only. An upstream error body can quote a filter or an address, so it rides on the error returned to the caller and never reaches a log line.
238
+
239
+ ## 📊 Telemetry and Privacy
240
+
241
+ **Anonymous Usage Statistics:** Check Point collects anonymous usage statistics to improve this MCP server. Only tool usage patterns and anonymous identifiers are collected (tool name, server version, machine id), no credentials, tenant data or tool arguments.
242
+
243
+ **Opt-Out:** Set `TELEMETRY_DISABLED=true` environment variable or use the `--no-telemetry` flag to disable telemetry collection.