@certynix/mcp 1.0.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.
Files changed (81) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +209 -0
  3. package/dist/index.d.ts +16 -0
  4. package/dist/index.js +119 -0
  5. package/dist/prompts/audit-report.d.ts +6 -0
  6. package/dist/prompts/audit-report.js +117 -0
  7. package/dist/prompts/security-review.d.ts +6 -0
  8. package/dist/prompts/security-review.js +95 -0
  9. package/dist/resources/alerts-active.d.ts +7 -0
  10. package/dist/resources/alerts-active.js +43 -0
  11. package/dist/resources/asset.d.ts +7 -0
  12. package/dist/resources/asset.js +61 -0
  13. package/dist/resources/organization-info.d.ts +8 -0
  14. package/dist/resources/organization-info.js +44 -0
  15. package/dist/resources/trust-score.d.ts +7 -0
  16. package/dist/resources/trust-score.js +46 -0
  17. package/dist/server.d.ts +13 -0
  18. package/dist/server.js +67 -0
  19. package/dist/tools/create-api-key.d.ts +3 -0
  20. package/dist/tools/create-api-key.js +37 -0
  21. package/dist/tools/create-webhook.d.ts +3 -0
  22. package/dist/tools/create-webhook.js +45 -0
  23. package/dist/tools/delete-asset.d.ts +3 -0
  24. package/dist/tools/delete-asset.js +48 -0
  25. package/dist/tools/get-asset.d.ts +3 -0
  26. package/dist/tools/get-asset.js +41 -0
  27. package/dist/tools/get-trust-score.d.ts +3 -0
  28. package/dist/tools/get-trust-score.js +43 -0
  29. package/dist/tools/list-alerts.d.ts +3 -0
  30. package/dist/tools/list-alerts.js +55 -0
  31. package/dist/tools/list-api-keys.d.ts +3 -0
  32. package/dist/tools/list-api-keys.js +51 -0
  33. package/dist/tools/list-assets.d.ts +3 -0
  34. package/dist/tools/list-assets.js +68 -0
  35. package/dist/tools/list-audit-logs.d.ts +3 -0
  36. package/dist/tools/list-audit-logs.js +62 -0
  37. package/dist/tools/list-webhooks.d.ts +3 -0
  38. package/dist/tools/list-webhooks.js +51 -0
  39. package/dist/tools/register-asset.d.ts +3 -0
  40. package/dist/tools/register-asset.js +87 -0
  41. package/dist/tools/revoke-api-key.d.ts +3 -0
  42. package/dist/tools/revoke-api-key.js +48 -0
  43. package/dist/tools/verify-asset.d.ts +3 -0
  44. package/dist/tools/verify-asset.js +53 -0
  45. package/dist/tools/verify-webhook-signature.d.ts +7 -0
  46. package/dist/tools/verify-webhook-signature.js +178 -0
  47. package/dist/utils/format.d.ts +10 -0
  48. package/dist/utils/format.js +18 -0
  49. package/dist/utils/mask.d.ts +14 -0
  50. package/dist/utils/mask.js +42 -0
  51. package/eslint.config.mjs +27 -0
  52. package/package.json +38 -0
  53. package/src/index.ts +149 -0
  54. package/src/prompts/audit-report.ts +126 -0
  55. package/src/prompts/security-review.ts +102 -0
  56. package/src/resources/alerts-active.ts +56 -0
  57. package/src/resources/asset.ts +79 -0
  58. package/src/resources/organization-info.ts +60 -0
  59. package/src/resources/trust-score.ts +59 -0
  60. package/src/server.ts +81 -0
  61. package/src/tools/create-api-key.ts +52 -0
  62. package/src/tools/create-webhook.ts +63 -0
  63. package/src/tools/delete-asset.ts +63 -0
  64. package/src/tools/get-asset.ts +53 -0
  65. package/src/tools/get-trust-score.ts +57 -0
  66. package/src/tools/list-alerts.ts +69 -0
  67. package/src/tools/list-api-keys.ts +63 -0
  68. package/src/tools/list-assets.ts +80 -0
  69. package/src/tools/list-audit-logs.ts +76 -0
  70. package/src/tools/list-webhooks.ts +63 -0
  71. package/src/tools/register-asset.ts +103 -0
  72. package/src/tools/revoke-api-key.ts +65 -0
  73. package/src/tools/verify-asset.ts +66 -0
  74. package/src/tools/verify-webhook-signature.ts +232 -0
  75. package/src/utils/format.ts +20 -0
  76. package/src/utils/mask.ts +41 -0
  77. package/tests/unit/tools/register-asset.test.ts +190 -0
  78. package/tests/unit/tools/verify-webhook-signature.test.ts +250 -0
  79. package/tests/unit/utils/mask.test.ts +129 -0
  80. package/tsconfig.json +17 -0
  81. package/vitest.config.ts +19 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@certynix/mcp` will be documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [1.0.0] - 2026-03-15
11
+
12
+ ### Added
13
+
14
+ - Initial release of `@certynix/mcp` — Official Certynix MCP Server
15
+ - **14 Tools:**
16
+ - `register_asset` — Register digital assets via SHA-256 hash, URL, or base64 file
17
+ - `verify_asset` — Public asset authenticity verification (no quota consumed)
18
+ - `list_assets` — List organization assets with filters and cursor-based pagination
19
+ - `get_asset` — Fetch a specific asset by ID with full metadata
20
+ - `delete_asset` — Soft delete an asset (requires `confirm: true`)
21
+ - `list_alerts` — List Exposure Alerts with severity and resolved filters
22
+ - `get_trust_score` — Fetch Trust Score V2 with all 4 pillar components and penalties
23
+ - `list_audit_logs` — List audit trail with action type and date range filters
24
+ - `create_api_key` — Create a new API Key (full key shown only once)
25
+ - `list_api_keys` — List API Keys (prefix only, never full value)
26
+ - `revoke_api_key` — Revoke an API Key immediately (requires `confirm: true`)
27
+ - `create_webhook` — Create webhook endpoint (signing_secret shown only once)
28
+ - `list_webhooks` — List webhooks (signing_secret never returned)
29
+ - `verify_webhook_signature` — Local HMAC-SHA256 webhook signature verification
30
+ - **4 Resources:**
31
+ - `certynix://organization/info` — Authenticated organization info
32
+ - `certynix://organization/trust-score` — Trust Score V2 with components and penalties
33
+ - `certynix://assets/{asset_id}` — Full asset metadata (URI template)
34
+ - `certynix://alerts/active` — Active (unresolved) Exposure Alerts
35
+ - **2 Prompts:**
36
+ - `certynix_audit_report` — Structured audit report for a specified period
37
+ - `certynix_security_review` — Complete organization security analysis with recommendations
38
+ - **Transports:**
39
+ - `stdio` transport — for Claude Desktop, Cursor, Windsurf and local tools
40
+ - `sse` transport — for remote agents, cloud platforms and web integrations
41
+ - **Security features:**
42
+ - Automatic sandbox detection via API key prefix (`cnx_test_sk_*`)
43
+ - API key masking (`maskApiKey()`) in all logs and error messages
44
+ - `sanitizeForOutput()` removes sensitive fields recursively from all outputs
45
+ - Destructive action confirmation (`confirm: true` required for `delete_asset` and `revoke_api_key`)
46
+ - Local HMAC-SHA256 webhook signature verification with constant-time comparison
47
+ - Anti-replay protection: timestamps older than 5 minutes are rejected
48
+ - Future timestamp detection: timestamps > 60s in the future are rejected
49
+ - `organization_id` never accepted as a tool parameter (always resolved via API Key)
package/README.md ADDED
@@ -0,0 +1,209 @@
1
+ # @certynix/mcp — Official Certynix MCP Server
2
+
3
+ > **Expose the Certynix Trust Infrastructure to AI agents via Model Context Protocol.**
4
+ > Connect Claude Desktop, Cursor, Windsurf, LangChain, CrewAI, and any MCP-compatible system to the Certynix API.
5
+
6
+ ---
7
+
8
+ ## What is this?
9
+
10
+ `@certynix/mcp` is an MCP (Model Context Protocol) server that acts as a bridge between AI agents and the Certynix API. It exposes the Trust Infrastructure capabilities as **tools**, **resources**, and **prompts** that any MCP client can consume.
11
+
12
+ **Use cases:**
13
+
14
+ - AI agent that automatically registers assets in a CI/CD pipeline
15
+ - Claude verifying the authenticity of a contract before analyzing it
16
+ - Agent monitoring Exposure Alerts and taking corrective actions
17
+ - Audit automation: audit log listing and analysis via prompt
18
+ - Document approval workflow integration
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install -g @certynix/mcp
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Configuration
31
+
32
+ ### Environment variables
33
+
34
+ ```bash
35
+ # REQUIRED
36
+ CERTYNIX_API_KEY=cnx_live_sk_... # Production key
37
+ # or
38
+ CERTYNIX_API_KEY=cnx_test_sk_... # Sandbox key (auto-detected)
39
+
40
+ # OPTIONAL
41
+ CERTYNIX_BASE_URL=https://api.certynix.com # Auto-detected from key prefix
42
+ CERTYNIX_TIMEOUT=30000 # Request timeout in ms (default: 30000)
43
+ MCP_TRANSPORT=stdio # stdio | sse (default: stdio)
44
+ MCP_PORT=3100 # SSE port (default: 3100, sse only)
45
+ MCP_LOG_LEVEL=info # debug | info | warn | error
46
+ ```
47
+
48
+ ### Sandbox mode
49
+
50
+ API keys prefixed with `cnx_test_sk_` automatically connect to the sandbox environment (`https://sandbox.certynix.com`). No configuration needed.
51
+
52
+ ---
53
+
54
+ ## Claude Desktop
55
+
56
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "certynix": {
62
+ "command": "npx",
63
+ "args": ["-y", "@certynix/mcp"],
64
+ "env": {
65
+ "CERTYNIX_API_KEY": "cnx_live_sk_..."
66
+ }
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ Or if installed globally:
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "certynix": {
78
+ "command": "certynix-mcp",
79
+ "env": {
80
+ "CERTYNIX_API_KEY": "cnx_live_sk_..."
81
+ }
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Cursor / Windsurf
90
+
91
+ Add to `~/.cursor/mcp.json` (Cursor) or the equivalent Windsurf config:
92
+
93
+ ```json
94
+ {
95
+ "mcpServers": {
96
+ "certynix": {
97
+ "command": "certynix-mcp",
98
+ "env": {
99
+ "CERTYNIX_API_KEY": "cnx_live_sk_..."
100
+ }
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ## SSE Transport (remote agents)
109
+
110
+ ```bash
111
+ # Start SSE server
112
+ CERTYNIX_API_KEY=cnx_live_sk_... MCP_TRANSPORT=sse MCP_PORT=3100 certynix-mcp
113
+
114
+ # Endpoints:
115
+ # SSE: http://localhost:3100/sse
116
+ # Messages: http://localhost:3100/message
117
+ # Health check: http://localhost:3100/health
118
+ ```
119
+
120
+ ### Docker
121
+
122
+ ```dockerfile
123
+ FROM node:20-alpine
124
+ RUN npm install -g @certynix/mcp
125
+ ENV MCP_TRANSPORT=sse
126
+ ENV MCP_PORT=3100
127
+ EXPOSE 3100
128
+ CMD ["certynix-mcp"]
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Tools (14)
134
+
135
+ | Tool | Description |
136
+ |------|-------------|
137
+ | `register_asset` | Register a digital asset via SHA-256 hash, public URL, or base64 file content |
138
+ | `verify_asset` | Publicly verify asset authenticity — no auth required, no quota consumed |
139
+ | `list_assets` | List organization assets with status and date filters, cursor pagination |
140
+ | `get_asset` | Fetch a specific asset by ID with full metadata and event history |
141
+ | `delete_asset` | Soft delete an asset — irreversible, requires `confirm: true` |
142
+ | `list_alerts` | List Exposure Alerts with severity and resolved status filters |
143
+ | `get_trust_score` | Get Trust Score V2: score 0-100, 4-pillar breakdown, active penalties |
144
+ | `list_audit_logs` | List complete audit trail with action type and date range filters |
145
+ | `create_api_key` | Create a new API Key — full key shown only once, store immediately |
146
+ | `list_api_keys` | List API Keys — prefix only, full key never returned |
147
+ | `revoke_api_key` | Revoke an API Key immediately — irreversible, requires `confirm: true` |
148
+ | `create_webhook` | Create a webhook endpoint — signing_secret shown only at creation |
149
+ | `list_webhooks` | List webhooks — signing_secret never returned in listings |
150
+ | `verify_webhook_signature` | Local HMAC-SHA256 webhook signature verification (no API call) |
151
+
152
+ ### Usage examples with Claude
153
+
154
+ ```
155
+ "Register this document on Certynix:
156
+ SHA-256 hash: a3f4b2c1d8e9f0123456789abcdef0123456789abcdef0123456789abcdef01
157
+ filename: service-contract-2026.pdf"
158
+
159
+ "Verify if the file with hash e3b0c44298fc1c149afbf4c8996fb924...
160
+ has been certified by anyone"
161
+
162
+ "List the last 10 high-severity Exposure Alerts"
163
+
164
+ "Generate a security review of our organization"
165
+
166
+ "Create an API Key called 'CI/CD Pipeline - GitHub Actions'"
167
+
168
+ "Show me all active Exposure Alerts"
169
+
170
+ "What is our current Trust Score?"
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Resources (4)
176
+
177
+ | URI | Description |
178
+ |-----|-------------|
179
+ | `certynix://organization/info` | Authenticated organization info: name, plan, Trust Score |
180
+ | `certynix://organization/trust-score` | Trust Score V2 with component breakdown and active penalties |
181
+ | `certynix://assets/{asset_id}` | Full asset metadata by ID (URI template) |
182
+ | `certynix://alerts/active` | Active (unresolved) Exposure Alerts |
183
+
184
+ ---
185
+
186
+ ## Prompts (2)
187
+
188
+ | Prompt | Description |
189
+ |--------|-------------|
190
+ | `certynix_audit_report` | Generate a structured audit report for a period (`last_7_days`, `last_30_days`, `custom`) |
191
+ | `certynix_security_review` | Complete organization security analysis: Trust Score, penalties, API Keys, alerts, recommendations |
192
+
193
+ ---
194
+
195
+ ## Security
196
+
197
+ - **API Key never exposed**: masked in all logs as `cnx_live_sk_***`
198
+ - **Sensitive fields sanitized**: `api_key`, `secret`, `token`, `password`, `signing_secret` replaced with `***` in all outputs
199
+ - **Destructive actions require confirmation**: `delete_asset` and `revoke_api_key` require `confirm: true`
200
+ - **`organization_id` never accepted as parameter**: always resolved server-side via API Key
201
+ - **Webhook verification is constant-time**: prevents HMAC timing attacks
202
+ - **Anti-replay protection**: webhook timestamps older than 5 minutes are rejected
203
+ - **Signing secret shown only once**: at webhook creation — never returned in listings
204
+
205
+ ---
206
+
207
+ ## Changelog
208
+
209
+ See [CHANGELOG.md](./CHANGELOG.md) for release history.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Certynix MCP Server — Entrypoint
4
+ *
5
+ * Expõe a Certynix Trust Infrastructure para agentes de IA via Model Context Protocol.
6
+ * Suporta transporte stdio (Claude Desktop) e SSE (integrações remotas).
7
+ *
8
+ * Variáveis de ambiente:
9
+ * CERTYNIX_API_KEY — obrigatório (cnx_live_sk_* ou cnx_test_sk_*)
10
+ * CERTYNIX_BASE_URL — opcional (auto-detectado via prefixo da key)
11
+ * CERTYNIX_TIMEOUT — opcional (ms, padrão: 30000)
12
+ * MCP_TRANSPORT — opcional (stdio | sse, padrão: stdio)
13
+ * MCP_PORT — opcional (apenas para sse, padrão: 3100)
14
+ * MCP_LOG_LEVEL — opcional (debug | info | warn | error, padrão: info)
15
+ */
16
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Certynix MCP Server — Entrypoint
4
+ *
5
+ * Expõe a Certynix Trust Infrastructure para agentes de IA via Model Context Protocol.
6
+ * Suporta transporte stdio (Claude Desktop) e SSE (integrações remotas).
7
+ *
8
+ * Variáveis de ambiente:
9
+ * CERTYNIX_API_KEY — obrigatório (cnx_live_sk_* ou cnx_test_sk_*)
10
+ * CERTYNIX_BASE_URL — opcional (auto-detectado via prefixo da key)
11
+ * CERTYNIX_TIMEOUT — opcional (ms, padrão: 30000)
12
+ * MCP_TRANSPORT — opcional (stdio | sse, padrão: stdio)
13
+ * MCP_PORT — opcional (apenas para sse, padrão: 3100)
14
+ * MCP_LOG_LEVEL — opcional (debug | info | warn | error, padrão: info)
15
+ */
16
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
17
+ import { createServer } from './server.js';
18
+ import { maskApiKey } from './utils/mask.js';
19
+ async function main() {
20
+ const apiKey = process.env['CERTYNIX_API_KEY'];
21
+ if (!apiKey) {
22
+ console.error('Error: CERTYNIX_API_KEY environment variable is required.\n' +
23
+ 'Set it to your Certynix API Key (cnx_live_sk_... for production, cnx_test_sk_... for sandbox).');
24
+ process.exit(1);
25
+ }
26
+ // Validar formato básico sem expor a key
27
+ if (!apiKey.startsWith('cnx_live_sk_') && !apiKey.startsWith('cnx_test_sk_')) {
28
+ console.error('Error: Invalid CERTYNIX_API_KEY format.\n' +
29
+ 'Expected: cnx_live_sk_... (production) or cnx_test_sk_... (sandbox).');
30
+ process.exit(1);
31
+ }
32
+ const transport = process.env['MCP_TRANSPORT'] ?? 'stdio';
33
+ const baseUrl = process.env['CERTYNIX_BASE_URL'];
34
+ const timeoutRaw = process.env['CERTYNIX_TIMEOUT'];
35
+ const timeout = timeoutRaw !== undefined ? parseInt(timeoutRaw, 10) : undefined;
36
+ const isSandbox = apiKey.startsWith('cnx_test_sk_');
37
+ let server;
38
+ try {
39
+ server = createServer(apiKey, {
40
+ ...(baseUrl !== undefined ? { baseUrl } : {}),
41
+ ...(timeout !== undefined ? { timeout } : {}),
42
+ });
43
+ }
44
+ catch (err) {
45
+ // Nunca logar a API key, mesmo em erro de inicialização
46
+ console.error('Failed to initialize Certynix MCP Server. Check your API key format and network connectivity.');
47
+ if (err instanceof Error) {
48
+ // Sanitizar mensagem de erro para garantir que a key não vaze
49
+ const sanitized = err.message.replace(apiKey, maskApiKey(apiKey));
50
+ console.error(`Details: ${sanitized}`);
51
+ }
52
+ process.exit(1);
53
+ }
54
+ if (transport === 'stdio') {
55
+ const stdioTransport = new StdioServerTransport();
56
+ await server.connect(stdioTransport);
57
+ // Log para stderr (não interfere com stdio MCP) — API key mascarada
58
+ console.error(`Certynix MCP Server running (stdio) — ` +
59
+ `API key: ${maskApiKey(apiKey)} — ` +
60
+ `Environment: ${isSandbox ? 'sandbox' : 'production'}`);
61
+ }
62
+ else if (transport === 'sse') {
63
+ const port = parseInt(process.env['MCP_PORT'] ?? '3100', 10);
64
+ // SSE transport via HTTP server
65
+ // Importação dinâmica para evitar dependência quando não for necessário
66
+ const { createServer: createHttpServer } = await import('node:http');
67
+ const { SSEServerTransport } = await import('@modelcontextprotocol/sdk/server/sse.js');
68
+ const httpServer = createHttpServer();
69
+ let sseTransport = null;
70
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
71
+ httpServer.on('request', async (req, res) => {
72
+ if (req.method === 'GET' && req.url === '/sse') {
73
+ sseTransport = new SSEServerTransport('/message', res);
74
+ await server.connect(sseTransport);
75
+ console.error(`Certynix MCP SSE client connected from ${req.socket.remoteAddress ?? 'unknown'}`);
76
+ }
77
+ else if (req.method === 'POST' && req.url === '/message') {
78
+ if (!sseTransport) {
79
+ res.writeHead(503, { 'Content-Type': 'application/json' });
80
+ res.end(JSON.stringify({ error: 'SSE connection not established yet' }));
81
+ return;
82
+ }
83
+ await sseTransport.handlePostMessage(req, res);
84
+ }
85
+ else if (req.method === 'GET' && req.url === '/health') {
86
+ res.writeHead(200, { 'Content-Type': 'application/json' });
87
+ res.end(JSON.stringify({
88
+ status: 'ok',
89
+ server: 'certynix-mcp',
90
+ version: '1.0.0',
91
+ environment: isSandbox ? 'sandbox' : 'production',
92
+ }));
93
+ }
94
+ else {
95
+ res.writeHead(404, { 'Content-Type': 'application/json' });
96
+ res.end(JSON.stringify({ error: 'Not found' }));
97
+ }
98
+ });
99
+ await new Promise((resolve, reject) => {
100
+ httpServer.listen(port, () => {
101
+ console.error(`Certynix MCP Server running on port ${port} (SSE) — ` +
102
+ `API key: ${maskApiKey(apiKey)} — ` +
103
+ `Environment: ${isSandbox ? 'sandbox' : 'production'}\n` +
104
+ ` SSE endpoint: http://localhost:${port}/sse\n` +
105
+ ` Health check: http://localhost:${port}/health`);
106
+ resolve();
107
+ });
108
+ httpServer.on('error', reject);
109
+ });
110
+ }
111
+ else {
112
+ console.error(`Error: Invalid MCP_TRANSPORT value: "${transport}". Expected "stdio" or "sse".`);
113
+ process.exit(1);
114
+ }
115
+ }
116
+ main().catch((err) => {
117
+ console.error('Fatal error:', err instanceof Error ? err.message : String(err));
118
+ process.exit(1);
119
+ });
@@ -0,0 +1,6 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ /**
3
+ * Prompt: certynix_audit_report
4
+ * Gera um relatório de auditoria estruturado a partir dos audit logs da organização.
5
+ */
6
+ export declare function registerAuditReportPrompt(server: McpServer): void;
@@ -0,0 +1,117 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Prompt: certynix_audit_report
4
+ * Gera um relatório de auditoria estruturado a partir dos audit logs da organização.
5
+ */
6
+ export function registerAuditReportPrompt(server) {
7
+ server.prompt('certynix_audit_report', 'Gera um relatório de auditoria estruturado para um período específico, analisando ações críticas, padrões de acesso e eventos de segurança.', {
8
+ period: z
9
+ .enum(['last_7_days', 'last_30_days', 'custom'])
10
+ .describe("Período do relatório: 'last_7_days' (últimos 7 dias), 'last_30_days' (últimos 30 dias), 'custom' (usar start_date e end_date)."),
11
+ start_date: z
12
+ .string()
13
+ .optional()
14
+ .describe("Data de início no formato ISO 8601 (ex: 2026-01-01T00:00:00Z). Necessário apenas quando period='custom'."),
15
+ end_date: z
16
+ .string()
17
+ .optional()
18
+ .describe("Data de fim no formato ISO 8601 (ex: 2026-01-31T23:59:59Z). Necessário apenas quando period='custom'."),
19
+ }, (args) => {
20
+ const period = args['period'] ?? 'last_30_days';
21
+ const startDate = args['start_date'];
22
+ const endDate = args['end_date'];
23
+ let periodDescription;
24
+ let dateInstructions;
25
+ if (period === 'last_7_days') {
26
+ const now = new Date();
27
+ const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
28
+ periodDescription = 'últimos 7 dias';
29
+ dateInstructions = `Use created_after="${weekAgo.toISOString()}" e created_before="${now.toISOString()}" ao chamar list_audit_logs.`;
30
+ }
31
+ else if (period === 'last_30_days') {
32
+ const now = new Date();
33
+ const monthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
34
+ periodDescription = 'últimos 30 dias';
35
+ dateInstructions = `Use created_after="${monthAgo.toISOString()}" e created_before="${now.toISOString()}" ao chamar list_audit_logs.`;
36
+ }
37
+ else if (period === 'custom' && startDate && endDate) {
38
+ periodDescription = `${startDate} até ${endDate}`;
39
+ dateInstructions = `Use created_after="${startDate}" e created_before="${endDate}" ao chamar list_audit_logs.`;
40
+ }
41
+ else {
42
+ periodDescription = 'período especificado';
43
+ dateInstructions =
44
+ "Peça ao usuário para especificar start_date e end_date quando period='custom'.";
45
+ }
46
+ return {
47
+ messages: [
48
+ {
49
+ role: 'user',
50
+ content: {
51
+ type: 'text',
52
+ text: `Gere um Relatório de Auditoria Certynix completo para o período: ${periodDescription}.
53
+
54
+ ## Instruções de execução
55
+
56
+ 1. **Chame a tool list_audit_logs** com os seguintes parâmetros:
57
+ - ${dateInstructions}
58
+ - limit: 100
59
+ - Se houver has_more=true na resposta, continue paginando com o next_cursor até obter todos os registros do período.
60
+
61
+ 2. **Chame a tool get_trust_score** para incluir o Trust Score atual no relatório.
62
+
63
+ 3. **Chame a tool list_alerts** com resolved=false para incluir alertas ativos.
64
+
65
+ ## Estrutura do relatório a gerar
66
+
67
+ Após coletar os dados, gere um relatório em Markdown com esta estrutura:
68
+
69
+ ---
70
+
71
+ # Relatório de Auditoria Certynix
72
+ **Período:** ${periodDescription}
73
+ **Gerado em:** [data atual]
74
+
75
+ ## Resumo Executivo
76
+ - Total de ações no período: [N]
77
+ - Trust Score atual: [score]/100
78
+ - Alertas ativos: [N]
79
+ - Eventos críticos: [N]
80
+
81
+ ## Trust Score
82
+ - Score: [N]/100 ([label])
83
+ - Identidade: [N]/35
84
+ - Segurança: [N]/25
85
+ - Comportamento: [N]/20
86
+ - Assets: [N]/20
87
+ - Penalidades ativas: [lista ou "Nenhuma"]
88
+
89
+ ## Atividade por Tipo de Ação
90
+ | Ação | Quantidade |
91
+ |------|-----------|
92
+ | asset.created | N |
93
+ | api_key.created | N |
94
+ | ... | ... |
95
+
96
+ ## Eventos Críticos de Segurança
97
+ [Lista de eventos relacionados a api_key.created, api_key.revoked, member.invited, plan.changed, etc.]
98
+
99
+ ## Assets Registrados no Período
100
+ [Sumário de assets registrados: total, status breakdown, first_registrant count]
101
+
102
+ ## Alertas de Exposição Ativos
103
+ [Lista de alertas não resolvidos com severidade]
104
+
105
+ ## Recomendações
106
+ [Com base nos dados coletados, liste 3-5 recomendações priorizadas]
107
+
108
+ ---
109
+
110
+ **IMPORTANTE:** Nunca inclua valores de API Keys, tokens, ou outros dados sensíveis no relatório.
111
+ `,
112
+ },
113
+ },
114
+ ],
115
+ };
116
+ });
117
+ }
@@ -0,0 +1,6 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ /**
3
+ * Prompt: certynix_security_review
4
+ * Analisa o estado de segurança da Organization e gera recomendações.
5
+ */
6
+ export declare function registerSecurityReviewPrompt(server: McpServer): void;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Prompt: certynix_security_review
3
+ * Analisa o estado de segurança da Organization e gera recomendações.
4
+ */
5
+ export function registerSecurityReviewPrompt(server) {
6
+ server.prompt('certynix_security_review', 'Gera uma análise de segurança completa da Organization: Trust Score, penalidades ativas, status de API Keys, alertas abertos e recomendações priorizadas.', {}, (_args) => {
7
+ return {
8
+ messages: [
9
+ {
10
+ role: 'user',
11
+ content: {
12
+ type: 'text',
13
+ text: `Realize uma Revisão de Segurança completa da organização Certynix.
14
+
15
+ ## Instruções de execução
16
+
17
+ Execute as seguintes tools em ordem para coletar dados:
18
+
19
+ 1. **get_trust_score** — Trust Score atual com componentes e penalidades
20
+ 2. **list_alerts** com resolved=false, limit=50 — Alertas de exposição ativos
21
+ 3. **list_api_keys** com limit=100 — Inventário de API Keys ativas
22
+ 4. **list_audit_logs** com limit=50, action="api_key.created" — Criações recentes de API Keys
23
+ 5. **list_audit_logs** com limit=20, action="member.invited" — Membros adicionados recentemente
24
+ 6. **list_assets** com limit=20, status="failed" — Assets com falha de verificação
25
+
26
+ ## Estrutura da análise a gerar
27
+
28
+ Após coletar todos os dados, gere uma Revisão de Segurança em Markdown:
29
+
30
+ ---
31
+
32
+ # Revisão de Segurança Certynix
33
+ **Data:** [data atual]
34
+ **Status Geral:** [Critico / Atenção / Bom / Excelente com base no score]
35
+
36
+ ## Trust Score: [N]/100
37
+
38
+ ### Componentes
39
+ | Pilar | Pontuação | Máximo | Status |
40
+ |-------|-----------|--------|--------|
41
+ | Identidade | N | 35 | [OK/Atenção/Crítico] |
42
+ | Segurança | N | 25 | [OK/Atenção/Crítico] |
43
+ | Comportamento | N | 20 | [OK/Atenção/Crítico] |
44
+ | Assets | N | 20 | [OK/Atenção/Crítico] |
45
+
46
+ ### Penalidades Ativas
47
+ [Lista de penalidades ou "Nenhuma penalidade ativa"]
48
+
49
+ ## Alertas de Exposição ([N] ativos)
50
+
51
+ ### Alta Severidade ([N])
52
+ [Lista de alertas high com descrição]
53
+
54
+ ### Média Severidade ([N])
55
+ [Lista de alertas medium]
56
+
57
+ ### Baixa Severidade ([N])
58
+ [Lista de alertas low]
59
+
60
+ ## API Keys ([N] ativas)
61
+ [Listar todas as API Keys com nome e data de criação]
62
+ [Identificar keys não utilizadas recentemente]
63
+ [Identificar keys criadas há mais de 90 dias sem rotação]
64
+
65
+ ## Observações de Acesso
66
+ [Membros adicionados recentemente]
67
+ [API Keys criadas recentemente]
68
+
69
+ ## Assets com Falha ([N])
70
+ [Lista de assets com status=failed]
71
+
72
+ ## Recomendações Priorizadas
73
+
74
+ ### Críticas (ação imediata)
75
+ 1. [recomendação baseada nos dados]
76
+
77
+ ### Altas (próxima semana)
78
+ 1. [recomendação baseada nos dados]
79
+
80
+ ### Médias (próximo mês)
81
+ 1. [recomendação baseada nos dados]
82
+
83
+ ## Score de Maturidade de Segurança
84
+ [Avaliação qualitativa de 1-5 com justificativa baseada nos dados coletados]
85
+
86
+ ---
87
+
88
+ **IMPORTANTE:** Nunca inclua valores de API Keys, tokens, signing secrets ou outros dados sensíveis na análise.
89
+ `,
90
+ },
91
+ },
92
+ ],
93
+ };
94
+ });
95
+ }
@@ -0,0 +1,7 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CertynixClient } from '@certynix/sdk';
3
+ /**
4
+ * Resource: certynix://alerts/active
5
+ * Lista todos os Exposure Alerts ativos não resolvidos.
6
+ */
7
+ export declare function registerActiveAlertsResource(server: McpServer, client: CertynixClient): void;
@@ -0,0 +1,43 @@
1
+ import { formatError } from '../utils/format.js';
2
+ /**
3
+ * Resource: certynix://alerts/active
4
+ * Lista todos os Exposure Alerts ativos não resolvidos.
5
+ */
6
+ export function registerActiveAlertsResource(server, client) {
7
+ server.resource('alerts-active', 'certynix://alerts/active', {
8
+ description: 'Lista de Exposure Alerts ativos não resolvidos: anomalias de integridade detectadas automaticamente (surtos de verificação, versões conflitantes, assets não verificados).',
9
+ mimeType: 'application/json',
10
+ }, async (_uri) => {
11
+ try {
12
+ const page = await client.alerts.listPage({ resolved: false, limit: 50 });
13
+ return {
14
+ contents: [
15
+ {
16
+ uri: 'certynix://alerts/active',
17
+ mimeType: 'application/json',
18
+ text: JSON.stringify({
19
+ data: page.data,
20
+ total_active: page.data.length,
21
+ has_more: page.pagination.has_more,
22
+ next_cursor: page.pagination.next_cursor,
23
+ note: page.pagination.has_more
24
+ ? 'Use a tool list_alerts com cursor para ver mais alertas.'
25
+ : undefined,
26
+ }, null, 2),
27
+ },
28
+ ],
29
+ };
30
+ }
31
+ catch (err) {
32
+ return {
33
+ contents: [
34
+ {
35
+ uri: 'certynix://alerts/active',
36
+ mimeType: 'application/json',
37
+ text: JSON.stringify({ error: formatError(err) }, null, 2),
38
+ },
39
+ ],
40
+ };
41
+ }
42
+ });
43
+ }
@@ -0,0 +1,7 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CertynixClient } from '@certynix/sdk';
3
+ /**
4
+ * Resource template: certynix://assets/{asset_id}
5
+ * Retorna metadados completos de um asset específico.
6
+ */
7
+ export declare function registerAssetResource(server: McpServer, client: CertynixClient): void;