mcp-aiven 0.1.5 → 1.3.3

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 (93) hide show
  1. package/README.md +61 -0
  2. package/dist/client.d.ts +0 -1
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +6 -15
  5. package/dist/client.js.map +1 -1
  6. package/dist/config.d.ts +8 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +50 -2
  9. package/dist/config.js.map +1 -1
  10. package/dist/generated/aiven-api.d.ts +837 -77
  11. package/dist/generated/aiven-api.d.ts.map +1 -1
  12. package/dist/index.js +28 -13
  13. package/dist/index.js.map +1 -1
  14. package/dist/manifests/core.yaml +51 -14
  15. package/dist/manifests/integrations.yaml +14 -0
  16. package/dist/manifests/kafka.yaml +73 -3
  17. package/dist/manifests/pg.yaml +17 -0
  18. package/dist/observability.d.ts +7 -0
  19. package/dist/observability.d.ts.map +1 -0
  20. package/dist/observability.js +36 -0
  21. package/dist/observability.js.map +1 -0
  22. package/dist/prompts.d.ts +1 -1
  23. package/dist/prompts.d.ts.map +1 -1
  24. package/dist/prompts.js +9 -4
  25. package/dist/prompts.js.map +1 -1
  26. package/dist/tools/api-tool.d.ts.map +1 -1
  27. package/dist/tools/api-tool.js +22 -8
  28. package/dist/tools/api-tool.js.map +1 -1
  29. package/dist/tools/applications/handlers.d.ts.map +1 -1
  30. package/dist/tools/applications/handlers.js +32 -24
  31. package/dist/tools/applications/handlers.js.map +1 -1
  32. package/dist/tools/applications/schemas.d.ts +12 -0
  33. package/dist/tools/applications/schemas.d.ts.map +1 -1
  34. package/dist/tools/applications/schemas.js +5 -0
  35. package/dist/tools/applications/schemas.js.map +1 -1
  36. package/dist/tools/docs/handlers.d.ts +3 -0
  37. package/dist/tools/docs/handlers.d.ts.map +1 -0
  38. package/dist/tools/docs/handlers.js +62 -0
  39. package/dist/tools/docs/handlers.js.map +1 -0
  40. package/dist/tools/docs/index.d.ts +2 -0
  41. package/dist/tools/docs/index.d.ts.map +1 -0
  42. package/dist/tools/docs/index.js +2 -0
  43. package/dist/tools/docs/index.js.map +1 -0
  44. package/dist/tools/kafka/handlers.d.ts.map +1 -1
  45. package/dist/tools/kafka/handlers.js +12 -7
  46. package/dist/tools/kafka/handlers.js.map +1 -1
  47. package/dist/tools/kafka/schemas.d.ts +6 -0
  48. package/dist/tools/kafka/schemas.d.ts.map +1 -1
  49. package/dist/tools/kafka/schemas.js +3 -0
  50. package/dist/tools/kafka/schemas.js.map +1 -1
  51. package/dist/tools/pg/handlers.d.ts.map +1 -1
  52. package/dist/tools/pg/handlers.js +8 -1
  53. package/dist/tools/pg/handlers.js.map +1 -1
  54. package/dist/tools/pg/query.d.ts.map +1 -1
  55. package/dist/tools/pg/query.js +13 -14
  56. package/dist/tools/pg/query.js.map +1 -1
  57. package/dist/tools/pg/schemas.d.ts +9 -0
  58. package/dist/tools/pg/schemas.d.ts.map +1 -1
  59. package/dist/tools/pg/schemas.js +7 -0
  60. package/dist/tools/pg/schemas.js.map +1 -1
  61. package/dist/tools/registry.d.ts.map +1 -1
  62. package/dist/tools/registry.js +5 -0
  63. package/dist/tools/registry.js.map +1 -1
  64. package/dist/tools/response-filter.d.ts +5 -1
  65. package/dist/tools/response-filter.d.ts.map +1 -1
  66. package/dist/tools/response-filter.js +87 -11
  67. package/dist/tools/response-filter.js.map +1 -1
  68. package/dist/tools/service-search.d.ts +4 -0
  69. package/dist/tools/service-search.d.ts.map +1 -0
  70. package/dist/tools/service-search.js +127 -0
  71. package/dist/tools/service-search.js.map +1 -0
  72. package/dist/tools/shared-schemas.d.ts +5 -0
  73. package/dist/tools/shared-schemas.d.ts.map +1 -0
  74. package/dist/tools/shared-schemas.js +9 -0
  75. package/dist/tools/shared-schemas.js.map +1 -0
  76. package/dist/transport.d.ts +9 -4
  77. package/dist/transport.d.ts.map +1 -1
  78. package/dist/transport.js +36 -4
  79. package/dist/transport.js.map +1 -1
  80. package/dist/types.d.ts +19 -1
  81. package/dist/types.d.ts.map +1 -1
  82. package/dist/types.js +11 -0
  83. package/dist/types.js.map +1 -1
  84. package/dist/untrusted.d.ts +8 -0
  85. package/dist/untrusted.d.ts.map +1 -0
  86. package/dist/untrusted.js +19 -0
  87. package/dist/untrusted.js.map +1 -0
  88. package/generator/schemas/api-schemas.json +28 -30
  89. package/package.json +4 -3
  90. package/src/manifests/core.yaml +51 -14
  91. package/src/manifests/integrations.yaml +14 -0
  92. package/src/manifests/kafka.yaml +73 -3
  93. package/src/manifests/pg.yaml +17 -0
