@occam-scaly/mcp-server 0.1.2

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 (91) hide show
  1. package/README.md +166 -0
  2. package/bin/scaly-mcp.js +6 -0
  3. package/dist/audit.d.ts +25 -0
  4. package/dist/audit.d.ts.map +1 -0
  5. package/dist/audit.js +182 -0
  6. package/dist/audit.js.map +1 -0
  7. package/dist/client.d.ts +16 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +142 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/config.d.ts +24 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +76 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +279 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/resources/index.d.ts +17 -0
  20. package/dist/resources/index.d.ts.map +1 -0
  21. package/dist/resources/index.js +505 -0
  22. package/dist/resources/index.js.map +1 -0
  23. package/dist/tools/addons.d.ts +3 -0
  24. package/dist/tools/addons.d.ts.map +1 -0
  25. package/dist/tools/addons.js +128 -0
  26. package/dist/tools/addons.js.map +1 -0
  27. package/dist/tools/apps.d.ts +3 -0
  28. package/dist/tools/apps.d.ts.map +1 -0
  29. package/dist/tools/apps.js +121 -0
  30. package/dist/tools/apps.js.map +1 -0
  31. package/dist/tools/compute.d.ts +3 -0
  32. package/dist/tools/compute.d.ts.map +1 -0
  33. package/dist/tools/compute.js +135 -0
  34. package/dist/tools/compute.js.map +1 -0
  35. package/dist/tools/db.d.ts +3 -0
  36. package/dist/tools/db.d.ts.map +1 -0
  37. package/dist/tools/db.js +597 -0
  38. package/dist/tools/db.js.map +1 -0
  39. package/dist/tools/deployments.d.ts +3 -0
  40. package/dist/tools/deployments.d.ts.map +1 -0
  41. package/dist/tools/deployments.js +354 -0
  42. package/dist/tools/deployments.js.map +1 -0
  43. package/dist/tools/diagnose.d.ts +3 -0
  44. package/dist/tools/diagnose.d.ts.map +1 -0
  45. package/dist/tools/diagnose.js +213 -0
  46. package/dist/tools/diagnose.js.map +1 -0
  47. package/dist/tools/env.d.ts +3 -0
  48. package/dist/tools/env.d.ts.map +1 -0
  49. package/dist/tools/env.js +216 -0
  50. package/dist/tools/env.js.map +1 -0
  51. package/dist/tools/index.d.ts +38 -0
  52. package/dist/tools/index.d.ts.map +1 -0
  53. package/dist/tools/index.js +48 -0
  54. package/dist/tools/index.js.map +1 -0
  55. package/dist/tools/jobs.d.ts +3 -0
  56. package/dist/tools/jobs.d.ts.map +1 -0
  57. package/dist/tools/jobs.js +160 -0
  58. package/dist/tools/jobs.js.map +1 -0
  59. package/dist/tools/logs.d.ts +3 -0
  60. package/dist/tools/logs.d.ts.map +1 -0
  61. package/dist/tools/logs.js +157 -0
  62. package/dist/tools/logs.js.map +1 -0
  63. package/dist/tools/operations.d.ts +3 -0
  64. package/dist/tools/operations.d.ts.map +1 -0
  65. package/dist/tools/operations.js +262 -0
  66. package/dist/tools/operations.js.map +1 -0
  67. package/dist/tools/project.d.ts +3 -0
  68. package/dist/tools/project.d.ts.map +1 -0
  69. package/dist/tools/project.js +341 -0
  70. package/dist/tools/project.js.map +1 -0
  71. package/dist/tools/s3.d.ts +3 -0
  72. package/dist/tools/s3.d.ts.map +1 -0
  73. package/dist/tools/s3.js +256 -0
  74. package/dist/tools/s3.js.map +1 -0
  75. package/dist/tools/status.d.ts +3 -0
  76. package/dist/tools/status.d.ts.map +1 -0
  77. package/dist/tools/status.js +139 -0
  78. package/dist/tools/status.js.map +1 -0
  79. package/dist/tools/write.d.ts +3 -0
  80. package/dist/tools/write.d.ts.map +1 -0
  81. package/dist/tools/write.js +900 -0
  82. package/dist/tools/write.js.map +1 -0
  83. package/dist/utils/jwt.d.ts +3 -0
  84. package/dist/utils/jwt.d.ts.map +1 -0
  85. package/dist/utils/jwt.js +32 -0
  86. package/dist/utils/jwt.js.map +1 -0
  87. package/dist/utils/paths.d.ts +5 -0
  88. package/dist/utils/paths.d.ts.map +1 -0
  89. package/dist/utils/paths.js +26 -0
  90. package/dist/utils/paths.js.map +1 -0
  91. package/package.json +50 -0
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # @occam-scaly/mcp-server
2
+
3
+ Model Context Protocol (MCP) server for Scaly. Connect your AI assistant (Claude, Cursor, etc.) to manage your cloud infrastructure.
4
+
5
+ ## Quick Start
6
+
7
+ Note: If `@occam-scaly/mcp-server` is not published to npm yet, run it from a local checkout of the Scaly repo (see “Development” below) and point your MCP client at `packages/mcp-server/bin/scaly-mcp.js`.
8
+
9
+ ### 1. Get your API key
10
+
11
+ Go to **Scaly Dashboard → Settings → Integrations → AI Assistants** and generate:
12
+
13
+ - **Scaly API key** (`SCALY_API_KEY`)
14
+ - **AppSync API key** (`SCALY_APPSYNC_KEY`, optional for Scaly hosted `prod|dev|qa`)
15
+
16
+ Optional:
17
+
18
+ - **OIDC session token** (`SCALY_OIDC_TOKEN`) — required only for DB/S3 tools. Get it from Scaly Dashboard → Settings → Integrations → AI Integrations.
19
+
20
+ ### 2. Configure your AI assistant
21
+
22
+ **Claude Desktop** - Add to `~/.config/claude/claude_desktop_config.json`:
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "scaly": {
28
+ "command": "npx",
29
+ "args": ["-y", "@occam-scaly/mcp-server"],
30
+ "env": {
31
+ "SCALY_API_KEY": "sk_live_your_key_here",
32
+ "SCALY_APPSYNC_KEY": "da2_live_your_key_here (optional for Scaly hosted prod/dev/qa)",
33
+ "SCALY_OIDC_TOKEN": "eyJ... (optional, enables DB/S3 tools)",
34
+ "SCALY_STAGE": "prod"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ **Claude Code** - Add to your Claude Code MCP settings.
42
+
43
+ ### 3. Restart your AI assistant
44
+
45
+ The Scaly tools will now be available.
46
+
47
+ ## Available Tools
48
+
49
+ All tools return **JSON-only** responses (wrapped in MCP `content[].text`).
50
+
51
+ ### Core inventory
52
+
53
+ - `scaly_status` - Overview of stacks/apps + running deployments
54
+ - `scaly_list_apps` / `scaly_get_app`
55
+ - `scaly_list_stacks` / `scaly_get_stack` (alias: `scaly_list_compute`)
56
+ - `scaly_list_addons` / `scaly_get_addon`
57
+ - `scaly_list_jobs` / `scaly_run_job`
58
+
59
+ ### Deployments & operations
60
+
61
+ - `scaly_list_deployments` / `scaly_get_deployment` (alias: `scaly_get_deployment_status`)
62
+ - `scaly_deploy_app` (currently implemented as stack service restart)
63
+ - `scaly_restart_stack_services`
64
+ - `scaly_retry_deployment`
65
+ - `scaly_get_operation` / `scaly_wait_operation` / `scaly_get_operation_events`
66
+
67
+ ### Configuration
68
+
69
+ - `scaly_set_env` (alias: `scaly_set_env_var`) – blocks secret-like keys, never echoes values
70
+ - `scaly_get_env_vars` – returns names only
71
+
72
+ ### Project config
73
+
74
+ - `scaly_plan` – computes a plan from `.scaly/config.yaml` and returns `plan_hash`
75
+ - `scaly_apply` – applies a plan (requires `plan_hash` and `auto_approve: true`)
76
+ - `scaly_pull` – writes `.scaly/config.yaml` by reverse-engineering live state
77
+
78
+ ### Write tools (imperative)
79
+
80
+ - `scaly_create_stack` / `scaly_update_stack` / `scaly_delete_stack` (preview-first; delete requires confirm)
81
+ - `scaly_create_database` / `scaly_create_storage` / `scaly_create_user_pool`
82
+ - `scaly_create_app`
83
+ - `scaly_link_addon`
84
+ - `scaly_configure_auth`
85
+
86
+ Notes:
87
+
88
+ - Phase 4 intentionally omits add-on updates/resizes, add-on deletion, and unlink operations.
89
+
90
+ ### Logs & diagnostics
91
+
92
+ - `scaly_get_logs` (unified logs)
93
+ - `scaly_diagnose_app`
94
+
95
+ ### Database & S3 (requires OIDC token)
96
+
97
+ - `scaly_db_query` / `scaly_db_execute`
98
+ - `scaly_db_migration_plan` / `scaly_db_migrate` / `scaly_db_schema_dump`
99
+ - `scaly_s3_list_objects` / `scaly_s3_download_object`
100
+ - `scaly_s3_upload_object` / `scaly_s3_delete_object` (currently NOT_SUPPORTED)
101
+
102
+ ## Resources
103
+
104
+ - `scaly://capabilities` (YAML)
105
+ - `scaly://resources-schema` (JSON Schema)
106
+ - `scaly://guides/platform` (Markdown)
107
+ - `scaly://guides/golden-paths` (Markdown)
108
+ - Templates: `scaly://guides/frameworks/{name}`, `scaly://guides/patterns/{name}`, `scaly://apps/{id}`, `scaly://stacks/{id}`
109
+
110
+ ## Example Usage
111
+
112
+ ```
113
+ You: "What apps do I have running?"
114
+
115
+ Claude: [Calling scaly_list_apps]
116
+
117
+ {"success":true,"data":{"apps":[...],"count":3},"meta":{...}}
118
+ ```
119
+
120
+ ```
121
+ You: "Deploy ml-api"
122
+
123
+ Claude: [Calling scaly_deploy_app]
124
+
125
+ {"success":true,"data":{"operation_id":"dep_abc123",...},"meta":{...}}
126
+ ```
127
+
128
+ ## Environment Variables
129
+
130
+ | Variable | Required | Description |
131
+ | ---------------------- | -------- | ---------------------------------------------------------------- |
132
+ | `SCALY_API_KEY` | Yes | Your Scaly API key |
133
+ | `SCALY_APPSYNC_KEY` | No | AppSync API key (enables API access; defaults for prod/dev/qa) |
134
+ | `SCALY_OIDC_TOKEN` | No | Cognito access token (enables DB/S3 tools) |
135
+ | `SCALY_MCP_AUDIT` | No | Enable audit logging (`true` by default; set `false` to disable) |
136
+ | `SCALY_MCP_AUDIT_FILE` | No | Write audit logs as JSONL to this file path (defaults to stderr) |
137
+ | `SCALY_STAGE` | No | `prod` (default), `dev`, `qa` (`staging` alias) |
138
+ | `SCALY_API_URL` | No | Override API URL |
139
+
140
+ ## Development
141
+
142
+ ```bash
143
+ # Install dependencies
144
+ npm install
145
+
146
+ # Run in development mode
147
+ npm run dev
148
+
149
+ # Build
150
+ npm run build
151
+
152
+ # Type check
153
+ npm run typecheck
154
+ ```
155
+
156
+ ## Security
157
+
158
+ - API keys are scoped to specific permissions
159
+ - Tool outputs are treated as durable transcripts; avoid returning secrets or credentials
160
+ - Never store API keys in version control
161
+ - Revoke keys immediately if compromised
162
+
163
+ ## Support
164
+
165
+ - Documentation: https://docs.scaly.cloud/mcp
166
+ - Issues: https://github.com/scaly-cloud/mcp-server/issues
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+
3
+ import('../dist/index.js').catch((err) => {
4
+ console.error('Failed to start Scaly MCP server:', err.message);
5
+ process.exit(1);
6
+ });
@@ -0,0 +1,25 @@
1
+ type AuditKind = 'tool_call' | 'resource_read';
2
+ type AuditEvent = {
3
+ kind: AuditKind;
4
+ ts: string;
5
+ request_id: string;
6
+ stage?: string;
7
+ api_url?: string;
8
+ name?: string;
9
+ uri?: string;
10
+ input?: unknown;
11
+ success: boolean;
12
+ error_code?: string;
13
+ duration_ms: number;
14
+ output?: unknown;
15
+ };
16
+ export declare function createAuditLogger({ stage, apiUrl }: {
17
+ stage?: string;
18
+ apiUrl?: string;
19
+ }): {
20
+ enabled: boolean;
21
+ logToolCall: (e: Omit<AuditEvent, "kind" | "ts" | "stage" | "api_url">) => void;
22
+ logResourceRead: (e: Omit<AuditEvent, "kind" | "ts" | "stage" | "api_url">) => void;
23
+ };
24
+ export {};
25
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAIA,KAAK,SAAS,GAAG,WAAW,GAAG,eAAe,CAAC;AAE/C,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAgJF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,MAAM,EACP,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;;qBAqBoB,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;yBAWjE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;EAY7D"}
package/dist/audit.js ADDED
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAuditLogger = createAuditLogger;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const node_crypto_1 = require("node:crypto");
10
+ function parseBoolEnv(value, defaultValue) {
11
+ if (value === undefined)
12
+ return defaultValue;
13
+ const v = value.trim().toLowerCase();
14
+ if (['1', 'true', 'yes', 'y', 'on'].includes(v))
15
+ return true;
16
+ if (['0', 'false', 'no', 'n', 'off'].includes(v))
17
+ return false;
18
+ return defaultValue;
19
+ }
20
+ function sha256(text) {
21
+ return (0, node_crypto_1.createHash)('sha256').update(text).digest('hex');
22
+ }
23
+ function summarizeString(value) {
24
+ const maxLen = 200;
25
+ if (value.length <= maxLen)
26
+ return value;
27
+ return { truncated: true, length: value.length, sha256: sha256(value) };
28
+ }
29
+ function redactValue(value, keyPath) {
30
+ const key = keyPath[keyPath.length - 1] || '';
31
+ const lower = key.toLowerCase();
32
+ // Always redact env var values and similar.
33
+ if (lower === 'value')
34
+ return '[REDACTED]';
35
+ // Avoid logging SQL or params verbatim (may contain sensitive data).
36
+ if (lower === 'sql' && typeof value === 'string') {
37
+ return {
38
+ redacted: true,
39
+ bytes: Buffer.byteLength(value, 'utf8'),
40
+ sha256: sha256(value)
41
+ };
42
+ }
43
+ if (lower === 'params' && Array.isArray(value)) {
44
+ return value.map((v) => {
45
+ if (typeof v === 'string') {
46
+ return {
47
+ type: 'string',
48
+ bytes: Buffer.byteLength(v, 'utf8'),
49
+ sha256: sha256(v)
50
+ };
51
+ }
52
+ if (typeof v === 'number')
53
+ return { type: 'number' };
54
+ if (typeof v === 'boolean')
55
+ return { type: 'boolean' };
56
+ if (v === null)
57
+ return { type: 'null' };
58
+ if (Array.isArray(v))
59
+ return { type: 'array' };
60
+ if (typeof v === 'object')
61
+ return { type: 'object' };
62
+ return { type: typeof v };
63
+ });
64
+ }
65
+ // Redact common credential-like fields by name (avoid matching "key" which is often non-secret, e.g., S3 object keys).
66
+ if (/(secret|token|password|credential|authorization|cookie)/i.test(lower)) {
67
+ return '[REDACTED]';
68
+ }
69
+ if (typeof value === 'string')
70
+ return summarizeString(value);
71
+ return value;
72
+ }
73
+ function redactObject(value, keyPath = [], depth = 0) {
74
+ const maxDepth = 6;
75
+ if (depth > maxDepth)
76
+ return '[TRUNCATED]';
77
+ if (Array.isArray(value)) {
78
+ return value.map((v) => redactObject(v, keyPath, depth + 1));
79
+ }
80
+ if (value && typeof value === 'object') {
81
+ const out = {};
82
+ for (const [k, v] of Object.entries(value)) {
83
+ out[k] = redactObject(redactValue(v, [...keyPath, k]), [...keyPath, k], depth + 1);
84
+ }
85
+ return out;
86
+ }
87
+ return redactValue(value, keyPath);
88
+ }
89
+ function summarizeOutput(value) {
90
+ if (!value || typeof value !== 'object')
91
+ return value;
92
+ const obj = value;
93
+ // Avoid logging potentially large/sensitive payloads.
94
+ const denyKeys = new Set([
95
+ 'rows',
96
+ 'events',
97
+ 'logs',
98
+ 'content',
99
+ 'schema',
100
+ 'stdout',
101
+ 'stderr'
102
+ ]);
103
+ const allowKeys = new Set([
104
+ 'operation_id',
105
+ 'app_id',
106
+ 'stack_id',
107
+ 'addon_id',
108
+ 'account_id',
109
+ 'output_path',
110
+ 'migration_path',
111
+ 'count',
112
+ 'row_count',
113
+ 'row_count_returned',
114
+ 'row_count_reported',
115
+ 'bytes',
116
+ 'bytes_written',
117
+ 'command',
118
+ 'preview',
119
+ 'dangerous',
120
+ 'reasons',
121
+ 'truncated',
122
+ 'next_cursor',
123
+ 'next_cursor_token',
124
+ 'next_cursor_page_token',
125
+ 'next_page_token',
126
+ 'next_token'
127
+ ]);
128
+ const summary = {};
129
+ for (const [k, v] of Object.entries(obj)) {
130
+ if (denyKeys.has(k))
131
+ continue;
132
+ if (allowKeys.has(k))
133
+ summary[k] = redactObject(v, [k]);
134
+ }
135
+ // If nothing matched, at least return top-level keys (no values).
136
+ if (Object.keys(summary).length === 0) {
137
+ return { keys: Object.keys(obj).slice(0, 50) };
138
+ }
139
+ return summary;
140
+ }
141
+ function createAuditLogger({ stage, apiUrl }) {
142
+ const enabled = parseBoolEnv(process.env.SCALY_MCP_AUDIT, true);
143
+ const filePath = process.env.SCALY_MCP_AUDIT_FILE?.trim() || null;
144
+ const write = (event) => {
145
+ if (!enabled)
146
+ return;
147
+ const line = JSON.stringify(event);
148
+ if (filePath) {
149
+ try {
150
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(filePath), { recursive: true });
151
+ node_fs_1.default.appendFileSync(filePath, line + '\n', 'utf8');
152
+ return;
153
+ }
154
+ catch {
155
+ // Fall back to stderr if file writing fails.
156
+ }
157
+ }
158
+ console.error(line);
159
+ };
160
+ return {
161
+ enabled,
162
+ logToolCall: (e) => write({
163
+ kind: 'tool_call',
164
+ ts: new Date().toISOString(),
165
+ stage,
166
+ api_url: apiUrl,
167
+ ...e,
168
+ input: redactObject(e.input),
169
+ output: summarizeOutput(e.output)
170
+ }),
171
+ logResourceRead: (e) => write({
172
+ kind: 'resource_read',
173
+ ts: new Date().toISOString(),
174
+ stage,
175
+ api_url: apiUrl,
176
+ ...e,
177
+ input: redactObject(e.input),
178
+ output: summarizeOutput(e.output)
179
+ })
180
+ };
181
+ }
182
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { GraphQLClient } from 'graphql-request';
2
+ import type { Config } from './config.js';
3
+ export declare function initClient(config: Config): GraphQLClient;
4
+ export declare function initOidcClient(config: Config): GraphQLClient | null;
5
+ export declare function getClient(): GraphQLClient;
6
+ export declare function getOidcClient(): GraphQLClient;
7
+ export declare function query<T>(gql: string, variables?: Record<string, unknown>): Promise<T>;
8
+ export declare function oidcQuery<T>(gql: string, variables?: Record<string, unknown>): Promise<T>;
9
+ export declare const FRAGMENTS: {
10
+ app: string;
11
+ stack: string;
12
+ deployment: string;
13
+ scheduledJob: string;
14
+ jobRun: string;
15
+ };
16
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAK1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAYxD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAYnE;AAED,wBAAgB,SAAS,IAAI,aAAa,CAKzC;AAED,wBAAgB,aAAa,IAAI,aAAa,CAO7C;AAGD,wBAAsB,KAAK,CAAC,CAAC,EAC3B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC,CAWZ;AAGD,eAAO,MAAM,SAAS;;;;;;CA8DrB,CAAC"}
package/dist/client.js ADDED
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FRAGMENTS = void 0;
4
+ exports.initClient = initClient;
5
+ exports.initOidcClient = initOidcClient;
6
+ exports.getClient = getClient;
7
+ exports.getOidcClient = getOidcClient;
8
+ exports.query = query;
9
+ exports.oidcQuery = oidcQuery;
10
+ const graphql_request_1 = require("graphql-request");
11
+ let client = null;
12
+ let oidcClient = null;
13
+ function initClient(config) {
14
+ // Two-key auth:
15
+ // - x-api-key: AppSync API key (enables API access)
16
+ // - x-scaly-api-key: User's Scaly API key (for authorization/scopes)
17
+ client = new graphql_request_1.GraphQLClient(config.apiUrl, {
18
+ headers: {
19
+ 'x-api-key': config.appSyncApiKey,
20
+ 'x-scaly-api-key': config.scalyApiKey,
21
+ 'Content-Type': 'application/json'
22
+ }
23
+ });
24
+ return client;
25
+ }
26
+ function initOidcClient(config) {
27
+ if (!config.oidcToken)
28
+ return null;
29
+ oidcClient = new graphql_request_1.GraphQLClient(config.apiUrl, {
30
+ headers: {
31
+ // OIDC JWT auth for sensitive operations (DB/S3 execution tools)
32
+ authorization: `Bearer ${config.oidcToken}`,
33
+ // Keep AppSync key so the endpoint is reachable in all auth-mode configs
34
+ 'x-api-key': config.appSyncApiKey,
35
+ 'Content-Type': 'application/json'
36
+ }
37
+ });
38
+ return oidcClient;
39
+ }
40
+ function getClient() {
41
+ if (!client) {
42
+ throw new Error('GraphQL client not initialized. Call initClient first.');
43
+ }
44
+ return client;
45
+ }
46
+ function getOidcClient() {
47
+ if (!oidcClient) {
48
+ throw new Error('OIDC client not initialized. Set SCALY_OIDC_TOKEN and restart the MCP server.');
49
+ }
50
+ return oidcClient;
51
+ }
52
+ // GraphQL query/mutation helpers
53
+ async function query(gql, variables) {
54
+ const c = getClient();
55
+ try {
56
+ return await c.request(gql, variables);
57
+ }
58
+ catch (error) {
59
+ // Extract meaningful error message
60
+ const message = error?.response?.errors?.[0]?.message ||
61
+ error?.message ||
62
+ 'Unknown GraphQL error';
63
+ throw new Error(`Scaly API error: ${message}`);
64
+ }
65
+ }
66
+ async function oidcQuery(gql, variables) {
67
+ const c = getOidcClient();
68
+ try {
69
+ return await c.request(gql, variables);
70
+ }
71
+ catch (error) {
72
+ const message = error?.response?.errors?.[0]?.message ||
73
+ error?.message ||
74
+ 'Unknown GraphQL error';
75
+ throw new Error(`Scaly API error: ${message}`);
76
+ }
77
+ }
78
+ // Common GraphQL fragments - aligned with actual schema
79
+ exports.FRAGMENTS = {
80
+ app: `
81
+ fragment AppFields on App {
82
+ id
83
+ name
84
+ status
85
+ stackId
86
+ accountId
87
+ source
88
+ createdAt
89
+ updatedAt
90
+ }
91
+ `,
92
+ stack: `
93
+ fragment StackFields on Stack {
94
+ id
95
+ name
96
+ status
97
+ size
98
+ createdAt
99
+ updatedAt
100
+ }
101
+ `,
102
+ deployment: `
103
+ fragment DeploymentFields on Deployment {
104
+ id
105
+ status
106
+ resourceId
107
+ resourceType
108
+ createdAt
109
+ updatedAt
110
+ metadata
111
+ }
112
+ `,
113
+ scheduledJob: `
114
+ fragment ScheduledJobFields on ScheduledJob {
115
+ id
116
+ name
117
+ appId
118
+ command
119
+ schedule
120
+ timezone
121
+ status
122
+ lastRunAt
123
+ lastRunStatus
124
+ nextRunAt
125
+ createdAt
126
+ updatedAt
127
+ }
128
+ `,
129
+ jobRun: `
130
+ fragment JobRunFields on JobRun {
131
+ id
132
+ jobId
133
+ status
134
+ startedAt
135
+ finishedAt
136
+ exitCode
137
+ error
138
+ triggeredBy
139
+ }
140
+ `
141
+ };
142
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAMA,gCAYC;AAED,wCAYC;AAED,8BAKC;AAED,sCAOC;AAGD,sBAeC;AAED,8BAcC;AAlFD,qDAAgD;AAGhD,IAAI,MAAM,GAAyB,IAAI,CAAC;AACxC,IAAI,UAAU,GAAyB,IAAI,CAAC;AAE5C,SAAgB,UAAU,CAAC,MAAc;IACvC,gBAAgB;IAChB,oDAAoD;IACpD,qEAAqE;IACrE,MAAM,GAAG,IAAI,+BAAa,CAAC,MAAM,CAAC,MAAM,EAAE;QACxC,OAAO,EAAE;YACP,WAAW,EAAE,MAAM,CAAC,aAAa;YACjC,iBAAiB,EAAE,MAAM,CAAC,WAAW;YACrC,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,cAAc,CAAC,MAAc;IAC3C,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IACnC,UAAU,GAAG,IAAI,+BAAa,CAAC,MAAM,CAAC,MAAM,EAAE;QAC5C,OAAO,EAAE;YACP,iEAAiE;YACjE,aAAa,EAAE,UAAU,MAAM,CAAC,SAAS,EAAE;YAC3C,yEAAyE;YACzE,WAAW,EAAE,MAAM,CAAC,aAAa;YACjC,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAgB,SAAS;IACvB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,aAAa;IAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,iCAAiC;AAC1B,KAAK,UAAU,KAAK,CACzB,GAAW,EACX,SAAmC;IAEnC,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,CAAC,OAAO,CAAI,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,mCAAmC;QACnC,MAAM,OAAO,GACX,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO;YACrC,KAAK,EAAE,OAAO;YACd,uBAAuB,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,SAAmC;IAEnC,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,CAAC,OAAO,CAAI,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,OAAO,GACX,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO;YACrC,KAAK,EAAE,OAAO;YACd,uBAAuB,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,wDAAwD;AAC3C,QAAA,SAAS,GAAG;IACvB,GAAG,EAAE;;;;;;;;;;;GAWJ;IACD,KAAK,EAAE;;;;;;;;;GASN;IACD,UAAU,EAAE;;;;;;;;;;GAUX;IACD,YAAY,EAAE;;;;;;;;;;;;;;;GAeb;IACD,MAAM,EAAE;;;;;;;;;;;GAWP;CACF,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { z } from 'zod';
2
+ declare const ConfigSchema: z.ZodObject<{
3
+ scalyApiKey: z.ZodString;
4
+ appSyncApiKey: z.ZodString;
5
+ oidcToken: z.ZodOptional<z.ZodString>;
6
+ apiUrl: z.ZodString;
7
+ stage: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ apiUrl: string;
10
+ scalyApiKey: string;
11
+ appSyncApiKey: string;
12
+ stage?: string | undefined;
13
+ oidcToken?: string | undefined;
14
+ }, {
15
+ apiUrl: string;
16
+ scalyApiKey: string;
17
+ appSyncApiKey: string;
18
+ stage?: string | undefined;
19
+ oidcToken?: string | undefined;
20
+ }>;
21
+ export type Config = z.infer<typeof ConfigSchema>;
22
+ export declare function loadConfig(): Config;
23
+ export {};
24
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+BxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;EAMhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,wBAAgB,UAAU,IAAI,MAAM,CAgDnC"}
package/dist/config.js ADDED
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadConfig = loadConfig;
4
+ const zod_1 = require("zod");
5
+ // Stage-aware configuration
6
+ // AppSync API keys enable API access; Scaly API keys provide authorization/scopes.
7
+ // The MCP AppSync keys are stage-wide and safe to ship as defaults; users can override with SCALY_APPSYNC_KEY.
8
+ const STAGE_CONFIG = {
9
+ prod: {
10
+ apiUrl: 'https://api.scalyapps.io/graphql',
11
+ defaultAppSyncApiKey: 'da2-2veyt7vqrbaqbjio56tcgpbboe'
12
+ },
13
+ dev: {
14
+ apiUrl: 'https://api.dev.scalyapps.io/graphql',
15
+ defaultAppSyncApiKey: 'da2-ujszvu6uwbenxfbtuy6svpffxi'
16
+ },
17
+ qa: {
18
+ apiUrl: 'https://api.qa.scalyapps.io/graphql',
19
+ defaultAppSyncApiKey: 'da2-riqkqxfjpjfihewbm4e2buq2xm'
20
+ }
21
+ };
22
+ function normalizeStage(stage) {
23
+ const s = (stage || '').trim().toLowerCase();
24
+ if (!s)
25
+ return 'prod';
26
+ if (s === 'production')
27
+ return 'prod';
28
+ if (s === 'staging')
29
+ return 'qa';
30
+ return s;
31
+ }
32
+ const ConfigSchema = zod_1.z.object({
33
+ scalyApiKey: zod_1.z.string().min(1, 'SCALY_API_KEY is required'),
34
+ appSyncApiKey: zod_1.z.string().min(1, 'SCALY_APPSYNC_KEY is required'),
35
+ oidcToken: zod_1.z.string().optional(),
36
+ apiUrl: zod_1.z.string().url(),
37
+ stage: zod_1.z.string().optional()
38
+ });
39
+ function loadConfig() {
40
+ const scalyApiKey = process.env.SCALY_API_KEY;
41
+ const oidcToken = process.env.SCALY_OIDC_TOKEN;
42
+ const apiUrl = process.env.SCALY_API_URL;
43
+ const stage = normalizeStage(process.env.SCALY_STAGE);
44
+ if (!scalyApiKey) {
45
+ console.error('Error: SCALY_API_KEY environment variable is required.\n\n' +
46
+ 'Get your API key from: Scaly Dashboard → Account → Integrations → AI Assistant\n');
47
+ process.exit(1);
48
+ }
49
+ // Determine API URL: explicit > stage-based > prod default
50
+ const stageConfig = STAGE_CONFIG[stage] || STAGE_CONFIG.prod;
51
+ const resolvedUrl = apiUrl || stageConfig.apiUrl;
52
+ const appSyncApiKey = process.env.SCALY_APPSYNC_KEY || stageConfig.defaultAppSyncApiKey;
53
+ if (!appSyncApiKey) {
54
+ console.error('Error: SCALY_APPSYNC_KEY environment variable is required.\n\n' +
55
+ 'This is the stage-wide AppSync key for MCP access.\n' +
56
+ 'If you are using the Scaly hosted environments (prod/dev/qa), you can omit SCALY_APPSYNC_KEY.\n');
57
+ process.exit(1);
58
+ }
59
+ const result = ConfigSchema.safeParse({
60
+ scalyApiKey,
61
+ appSyncApiKey,
62
+ oidcToken,
63
+ apiUrl: resolvedUrl,
64
+ stage
65
+ });
66
+ if (!result.success) {
67
+ console.error('Configuration error:', result.error.format());
68
+ process.exit(1);
69
+ }
70
+ // Log which endpoint we're using (helps with debugging)
71
+ if (stage !== 'prod') {
72
+ console.error(`Using ${stage} environment: ${resolvedUrl}`);
73
+ }
74
+ return result.data;
75
+ }
76
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}