mcp-server-scf 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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -0
  3. package/build/index.d.ts +3 -0
  4. package/build/index.d.ts.map +1 -0
  5. package/build/index.js +33 -0
  6. package/build/index.js.map +1 -0
  7. package/build/lib/api-client.d.ts +24 -0
  8. package/build/lib/api-client.d.ts.map +1 -0
  9. package/build/lib/api-client.js +72 -0
  10. package/build/lib/api-client.js.map +1 -0
  11. package/build/lib/errors.d.ts +14 -0
  12. package/build/lib/errors.d.ts.map +1 -0
  13. package/build/lib/errors.js +35 -0
  14. package/build/lib/errors.js.map +1 -0
  15. package/build/tools/capabilities.d.ts +3 -0
  16. package/build/tools/capabilities.d.ts.map +1 -0
  17. package/build/tools/capabilities.js +69 -0
  18. package/build/tools/capabilities.js.map +1 -0
  19. package/build/tools/catalog.d.ts +3 -0
  20. package/build/tools/catalog.d.ts.map +1 -0
  21. package/build/tools/catalog.js +94 -0
  22. package/build/tools/catalog.js.map +1 -0
  23. package/build/tools/evidence.d.ts +3 -0
  24. package/build/tools/evidence.d.ts.map +1 -0
  25. package/build/tools/evidence.js +69 -0
  26. package/build/tools/evidence.js.map +1 -0
  27. package/build/tools/organization.d.ts +3 -0
  28. package/build/tools/organization.d.ts.map +1 -0
  29. package/build/tools/organization.js +88 -0
  30. package/build/tools/organization.js.map +1 -0
  31. package/build/tools/risk.d.ts +3 -0
  32. package/build/tools/risk.d.ts.map +1 -0
  33. package/build/tools/risk.js +77 -0
  34. package/build/tools/risk.js.map +1 -0
  35. package/build/tools/scoped-controls.d.ts +3 -0
  36. package/build/tools/scoped-controls.d.ts.map +1 -0
  37. package/build/tools/scoped-controls.js +118 -0
  38. package/build/tools/scoped-controls.js.map +1 -0
  39. package/build/tools/vendors.d.ts +3 -0
  40. package/build/tools/vendors.d.ts.map +1 -0
  41. package/build/tools/vendors.js +92 -0
  42. package/build/tools/vendors.js.map +1 -0
  43. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Compliance Genie
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # mcp-server-scf
2
+
3
+ [![npm version](https://img.shields.io/npm/v/mcp-server-scf.svg)](https://www.npmjs.com/package/mcp-server-scf)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
+ [![MCP](https://img.shields.io/badge/MCP-compatible-green.svg)](https://modelcontextprotocol.io)
6
+
7
+ **Security compliance controls, frameworks, and risk management for AI agents.**
8
+
9
+ Give your AI assistant access to 1,451 SCF security controls, 354+ framework mappings (NIST 800-53, ISO 27001, SOC 2, FedRAMP, GDPR), evidence tracking, risk registers, and vendor risk management — all through the [Model Context Protocol](https://modelcontextprotocol.io).
10
+
11
+ ## Quick Start
12
+
13
+ ### Claude Desktop
14
+
15
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "scf": {
21
+ "command": "npx",
22
+ "args": ["-y", "mcp-server-scf"],
23
+ "env": {
24
+ "SCF_API_KEY": "scf_your_api_key_here",
25
+ "SCF_API_URL": "https://eu.scfcontrolsplatform.app"
26
+ }
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ### Claude Code
33
+
34
+ ```bash
35
+ claude mcp add scf -- npx -y mcp-server-scf
36
+ ```
37
+
38
+ Then set environment variables in your shell:
39
+
40
+ ```bash
41
+ export SCF_API_KEY="scf_your_api_key_here"
42
+ export SCF_API_URL="https://eu.scfcontrolsplatform.app"
43
+ ```
44
+
45
+ ### Cursor / Windsurf
46
+
47
+ Add to your MCP config (`.cursor/mcp.json` or equivalent):
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "scf": {
53
+ "command": "npx",
54
+ "args": ["-y", "mcp-server-scf"],
55
+ "env": {
56
+ "SCF_API_KEY": "scf_your_api_key_here",
57
+ "SCF_API_URL": "https://eu.scfcontrolsplatform.app"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Docker
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "scf": {
70
+ "command": "docker",
71
+ "args": ["run", "-i", "--rm", "-e", "SCF_API_KEY", "markac007/mcp-server-scf"],
72
+ "env": {
73
+ "SCF_API_KEY": "scf_your_api_key_here"
74
+ }
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## Getting an API Key
81
+
82
+ 1. Sign up at [scfcontrolsplatform.app](https://eu.scfcontrolsplatform.app)
83
+ 2. Go to **Settings > API Keys**
84
+ 3. Click **Generate New Key**
85
+ 4. Copy the key (shown once) and add it to your MCP config
86
+
87
+ ## Tools
88
+
89
+ ### Catalog (Read-Only Reference Data)
90
+
91
+ | Tool | Description |
92
+ |------|-------------|
93
+ | `list_controls` | List SCF security controls with search, domain, and framework filters |
94
+ | `get_control` | Get control details with assessment objectives and evidence items |
95
+ | `list_frameworks` | List all 354+ mapped compliance frameworks |
96
+ | `list_domains` | List compliance domains (Asset Management, IAC, etc.) |
97
+ | `list_evidence_catalog` | List 272 standard evidence types |
98
+ | `list_assessment_objectives` | List 5,736 assessment test criteria |
99
+
100
+ ### Control Scoping (Implementation Tracking)
101
+
102
+ | Tool | Description |
103
+ |------|-------------|
104
+ | `list_scoped_controls` | List controls scoped to your org with implementation status |
105
+ | `get_scoped_control` | Get detailed implementation status, owner, and audit history |
106
+ | `update_scoped_control` | Update status, owner, or notes (validated state transitions) |
107
+ | `get_scoping_stats` | Implementation progress — counts by status, completion % |
108
+ | `scope_framework` | Bulk-scope all controls from a framework |
109
+ | `batch_update_controls` | Batch update up to 500 controls in one transaction |
110
+
111
+ ### Evidence Collection
112
+
113
+ | Tool | Description |
114
+ |------|-------------|
115
+ | `list_evidence` | List evidence items tracked for controls |
116
+ | `create_evidence` | Create evidence linked to a control |
117
+ | `get_evidence_maturity` | Evidence maturity scores across controls |
118
+ | `list_evidence_tasks` | Evidence collection work queue |
119
+
120
+ ### Risk Management
121
+
122
+ | Tool | Description |
123
+ |------|-------------|
124
+ | `list_risks` | List risk register entries with scores and treatment status |
125
+ | `get_risk` | Get detailed risk assessment (inherent + residual scores) |
126
+ | `create_risk` | Create risk in the 5x5 matrix with likelihood and impact |
127
+ | `get_risk_matrix` | 5x5 risk matrix visualization data |
128
+ | `get_risk_summary` | Aggregated risk summary by severity |
129
+
130
+ ### Vendor Risk (TPRM)
131
+
132
+ | Tool | Description |
133
+ |------|-------------|
134
+ | `list_vendors` | List vendors with status and criticality filters |
135
+ | `get_vendor` | Get vendor details, certs, assessments, and risk scores |
136
+ | `create_vendor` | Add vendor to TPRM registry |
137
+ | `trigger_vendor_research` | AI-powered security research (HIBP, NVD, breach history) |
138
+ | `get_vendor_research` | Get latest vendor research results |
139
+ | `trigger_dpsia` | Data Protection Security Impact Assessment |
140
+
141
+ ### Organization & Platform
142
+
143
+ | Tool | Description |
144
+ |------|-------------|
145
+ | `get_current_user` | Current user profile and organizations |
146
+ | `list_organizations` | Organizations you have access to |
147
+ | `get_organization` | Org details, tier, usage, and settings |
148
+ | `list_members` | Organization members and roles |
149
+ | `get_work_queue` | Your prioritized task queue |
150
+ | `get_audit_log` | Field-level change audit trail (SOC 2) |
151
+ | `get_notifications` | User notifications and alerts |
152
+
153
+ ### Capabilities & Systems
154
+
155
+ | Tool | Description |
156
+ |------|-------------|
157
+ | `list_capability_themes` | 11 KSI-aligned capability themes |
158
+ | `list_capabilities` | Security capabilities mapped to systems |
159
+ | `list_systems` | Infrastructure systems inventory |
160
+ | `create_system` | Add system to inventory |
161
+
162
+ ## Configuration
163
+
164
+ | Variable | Required | Default | Description |
165
+ |----------|----------|---------|-------------|
166
+ | `SCF_API_KEY` | Yes | — | Your SCF platform API key (`scf_` prefix) |
167
+ | `SCF_API_URL` | No | `https://eu.scfcontrolsplatform.app` | Platform API URL |
168
+
169
+ ## Example Prompts
170
+
171
+ Once connected, try asking your AI assistant:
172
+
173
+ - "What NIST 800-53 controls apply to access control?"
174
+ - "Show me my organization's control implementation progress"
175
+ - "List all critical vendors and their risk scores"
176
+ - "Create a risk assessment for our cloud migration"
177
+ - "What evidence do I need to collect for SOC 2 audit?"
178
+ - "Show the 5x5 risk matrix for my organization"
179
+ - "What's in my compliance work queue today?"
180
+
181
+ ## Architecture
182
+
183
+ ```
184
+ mcp-server-scf
185
+ ├── src/
186
+ │ ├── index.ts # Server entry point (stdio transport)
187
+ │ ├── tools/
188
+ │ │ ├── catalog.ts # SCF reference data (read-only)
189
+ │ │ ├── scoped-controls.ts # Control implementation tracking
190
+ │ │ ├── evidence.ts # Evidence collection
191
+ │ │ ├── risk.ts # Risk register
192
+ │ │ ├── vendors.ts # Third-party risk management
193
+ │ │ ├── organization.ts # Org, users, audit, notifications
194
+ │ │ └── capabilities.ts # KSI themes, systems
195
+ │ └── lib/
196
+ │ ├── api-client.ts # HTTP client with auth
197
+ │ └── errors.ts # Structured error handling
198
+ ├── build/ # Compiled output
199
+ ├── package.json
200
+ └── tsconfig.json
201
+ ```
202
+
203
+ ## Development
204
+
205
+ ```bash
206
+ # Clone
207
+ git clone https://github.com/MarkAC007/mcp-server-scf.git
208
+ cd mcp-server-scf
209
+
210
+ # Install
211
+ npm install
212
+
213
+ # Build
214
+ npm run build
215
+
216
+ # Development (watch mode)
217
+ npm run dev
218
+
219
+ # Test with MCP Inspector
220
+ npm run inspector
221
+ ```
222
+
223
+ ## Testing with MCP Inspector
224
+
225
+ ```bash
226
+ SCF_API_KEY=scf_your_key npx @modelcontextprotocol/inspector node build/index.js
227
+ ```
228
+
229
+ ## Security
230
+
231
+ - API keys are never logged or included in error messages
232
+ - All communication uses HTTPS
233
+ - Keys are SHA-256 hashed server-side
234
+ - Rate limiting: 100 req/min (read), 20 req/min (write)
235
+ - Multi-tenant: All operations scoped to your organization
236
+
237
+ ## Contributing
238
+
239
+ Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting PRs.
240
+
241
+ 1. Fork the repository
242
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
243
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
244
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
245
+ 5. Open a Pull Request
246
+
247
+ ## License
248
+
249
+ MIT - see [LICENSE](LICENSE)
250
+
251
+ ## Links
252
+
253
+ - [SCF Controls Platform](https://eu.scfcontrolsplatform.app) - The compliance platform
254
+ - [Model Context Protocol](https://modelcontextprotocol.io) - MCP specification
255
+ - [SCF Framework](https://securecontrolsframework.com) - Secure Controls Framework
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { registerCatalogTools } from "./tools/catalog.js";
5
+ import { registerScopedControlTools } from "./tools/scoped-controls.js";
6
+ import { registerEvidenceTools } from "./tools/evidence.js";
7
+ import { registerRiskTools } from "./tools/risk.js";
8
+ import { registerVendorTools } from "./tools/vendors.js";
9
+ import { registerOrganizationTools } from "./tools/organization.js";
10
+ import { registerCapabilityTools } from "./tools/capabilities.js";
11
+ const server = new McpServer({
12
+ name: "mcp-server-scf",
13
+ version: "0.1.0",
14
+ });
15
+ // Register all tool groups
16
+ registerCatalogTools(server);
17
+ registerScopedControlTools(server);
18
+ registerEvidenceTools(server);
19
+ registerRiskTools(server);
20
+ registerVendorTools(server);
21
+ registerOrganizationTools(server);
22
+ registerCapabilityTools(server);
23
+ // Start server
24
+ async function main() {
25
+ const transport = new StdioServerTransport();
26
+ await server.connect(transport);
27
+ console.error("SCF MCP Server running on stdio");
28
+ }
29
+ main().catch((error) => {
30
+ console.error("Fatal error:", error);
31
+ process.exit(1);
32
+ });
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,2BAA2B;AAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACnC,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAClC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAEhC,eAAe;AACf,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ export interface ApiClientConfig {
2
+ baseUrl: string;
3
+ apiKey: string;
4
+ }
5
+ export interface PaginatedResponse<T> {
6
+ items: T[];
7
+ total: number;
8
+ page: number;
9
+ per_page: number;
10
+ pages: number;
11
+ }
12
+ export declare class ScfApiClient {
13
+ private baseUrl;
14
+ private apiKey;
15
+ constructor(config: ApiClientConfig);
16
+ private request;
17
+ get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
18
+ post<T>(path: string, body?: unknown): Promise<T>;
19
+ patch<T>(path: string, body?: unknown): Promise<T>;
20
+ delete<T>(path: string): Promise<T>;
21
+ put<T>(path: string, body?: unknown): Promise<T>;
22
+ }
23
+ export declare function getClient(): ScfApiClient;
24
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,eAAe;YAKrB,OAAO;IA+Cf,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhG,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAInC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAGvD;AAID,wBAAgB,SAAS,IAAI,YAAY,CAexC"}
@@ -0,0 +1,72 @@
1
+ import { ScfApiError } from "./errors.js";
2
+ export class ScfApiClient {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(config) {
6
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
7
+ this.apiKey = config.apiKey;
8
+ }
9
+ async request(method, path, options) {
10
+ const url = new URL(`${this.baseUrl}/api${path}`);
11
+ if (options?.params) {
12
+ for (const [key, value] of Object.entries(options.params)) {
13
+ if (value !== undefined && value !== null) {
14
+ url.searchParams.set(key, String(value));
15
+ }
16
+ }
17
+ }
18
+ const headers = {
19
+ Authorization: `Bearer ${this.apiKey}`,
20
+ Accept: "application/json",
21
+ };
22
+ if (options?.body) {
23
+ headers["Content-Type"] = "application/json";
24
+ }
25
+ const response = await fetch(url.toString(), {
26
+ method,
27
+ headers,
28
+ body: options?.body ? JSON.stringify(options.body) : undefined,
29
+ });
30
+ if (!response.ok) {
31
+ let detail = response.statusText;
32
+ try {
33
+ const errorBody = (await response.json());
34
+ detail = errorBody.detail || errorBody.error || detail;
35
+ }
36
+ catch {
37
+ // Use status text as fallback
38
+ }
39
+ throw new ScfApiError(detail, response.status);
40
+ }
41
+ return response.json();
42
+ }
43
+ async get(path, params) {
44
+ return this.request("GET", path, { params });
45
+ }
46
+ async post(path, body) {
47
+ return this.request("POST", path, { body });
48
+ }
49
+ async patch(path, body) {
50
+ return this.request("PATCH", path, { body });
51
+ }
52
+ async delete(path) {
53
+ return this.request("DELETE", path);
54
+ }
55
+ async put(path, body) {
56
+ return this.request("PUT", path, { body });
57
+ }
58
+ }
59
+ let _client = null;
60
+ export function getClient() {
61
+ if (!_client) {
62
+ const apiKey = process.env.SCF_API_KEY;
63
+ const baseUrl = process.env.SCF_API_URL || "https://eu.scfcontrolsplatform.app";
64
+ if (!apiKey) {
65
+ throw new Error("SCF_API_KEY environment variable is required. " +
66
+ "Generate one at https://eu.scfcontrolsplatform.app/settings/api-keys");
67
+ }
68
+ _client = new ScfApiClient({ baseUrl, apiKey });
69
+ }
70
+ return _client;
71
+ }
72
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare class ScfApiError extends Error {
2
+ statusCode: number;
3
+ errorCode?: string | undefined;
4
+ constructor(message: string, statusCode: number, errorCode?: string | undefined);
5
+ }
6
+ export declare function formatError(error: unknown): string;
7
+ export declare function errorResult(error: unknown): {
8
+ content: {
9
+ type: "text";
10
+ text: string;
11
+ }[];
12
+ isError: boolean;
13
+ };
14
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;IAG3B,UAAU,EAAE,MAAM;IAClB,SAAS,CAAC,EAAE,MAAM;gBAFzB,OAAO,EAAE,MAAM,EACR,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,YAAA;CAK5B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWlD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO;;;;;;EAKzC"}
@@ -0,0 +1,35 @@
1
+ export class ScfApiError extends Error {
2
+ statusCode;
3
+ errorCode;
4
+ constructor(message, statusCode, errorCode) {
5
+ super(message);
6
+ this.statusCode = statusCode;
7
+ this.errorCode = errorCode;
8
+ this.name = "ScfApiError";
9
+ }
10
+ }
11
+ export function formatError(error) {
12
+ if (error instanceof ScfApiError) {
13
+ if (error.statusCode === 401)
14
+ return "Authentication failed. Check your SCF_API_KEY.";
15
+ if (error.statusCode === 403)
16
+ return "Access denied. Your API key may lack permissions for this operation.";
17
+ if (error.statusCode === 404)
18
+ return `Not found: ${error.message}`;
19
+ if (error.statusCode === 429)
20
+ return "Rate limited. Please wait before retrying.";
21
+ if (error.statusCode === 402)
22
+ return "Subscription limit reached. Upgrade your plan to continue.";
23
+ return `API error (${error.statusCode}): ${error.message}`;
24
+ }
25
+ if (error instanceof Error)
26
+ return error.message;
27
+ return String(error);
28
+ }
29
+ export function errorResult(error) {
30
+ return {
31
+ content: [{ type: "text", text: formatError(error) }],
32
+ isError: true,
33
+ };
34
+ }
35
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAY,SAAQ,KAAK;IAG3B;IACA;IAHT,YACE,OAAe,EACR,UAAkB,EAClB,SAAkB;QAEzB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,eAAU,GAAV,UAAU,CAAQ;QAClB,cAAS,GAAT,SAAS,CAAS;QAGzB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO,gDAAgD,CAAC;QACtF,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO,sEAAsE,CAAC;QAC5G,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC;QACnE,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO,4CAA4C,CAAC;QAClF,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO,4DAA4D,CAAC;QAClG,OAAO,cAAc,KAAK,CAAC,UAAU,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7D,CAAC;IACD,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IACjD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerCapabilityTools(server: McpServer): void;
3
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/tools/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,QAmFxD"}
@@ -0,0 +1,69 @@
1
+ import { z } from "zod";
2
+ import { getClient } from "../lib/api-client.js";
3
+ import { errorResult } from "../lib/errors.js";
4
+ export function registerCapabilityTools(server) {
5
+ server.tool("list_capability_themes", "List the 11 KSI-aligned capability themes that group NIST 800-53 controls into security capability areas. Provides a high-level view of your security posture by capability.", {}, async () => {
6
+ try {
7
+ const client = getClient();
8
+ const data = await client.get("/capability-themes");
9
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
10
+ }
11
+ catch (error) {
12
+ return errorResult(error);
13
+ }
14
+ });
15
+ server.tool("list_capabilities", "List capabilities for an organization. Capabilities map to systems and evidence, showing what security functions your infrastructure supports.", {
16
+ org_id: z.string().describe("Organization ID"),
17
+ page: z.number().min(1).default(1).describe("Page number"),
18
+ per_page: z.number().min(1).max(100).default(25).describe("Results per page"),
19
+ }, async ({ org_id, page, per_page }) => {
20
+ try {
21
+ const client = getClient();
22
+ const data = await client.get(`/organizations/${org_id}/capabilities`, { page, per_page });
23
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
24
+ }
25
+ catch (error) {
26
+ return errorResult(error);
27
+ }
28
+ });
29
+ server.tool("list_systems", "List infrastructure systems in the organization's inventory. Systems are the tools and platforms that implement security capabilities.", {
30
+ org_id: z.string().describe("Organization ID"),
31
+ }, async ({ org_id }) => {
32
+ try {
33
+ const client = getClient();
34
+ const data = await client.get(`/organizations/${org_id}/systems`);
35
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
36
+ }
37
+ catch (error) {
38
+ return errorResult(error);
39
+ }
40
+ });
41
+ server.tool("create_system", "Add a system to the organization's infrastructure inventory. Systems can be linked to capabilities and evidence.", {
42
+ org_id: z.string().describe("Organization ID"),
43
+ name: z.string().describe("System name"),
44
+ description: z.string().optional().describe("System description"),
45
+ system_type: z
46
+ .enum([
47
+ "cloud_provider",
48
+ "identity_provider",
49
+ "ticketing",
50
+ "logging",
51
+ "security_tool",
52
+ "code_repository",
53
+ "document_management",
54
+ "custom",
55
+ ])
56
+ .describe("System type"),
57
+ status: z.enum(["active", "inactive", "deprecated"]).default("active").describe("System status"),
58
+ }, async ({ org_id, ...body }) => {
59
+ try {
60
+ const client = getClient();
61
+ const data = await client.post(`/organizations/${org_id}/systems`, body);
62
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
63
+ }
64
+ catch (error) {
65
+ return errorResult(error);
66
+ }
67
+ });
68
+ }
69
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/tools/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerCatalogTools(server: McpServer): void;
3
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/tools/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,QAsHrD"}