package/README.md CHANGED
@@ -56,6 +56,42 @@ Add to `.vscode/mcp.json` in your workspace:
56
56
  }
57
57
  ```
58
58
 
59
+ #### Read-Only Mode (Remote)
60
+
61
+ Enable read-only mode by adding `?read_only=true` to the URL. All write operations will be excluded from the MCP:
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "aiven-mcp": {
67
+ "url": "https://mcp.aiven.live/mcp?read_only=true"
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ #### Scoped Tools (Remote)
74
+
75
+ Reduce the tool surface exposed to your AI agent by adding `?services_scope=` to the URL. Useful when you only work with a subset of Aiven services and want to keep the agent's context focused. Combine values with commas. `core` (project/service discovery) is always included implicitly.
76
+
77
+ Valid scopes: `all`, `core`, `pg`, `kafka`, `application`, `integrations`. Use `all` to explicitly load every tool (same as omitting the param). `all` cannot be combined with other scopes.
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "aiven-mcp": {
83
+ "url": "https://mcp.aiven.live/mcp?services_scope=kafka"
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ You can also combine with `read_only`:
90
+
91
+ ```
92
+ https://mcp.aiven.live/mcp?services_scope=pg&read_only=true
93
+ ```
94
+
59
95
  ### Option 2: stdio (local)
60
96
 
61
97
  Run the server locally as a child process of your MCP client. Requires Node.js 18+.
@@ -88,12 +124,31 @@ Config file locations:
88
124
  - Cursor: Cursor Settings > MCP Servers
89
125
  - VS Code: `.vscode/mcp.json` in your workspace
90
126
 
127
+ ### Option 3: Local development
128
+
129
+ Run a local build of the server (useful for development and testing):
130
+
131
+ ```bash
132
+ pnpm install && pnpm generate:api-types && pnpm generate && pnpm build && AIVEN_TOKEN="<YOUR_TOKEN>" MCP_TRANSPORT="http" PORT=3000 node dist/index.js
133
+ ```
134
+
135
+ The server listens on port 3000 by default. Connect your MCP client to `http://localhost:3000/mcp`.
136
+
137
+ To point a remote deployment at a custom host (e.g. your local build), set `MCP_HOST`:
138
+
139
+ ```bash
140
+ MCP_HOST=http://localhost:3000 node dist/index.js
141
+ ```
142
+
91
143
  ### Environment Variables
92
144
 
93
145
  | Variable | Required | Default | Description |
94
146
  |---|---|---|---|
95
147
  | `AIVEN_TOKEN` | stdio only | -- | Aiven API token ([create one here](https://console.aiven.io/profile/tokens)) |
96
148
  | `AIVEN_READ_ONLY` | No | `false` | Set to `true` to expose only read-only tools |
149
+ | `AIVEN_SERVICES_SCOPE` | No | -- | Comma-separated scopes to expose (e.g. `kafka`, `pg,kafka`, or `all`). Valid: `all`, `core`, `pg`, `kafka`, `application`, `integrations`. `core` is always included. Omitting the var or setting `all` loads every tool. |
150
+ | `MCP_HOST` | No | `https://mcp.aiven.live` | Override the OAuth protected resource host |
151
+ | `MCP_TRANSPORT` | No | `stdio` | Set to `http` to start an HTTP server instead of stdio |
97
152
 
98
153
  In remote (HTTP) mode, `AIVEN_TOKEN` is not needed. Your MCP client sends your token as a Bearer token with each request.
99
154
 
@@ -164,6 +219,12 @@ In remote (HTTP) mode, `AIVEN_TOKEN` is not needed. Your MCP client sends your t
164
219
  | `aiven_vcs_integration_list` | List connected VCS (GitHub) accounts |
165
220
  | `aiven_vcs_integration_repository_list` | List repositories for a VCS integration |
166
221
 
222
+ ### Documentation
223
+
224
+ | Tool | Description |
225
+ |---|---|
226
+ | `aiven_docs_search` | Search the official Aiven documentation in natural language. Only available on the hosted server (`https://mcp.aiven.live/mcp`) — not exposed in self-hosted deployments. |
227
+
167
228
  ## Contributing
168
229
 
169
230
  See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, running locally, and adding new tools.
package/dist/client.d.ts CHANGED
@@ -6,7 +6,6 @@ export declare class AivenClient {
6
6
  private readonly fetchClient;
7
7
  constructor(config: AivenConfig);
8
8
  request<T>(method: HttpMethod, path: string, body?: unknown, options?: RequestOptions): Promise<T>;
9
- private logAivenRequest;
10
9
  private buildHeaders;
11
10
  get<T>(path: string, options?: RequestOptions): Promise<T>;
12
11
  post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI1E,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;gBAEzD,MAAM,EAAE,WAAW;IAczB,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,CAAC,CAAC;IAyCb,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,YAAY;IAcd,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI3E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1E,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;CAGpE"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI1E,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;gBAEzD,MAAM,EAAE,WAAW;IAczB,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,CAAC,CAAC;IAwCb,OAAO,CAAC,YAAY;IAoBd,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI3E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1E,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;CAGpE"}
package/dist/client.js CHANGED
@@ -26,7 +26,6 @@ export class AivenClient {
26
26
  }
27
27
  const timeout = options?.timeout ?? this.defaultTimeout;
28
28
  const perRequestHeaders = this.buildHeaders(token, options);
29
- this.logAivenRequest(method, path, perRequestHeaders);
30
29
  const result = (await this.fetchClient.request(method.toLowerCase(), path, {
31
30
  params: options?.query ? { query: options.query } : undefined,
32
31
  body: body,
@@ -41,20 +40,6 @@ export class AivenClient {
41
40
  }
42
41
  return result.data;
43
42
  }
44
- logAivenRequest(method, path, perRequestHeaders) {
45
- const url = `${API_BASE_URL}${path.startsWith('/') ? path : `/${path}`}`;
46
- const merged = {
47
- 'Content-Type': 'application/json',
48
- Accept: 'application/json',
49
- 'User-Agent': `mcp-aiven/${VERSION}`,
50
- ...perRequestHeaders,
51
- };
52
- const forLog = { ...merged };
53
- if (forLog['Authorization']?.startsWith('Bearer ')) {
54
- forLog['Authorization'] = 'Bearer [REDACTED]';
55
- }
56
- console.error('mcp-aiven: Aiven request %s %s headers=%s', method, url, JSON.stringify(forLog));
57
- }
58
43
  buildHeaders(token, options) {
59
44
  const headers = {
60
45
  Authorization: `Bearer ${token}`,
@@ -66,6 +51,12 @@ export class AivenClient {
66
51
  if (options?.mcpClient) {
67
52
  headers['X-MCP-Client'] = options.mcpClient;
68
53
  }
54
+ if (options?.requestId) {
55
+ headers['X-MCP-Request-ID'] = options.requestId;
56
+ }
57
+ if (options?.toolReasoning) {
58
+ headers['X-MCP-Tool-Reasoning'] = options.toolReasoning;
59
+ }
69
60
  return headers;
70
61
  }
71
62
  async get(path, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import type { AivenConfig } from './types.js';
2
+ import { ServiceCategory } from './types.js';
2
3
  export declare const VERSION: string;
3
4
  export declare const API_ORIGIN: string;
4
5
  export declare const API_BASE_URL: string;
5
- export declare const HOST = "https://mcp.aiven.live";
6
+ export declare const HOST: string;
6
7
  /** HTTP POST /mcp rate limit (per bearer token hash, else per client IP). */
7
8
  export interface HttpMcpRateLimitConfig {
8
9
  windowMs: number;
@@ -11,5 +12,11 @@ export interface HttpMcpRateLimitConfig {
11
12
  export declare function loadHttpMcpRateLimit(): HttpMcpRateLimitConfig;
12
13
  /** When true, Express honors X-Forwarded-For for req.ip (use behind a reverse proxy). */
13
14
  export declare function httpTrustProxyEnabled(): boolean;
15
+ export declare const VALID_SCOPES: readonly string[];
16
+ export declare function parseScopes(raw: string | undefined): {
17
+ categories: ReadonlySet<ServiceCategory> | undefined;
18
+ } | {
19
+ error: string;
20
+ };
14
21
  export declare function loadConfig(transport?: 'stdio' | 'http'): AivenConfig;
15
22
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C,eAAO,MAAM,OAAO,QAAc,CAAC;AACnC,eAAO,MAAM,UAAU,QAA4D,CAAC;AACpF,eAAO,MAAM,YAAY,QAAqB,CAAC;AAC/C,eAAO,MAAM,IAAI,2BAA2B,CAAA;AAE5C,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AASD,wBAAgB,oBAAoB,IAAI,sBAAsB,CAK7D;AAED,yFAAyF;AACzF,wBAAgB,qBAAqB,IAAI,OAAO,CAG/C;AAED,wBAAgB,UAAU,CAAC,SAAS,GAAE,OAAO,GAAG,MAAgB,GAAG,WAAW,CAa7E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI7C,eAAO,MAAM,OAAO,QAAc,CAAC;AACnC,eAAO,MAAM,UAAU,QAA4D,CAAC;AACpF,eAAO,MAAM,YAAY,QAAqB,CAAC;AAC/C,eAAO,MAAM,IAAI,QAAsD,CAAC;AAExE,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AASD,wBAAgB,oBAAoB,IAAI,sBAAsB,CAK7D;AAED,yFAAyF;AACzF,wBAAgB,qBAAqB,IAAI,OAAO,CAG/C;AAcD,eAAO,MAAM,YAAY,mBAA4D,CAAC;AAEtF,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB;IAAE,UAAU,EAAE,WAAW,CAAC,eAAe,CAAC,GAAG,SAAS,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAiC9E;AAED,wBAAgB,UAAU,CAAC,SAAS,GAAE,OAAO,GAAG,MAAgB,GAAG,WAAW,CAkB7E"}
package/dist/config.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { createRequire } from 'node:module';
2
+ import { ServiceCategory } from './types.js';
2
3
  const require = createRequire(import.meta.url);
3
4
  const pkg = require('../package.json');
4
5
  export const VERSION = pkg.version;
5
6
  export const API_ORIGIN = process.env['AIVEN_API_ORIGIN'] ?? 'https://api.aiven.io';
6
7
  export const API_BASE_URL = `${API_ORIGIN}/v1`;
7
- export const HOST = 'https://mcp.aiven.live';
8
+ export const HOST = process.env['MCP_HOST'] ?? 'https://mcp.aiven.live';
8
9
  function parsePositiveIntEnv(name, defaultValue) {
9
10
  const raw = process.env[name];
10
11
  if (raw === undefined || raw === '')
@@ -23,6 +24,49 @@ export function httpTrustProxyEnabled() {
23
24
  const v = process.env['MCP_TRUST_PROXY'];
24
25
  return v === '1' || v === 'true';
25
26
  }
27
+ /**
28
+ * User-selectable scope names. Maps to ServiceCategory; `core` is always implicitly included
29
+ * because every other category depends on `aiven_project_list` / `aiven_service_get` etc.
30
+ */
31
+ const SCOPE_TO_CATEGORY = {
32
+ core: ServiceCategory.Core,
33
+ pg: ServiceCategory.Pg,
34
+ kafka: ServiceCategory.Kafka,
35
+ application: ServiceCategory.Application,
36
+ integrations: ServiceCategory.Integrations,
37
+ };
38
+ export const VALID_SCOPES = Object.freeze(['all', ...Object.keys(SCOPE_TO_CATEGORY)]);
39
+ export function parseScopes(raw) {
40
+ if (raw === undefined)
41
+ return { categories: undefined };
42
+ const parts = raw
43
+ .split(',')
44
+ .map((s) => s.trim())
45
+ .filter((s) => s.length > 0);
46
+ if (parts.length === 0) {
47
+ return { error: `Empty scope list. Valid scopes: ${VALID_SCOPES.join(', ')}` };
48
+ }
49
+ if (parts.includes('all')) {
50
+ if (parts.length > 1) {
51
+ return { error: `'all' cannot be combined with other scopes` };
52
+ }
53
+ return { categories: undefined };
54
+ }
55
+ const unknown = parts.filter((p) => !(p in SCOPE_TO_CATEGORY));
56
+ if (unknown.length > 0) {
57
+ return {
58
+ error: `Unknown scope(s): ${unknown.join(', ')}. Valid scopes: ${VALID_SCOPES.join(', ')}`,
59
+ };
60
+ }
61
+ const set = new Set();
62
+ set.add(ServiceCategory.Core);
63
+ for (const p of parts) {
64
+ const cat = SCOPE_TO_CATEGORY[p];
65
+ if (cat)
66
+ set.add(cat);
67
+ }
68
+ return { categories: set };
69
+ }
26
70
  export function loadConfig(transport = 'stdio') {
27
71
  const token = process.env['AIVEN_TOKEN'];
28
72
  if (!token && transport !== 'http') {
@@ -30,6 +74,10 @@ export function loadConfig(transport = 'stdio') {
30
74
  'Get your token from: https://console.aiven.io/profile/auth');
31
75
  }
32
76
  const readOnly = process.env['AIVEN_READ_ONLY'] === 'true';
33
- return { token, readOnly, transport };
77
+ const parsed = parseScopes(process.env['AIVEN_SERVICES_SCOPE']);
78
+ if ('error' in parsed) {
79
+ throw new Error(`AIVEN_SERVICES_SCOPE: ${parsed.error}`);
80
+ }
81
+ return { token, readOnly, transport, categories: parsed.categories };
34
82
  }
35
83
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAC9D,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,sBAAsB,CAAC;AACpF,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,UAAU,KAAK,CAAC;AAC/C,MAAM,CAAC,MAAM,IAAI,GAAG,wBAAwB,CAAA;AAQ5C,SAAS,mBAAmB,CAAC,IAAY,EAAE,YAAoB;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,YAAY,CAAC;IACzD,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,QAAQ,EAAE,mBAAmB,CAAC,+BAA+B,EAAE,MAAM,CAAC;QACtE,KAAK,EAAE,mBAAmB,CAAC,yBAAyB,EAAE,GAAG,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,qBAAqB;IACnC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACzC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,MAAM,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAA8B,OAAO;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAEzC,IAAI,CAAC,KAAK,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,iDAAiD;YAC/C,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,MAAM,CAAC;IAE3D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}