@pecot/tools-mcp 0.0.0-stage → 1.0.1

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 (71) hide show
  1. package/.claude-plugin/plugin.json +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +113 -2
  4. package/bin/pecot-tools-mcp.mjs +10 -0
  5. package/cli/dist/cli.d.ts +9 -0
  6. package/cli/dist/cli.js +65 -0
  7. package/cli/dist/domain/allowlist.d.ts +228 -0
  8. package/cli/dist/domain/allowlist.js +657 -0
  9. package/cli/dist/domain/arguments.d.ts +37 -0
  10. package/cli/dist/domain/arguments.js +453 -0
  11. package/cli/dist/domain/athena-query.d.ts +22 -0
  12. package/cli/dist/domain/athena-query.js +191 -0
  13. package/cli/dist/domain/failure.d.ts +22 -0
  14. package/cli/dist/domain/failure.js +99 -0
  15. package/cli/dist/domain/redact.d.ts +5 -0
  16. package/cli/dist/domain/redact.js +38 -0
  17. package/cli/dist/domain/s3-input.d.ts +20 -0
  18. package/cli/dist/domain/s3-input.js +50 -0
  19. package/cli/dist/domain/sso-output.d.ts +23 -0
  20. package/cli/dist/domain/sso-output.js +70 -0
  21. package/cli/dist/infra/awscli.d.ts +104 -0
  22. package/cli/dist/infra/awscli.js +245 -0
  23. package/cli/dist/infra/ignore-rejection.d.ts +6 -0
  24. package/cli/dist/infra/ignore-rejection.js +13 -0
  25. package/cli/dist/infra/local-file.d.ts +9 -0
  26. package/cli/dist/infra/local-file.js +21 -0
  27. package/cli/dist/infra/sso/login-registry.d.ts +99 -0
  28. package/cli/dist/infra/sso/login-registry.js +314 -0
  29. package/cli/dist/mcp/executor.d.ts +14 -0
  30. package/cli/dist/mcp/executor.js +44 -0
  31. package/cli/dist/mcp/result.d.ts +57 -0
  32. package/cli/dist/mcp/result.js +53 -0
  33. package/cli/dist/mcp/serve.d.ts +70 -0
  34. package/cli/dist/mcp/serve.js +185 -0
  35. package/cli/dist/mcp/server.d.ts +69 -0
  36. package/cli/dist/mcp/server.js +115 -0
  37. package/cli/dist/mcp/tools/_shared.d.ts +141 -0
  38. package/cli/dist/mcp/tools/_shared.js +290 -0
  39. package/cli/dist/mcp/tools/athena.d.ts +4 -0
  40. package/cli/dist/mcp/tools/athena.js +82 -0
  41. package/cli/dist/mcp/tools/cloudwatch.d.ts +4 -0
  42. package/cli/dist/mcp/tools/cloudwatch.js +46 -0
  43. package/cli/dist/mcp/tools/ec2.d.ts +4 -0
  44. package/cli/dist/mcp/tools/ec2.js +31 -0
  45. package/cli/dist/mcp/tools/ecr.d.ts +4 -0
  46. package/cli/dist/mcp/tools/ecr.js +37 -0
  47. package/cli/dist/mcp/tools/index.d.ts +7 -0
  48. package/cli/dist/mcp/tools/index.js +37 -0
  49. package/cli/dist/mcp/tools/lambda.d.ts +4 -0
  50. package/cli/dist/mcp/tools/lambda.js +36 -0
  51. package/cli/dist/mcp/tools/logs.d.ts +4 -0
  52. package/cli/dist/mcp/tools/logs.js +74 -0
  53. package/cli/dist/mcp/tools/rds.d.ts +4 -0
  54. package/cli/dist/mcp/tools/rds.js +60 -0
  55. package/cli/dist/mcp/tools/s3.d.ts +4 -0
  56. package/cli/dist/mcp/tools/s3.js +96 -0
  57. package/cli/dist/mcp/tools/scheduler.d.ts +4 -0
  58. package/cli/dist/mcp/tools/scheduler.js +44 -0
  59. package/cli/dist/mcp/tools/sqs.d.ts +4 -0
  60. package/cli/dist/mcp/tools/sqs.js +33 -0
  61. package/cli/dist/mcp/tools/sso.d.ts +11 -0
  62. package/cli/dist/mcp/tools/sso.js +240 -0
  63. package/cli/dist/mcp/tools/sts.d.ts +4 -0
  64. package/cli/dist/mcp/tools/sts.js +15 -0
  65. package/cli/dist/node-runtime.d.ts +20 -0
  66. package/cli/dist/node-runtime.js +84 -0
  67. package/cli/dist/package.json +1 -0
  68. package/cli/dist/version.d.ts +19 -0
  69. package/cli/dist/version.js +44 -0
  70. package/npm-shrinkwrap.json +67 -0
  71. package/package.json +21 -4
@@ -0,0 +1,657 @@
1
+ // 許可リストの型と実体。公開する awscli コマンドは全てここで静的に宣言し、
2
+ // ツール実装(mcp/tools/*)はこの宣言からしか引数を組み立てない。
3
+ //
4
+ // エントリの並びは contracts/mcp-tools.md の表の順で、そのまま tools/list の並びになる。
5
+ // 系統ごとの配列に分けてから ALLOWLIST へ連結する(1 系統を足すときに触る範囲が閉じる)。
6
+ /**
7
+ `profile` の書式。data-model.md の `^[A-Za-z0-9_.-]+$` と同値(`\w` = `[A-Za-z0-9_]`)。
8
+
9
+ inputSchema へ載せる mcp 層も同じ定数を読む。書式の定義をここ 1 箇所に保つため。
10
+ */
11
+ export const PROFILE_PATTERN = /^[\w.-]+$/;
12
+ /**
13
+ `region` の書式(`ap-northeast-1` 等)。
14
+
15
+ 先頭は 2〜4 文字。European Sovereign Cloud の `eusc-de-east-1` が 4 文字始まりで、
16
+ 2 文字固定だと入力検証エラーで弾かれる。
17
+ 契約書の共通規約も `^[a-z]{2,4}(-[a-z]+)+-\d$` で、本パターンと一致している。
18
+ 契約書は specs/012-awscli-mcp-server/contracts/mcp-tools.md を指す。
19
+ */
20
+ // eslint-disable-next-line security/detect-unsafe-regex -- 繰り返し部の先頭 '-' は内側の文字クラスに無く backtracking しない
21
+ export const REGION_PATTERN = /^[a-z]{2,4}(?:-[a-z]+)+-\d$/;
22
+ /**
23
+ ISO 8601 の日時(`2026-09-01T00:00Z` / `2026-09-01T00:00:00.000+09:00`)。
24
+
25
+ CloudWatch と RDS の timestamp 引数はこの書式で渡す。CloudWatch Logs 系の epoch ミリ秒
26
+ (integer)とは型が異なるので、契約と description にも「ISO 8601」と明記している。
27
+ `Z` とオフセット付きの双方を awscli 2.36.40 が正しく変換することを動作確認済み。
28
+ */
29
+ // eslint-disable-next-line security/detect-unsafe-regex -- 任意の繰り返しは `(?:\.\d+)?` の 1 段だけ。直前が固定文字 '.' で、直後は Z かオフセットの固定長。入れ子が無く backtracking しない
30
+ export const TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:\d{2})$/;
31
+ /**
32
+ 全エントリ共通の任意入力 `profile`。
33
+ */
34
+ export const PROFILE_INPUT = {
35
+ name: 'profile',
36
+ kind: 'string',
37
+ required: false,
38
+ awsFlag: '--profile',
39
+ pattern: PROFILE_PATTERN,
40
+ };
41
+ /**
42
+ 全エントリ共通の任意入力 `region`。
43
+ */
44
+ export const REGION_INPUT = {
45
+ name: 'region',
46
+ kind: 'string',
47
+ required: false,
48
+ awsFlag: '--region',
49
+ pattern: REGION_PATTERN,
50
+ };
51
+ /**
52
+ ページング列が `max-items` のエントリが共通で持つ入力(契約の共通規約)。
53
+ */
54
+ const MAX_ITEMS_INPUTS = [
55
+ { name: 'max_items', kind: 'integer', required: false, awsFlag: '--max-items', min: 1 },
56
+ { name: 'starting_token', kind: 'string', required: false, awsFlag: '--starting-token' },
57
+ ];
58
+ export const STS_GET_CALLER_IDENTITY = {
59
+ toolName: 'aws_sts_get_caller_identity',
60
+ service: 'sts',
61
+ subcommand: 'get-caller-identity',
62
+ kind: 'read',
63
+ jsonOutput: true,
64
+ pagination: 'none',
65
+ inputs: [],
66
+ };
67
+ const STS_ENTRIES = [STS_GET_CALLER_IDENTITY];
68
+ export const LAMBDA_LIST_FUNCTIONS = {
69
+ toolName: 'aws_lambda_list_functions',
70
+ service: 'lambda',
71
+ subcommand: 'list-functions',
72
+ kind: 'read',
73
+ jsonOutput: true,
74
+ pagination: 'max-items',
75
+ inputs: [...MAX_ITEMS_INPUTS],
76
+ };
77
+ export const LAMBDA_GET_FUNCTION_CONFIGURATION = {
78
+ toolName: 'aws_lambda_get_function_configuration',
79
+ service: 'lambda',
80
+ subcommand: 'get-function-configuration',
81
+ kind: 'read',
82
+ jsonOutput: true,
83
+ pagination: 'none',
84
+ inputs: [
85
+ { name: 'function_name', kind: 'string', required: true, awsFlag: '--function-name' },
86
+ { name: 'qualifier', kind: 'string', required: false, awsFlag: '--qualifier' },
87
+ ],
88
+ };
89
+ /**
90
+ `lambda list-event-source-mappings`。
91
+
92
+ 関数とイベントソース(SQS キュー等)の対応を引くために使う。`--event-source-arn` と
93
+ `--function-name` は、片方だけでも両方でも指定できる。
94
+ */
95
+ export const LAMBDA_LIST_EVENT_SOURCE_MAPPINGS = {
96
+ toolName: 'aws_lambda_list_event_source_mappings',
97
+ service: 'lambda',
98
+ subcommand: 'list-event-source-mappings',
99
+ kind: 'read',
100
+ jsonOutput: true,
101
+ pagination: 'max-items',
102
+ inputs: [
103
+ {
104
+ name: 'event_source_arn',
105
+ kind: 'string',
106
+ required: false,
107
+ awsFlag: '--event-source-arn',
108
+ pattern: /^arn:/,
109
+ },
110
+ { name: 'function_name', kind: 'string', required: false, awsFlag: '--function-name' },
111
+ ...MAX_ITEMS_INPUTS,
112
+ ],
113
+ };
114
+ const LAMBDA_ENTRIES = [
115
+ LAMBDA_LIST_FUNCTIONS,
116
+ LAMBDA_GET_FUNCTION_CONFIGURATION,
117
+ LAMBDA_LIST_EVENT_SOURCE_MAPPINGS,
118
+ ];
119
+ export const LOGS_DESCRIBE_LOG_GROUPS = {
120
+ toolName: 'aws_logs_describe_log_groups',
121
+ service: 'logs',
122
+ subcommand: 'describe-log-groups',
123
+ kind: 'read',
124
+ jsonOutput: true,
125
+ pagination: 'max-items',
126
+ inputs: [
127
+ { name: 'log_group_name_prefix', kind: 'string', required: false, awsFlag: '--log-group-name-prefix' },
128
+ ...MAX_ITEMS_INPUTS,
129
+ ],
130
+ };
131
+ export const LOGS_DESCRIBE_LOG_STREAMS = {
132
+ toolName: 'aws_logs_describe_log_streams',
133
+ service: 'logs',
134
+ subcommand: 'describe-log-streams',
135
+ kind: 'read',
136
+ jsonOutput: true,
137
+ pagination: 'max-items',
138
+ inputs: [
139
+ { name: 'log_group_name', kind: 'string', required: true, awsFlag: '--log-group-name' },
140
+ { name: 'log_stream_name_prefix', kind: 'string', required: false, awsFlag: '--log-stream-name-prefix' },
141
+ {
142
+ name: 'order_by',
143
+ kind: 'enum',
144
+ required: false,
145
+ awsFlag: '--order-by',
146
+ values: ['LogStreamName', 'LastEventTime'],
147
+ },
148
+ { name: 'descending', kind: 'boolean', required: false, awsFlag: '--descending', default: false },
149
+ ...MAX_ITEMS_INPUTS,
150
+ ],
151
+ };
152
+ export const LOGS_GET_LOG_EVENTS = {
153
+ toolName: 'aws_logs_get_log_events',
154
+ service: 'logs',
155
+ subcommand: 'get-log-events',
156
+ kind: 'read',
157
+ jsonOutput: true,
158
+ pagination: 'limit-next-token',
159
+ inputs: [
160
+ { name: 'log_group_name', kind: 'string', required: true, awsFlag: '--log-group-name' },
161
+ { name: 'log_stream_name', kind: 'string', required: true, awsFlag: '--log-stream-name' },
162
+ { name: 'start_time', kind: 'integer', required: false, awsFlag: '--start-time' },
163
+ { name: 'end_time', kind: 'integer', required: false, awsFlag: '--end-time' },
164
+ { name: 'limit', kind: 'integer', required: false, awsFlag: '--limit', min: 1, max: 10_000 },
165
+ { name: 'next_token', kind: 'string', required: false, awsFlag: '--next-token' },
166
+ { name: 'start_from_head', kind: 'boolean', required: false, awsFlag: '--start-from-head', default: false },
167
+ ],
168
+ };
169
+ export const LOGS_FILTER_LOG_EVENTS = {
170
+ toolName: 'aws_logs_filter_log_events',
171
+ service: 'logs',
172
+ subcommand: 'filter-log-events',
173
+ kind: 'read',
174
+ jsonOutput: true,
175
+ pagination: 'max-items',
176
+ inputs: [
177
+ { name: 'log_group_name', kind: 'string', required: true, awsFlag: '--log-group-name' },
178
+ { name: 'log_stream_names', kind: 'string-list', required: false, awsFlag: '--log-stream-names' },
179
+ { name: 'log_stream_name_prefix', kind: 'string', required: false, awsFlag: '--log-stream-name-prefix' },
180
+ { name: 'filter_pattern', kind: 'string', required: false, awsFlag: '--filter-pattern' },
181
+ { name: 'start_time', kind: 'integer', required: false, awsFlag: '--start-time' },
182
+ { name: 'end_time', kind: 'integer', required: false, awsFlag: '--end-time' },
183
+ ...MAX_ITEMS_INPUTS,
184
+ ],
185
+ exclusive: [['log_stream_names', 'log_stream_name_prefix']],
186
+ };
187
+ const LOGS_ENTRIES = [
188
+ LOGS_DESCRIBE_LOG_GROUPS,
189
+ LOGS_DESCRIBE_LOG_STREAMS,
190
+ LOGS_GET_LOG_EVENTS,
191
+ LOGS_FILTER_LOG_EVENTS,
192
+ ];
193
+ /**
194
+ CloudWatch の標準単位(`--unit` の候補。awscli 2.36.40)。
195
+
196
+ 許可リストの `values` と mcp 層の `z.enum`、契約テストが同じ配列を読む。3 箇所に写すと
197
+ 綴りがずれるので定義をここ 1 箇所に置く。`z.enum` は非空タプルを要求するため型注釈を付ける。
198
+ */
199
+ export const CLOUDWATCH_UNIT_VALUES = [
200
+ 'Seconds', 'Microseconds', 'Milliseconds',
201
+ 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes',
202
+ 'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits',
203
+ 'Percent', 'Count',
204
+ 'Bytes/Second', 'Kilobytes/Second', 'Megabytes/Second', 'Gigabytes/Second',
205
+ 'Terabytes/Second',
206
+ 'Bits/Second', 'Kilobits/Second', 'Megabits/Second', 'Gigabits/Second',
207
+ 'Terabits/Second',
208
+ 'Count/Second', 'None',
209
+ ];
210
+ /**
211
+ `cloudwatch get-metric-statistics`。
212
+
213
+ `--statistics` を必須にすることで `--extended-statistics`(パーセンタイル)を公開しない形に
214
+ 閉じている。API は双方の同時指定を拒否するため、片方だけを公開すれば足りる。
215
+ */
216
+ export const CLOUDWATCH_GET_METRIC_STATISTICS = {
217
+ toolName: 'aws_cloudwatch_get_metric_statistics',
218
+ service: 'cloudwatch',
219
+ subcommand: 'get-metric-statistics',
220
+ kind: 'read',
221
+ jsonOutput: true,
222
+ pagination: 'none',
223
+ inputs: [
224
+ { name: 'namespace', kind: 'string', required: true, awsFlag: '--namespace' },
225
+ { name: 'metric_name', kind: 'string', required: true, awsFlag: '--metric-name' },
226
+ {
227
+ name: 'dimensions',
228
+ kind: 'shorthand-list',
229
+ required: false,
230
+ awsFlag: '--dimensions',
231
+ elements: [{ key: 'Name', field: 'name' }, { key: 'Value', field: 'value' }],
232
+ },
233
+ {
234
+ name: 'start_time',
235
+ kind: 'string',
236
+ required: true,
237
+ awsFlag: '--start-time',
238
+ pattern: TIMESTAMP_PATTERN,
239
+ },
240
+ {
241
+ name: 'end_time',
242
+ kind: 'string',
243
+ required: true,
244
+ awsFlag: '--end-time',
245
+ pattern: TIMESTAMP_PATTERN,
246
+ },
247
+ { name: 'period', kind: 'integer', required: true, awsFlag: '--period', min: 1 },
248
+ {
249
+ name: 'statistics',
250
+ kind: 'string-list',
251
+ required: true,
252
+ awsFlag: '--statistics',
253
+ values: ['SampleCount', 'Average', 'Sum', 'Minimum', 'Maximum'],
254
+ },
255
+ {
256
+ name: 'unit',
257
+ kind: 'enum',
258
+ required: false,
259
+ awsFlag: '--unit',
260
+ values: CLOUDWATCH_UNIT_VALUES,
261
+ },
262
+ ],
263
+ };
264
+ const CLOUDWATCH_ENTRIES = [CLOUDWATCH_GET_METRIC_STATISTICS];
265
+ export const SQS_LIST_QUEUES = {
266
+ toolName: 'aws_sqs_list_queues',
267
+ service: 'sqs',
268
+ subcommand: 'list-queues',
269
+ kind: 'read',
270
+ jsonOutput: true,
271
+ pagination: 'max-items',
272
+ inputs: [
273
+ { name: 'queue_name_prefix', kind: 'string', required: false, awsFlag: '--queue-name-prefix' },
274
+ ...MAX_ITEMS_INPUTS,
275
+ ],
276
+ };
277
+ export const SQS_GET_QUEUE_ATTRIBUTES = {
278
+ toolName: 'aws_sqs_get_queue_attributes',
279
+ service: 'sqs',
280
+ subcommand: 'get-queue-attributes',
281
+ kind: 'read',
282
+ jsonOutput: true,
283
+ pagination: 'none',
284
+ inputs: [
285
+ { name: 'queue_url', kind: 'string', required: true, awsFlag: '--queue-url', pattern: /^https:\/\// },
286
+ {
287
+ name: 'attribute_names',
288
+ kind: 'string-list',
289
+ required: false,
290
+ awsFlag: '--attribute-names',
291
+ default: ['All'],
292
+ },
293
+ ],
294
+ };
295
+ const SQS_ENTRIES = [SQS_LIST_QUEUES, SQS_GET_QUEUE_ATTRIBUTES];
296
+ /**
297
+ `athena start-query-execution`。
298
+
299
+ `database` / `catalog` / `output_location` は検証だけに使う。
300
+ awscli へは shorthand の `--query-execution-context` / `--result-configuration` として渡す。利用者に shorthand の
301
+ 文字列そのものを書かせると契約外のキー(`ExpectedBucketOwner` 等)を混ぜられるため、
302
+ 組み立てはここの宣言に閉じる。
303
+ */
304
+ export const ATHENA_START_QUERY_EXECUTION = {
305
+ toolName: 'aws_athena_start_query_execution',
306
+ service: 'athena',
307
+ subcommand: 'start-query-execution',
308
+ kind: 'execute',
309
+ jsonOutput: true,
310
+ pagination: 'none',
311
+ inputs: [
312
+ { name: 'query_string', kind: 'string', required: true, awsFlag: '--query-string' },
313
+ { name: 'work_group', kind: 'string', required: false, awsFlag: '--work-group' },
314
+ { name: 'database', kind: 'string', required: false },
315
+ { name: 'catalog', kind: 'string', required: false },
316
+ { name: 'output_location', kind: 'string', required: false, pattern: /^s3:\/\// },
317
+ {
318
+ name: 'query_execution_context',
319
+ kind: 'shorthand',
320
+ required: false,
321
+ awsFlag: '--query-execution-context',
322
+ parts: [{ key: 'Database', from: 'database' }, { key: 'Catalog', from: 'catalog' }],
323
+ },
324
+ {
325
+ name: 'result_configuration',
326
+ kind: 'shorthand',
327
+ required: false,
328
+ awsFlag: '--result-configuration',
329
+ parts: [{ key: 'OutputLocation', from: 'output_location' }],
330
+ },
331
+ ],
332
+ };
333
+ export const ATHENA_GET_QUERY_EXECUTION = {
334
+ toolName: 'aws_athena_get_query_execution',
335
+ service: 'athena',
336
+ subcommand: 'get-query-execution',
337
+ kind: 'read',
338
+ jsonOutput: true,
339
+ pagination: 'none',
340
+ inputs: [
341
+ { name: 'query_execution_id', kind: 'string', required: true, awsFlag: '--query-execution-id' },
342
+ ],
343
+ };
344
+ export const ATHENA_GET_QUERY_RESULTS = {
345
+ toolName: 'aws_athena_get_query_results',
346
+ service: 'athena',
347
+ subcommand: 'get-query-results',
348
+ kind: 'read',
349
+ jsonOutput: true,
350
+ pagination: 'max-items',
351
+ inputs: [
352
+ { name: 'query_execution_id', kind: 'string', required: true, awsFlag: '--query-execution-id' },
353
+ ...MAX_ITEMS_INPUTS,
354
+ ],
355
+ };
356
+ const ATHENA_ENTRIES = [
357
+ ATHENA_START_QUERY_EXECUTION,
358
+ ATHENA_GET_QUERY_EXECUTION,
359
+ ATHENA_GET_QUERY_RESULTS,
360
+ ];
361
+ /**
362
+ `s3 ls`。高レベルコマンドで JSON 出力を持たないため jsonOutput は false。
363
+ */
364
+ export const S3_LS = {
365
+ toolName: 'aws_s3_ls',
366
+ service: 's3',
367
+ subcommand: 'ls',
368
+ kind: 'read',
369
+ jsonOutput: false,
370
+ pagination: 'none',
371
+ inputs: [
372
+ { name: 's3_uri', kind: 's3-list-uri', required: false, positional: 0 },
373
+ ],
374
+ };
375
+ /**
376
+ `s3 cp <s3_uri> <local_path>`。
377
+
378
+ 入力は「取得元は S3、書き出し先はローカル」の 2 項目に固定されている。
379
+ そのため、アップロード方向は検証で弾くまでもなく表現できない(research R7)。
380
+ */
381
+ export const S3_CP = {
382
+ toolName: 'aws_s3_cp',
383
+ service: 's3',
384
+ subcommand: 'cp',
385
+ kind: 'fetch',
386
+ jsonOutput: false,
387
+ pagination: 'none',
388
+ inputs: [
389
+ { name: 's3_uri', kind: 's3-uri', required: true, positional: 0 },
390
+ { name: 'local_path', kind: 'abs-path', required: true, positional: 1 },
391
+ { name: 'overwrite', kind: 'boolean', required: false, default: false },
392
+ ],
393
+ };
394
+ export const S3API_GET_OBJECT = {
395
+ toolName: 'aws_s3api_get_object',
396
+ service: 's3api',
397
+ subcommand: 'get-object',
398
+ kind: 'fetch',
399
+ jsonOutput: true,
400
+ pagination: 'none',
401
+ inputs: [
402
+ { name: 'bucket', kind: 'string', required: true, awsFlag: '--bucket' },
403
+ { name: 'key', kind: 'string', required: true, awsFlag: '--key' },
404
+ { name: 'outfile', kind: 'abs-path', required: true, positional: 0 },
405
+ { name: 'version_id', kind: 'string', required: false, awsFlag: '--version-id' },
406
+ { name: 'range', kind: 'string', required: false, awsFlag: '--range', pattern: /^bytes=/ },
407
+ { name: 'overwrite', kind: 'boolean', required: false, default: false },
408
+ ],
409
+ };
410
+ const S3_ENTRIES = [S3_LS, S3_CP, S3API_GET_OBJECT];
411
+ /**
412
+ イベントを引ける発生元の種別(`--source-type` の候補。awscli 2.36.40)。
413
+
414
+ 許可リストの `values` と mcp 層の `z.enum`、契約テストが同じ配列を読む(`CLOUDWATCH_UNIT_VALUES`
415
+ と同型)。
416
+ */
417
+ export const RDS_SOURCE_TYPE_VALUES = [
418
+ 'db-instance', 'db-parameter-group', 'db-security-group', 'db-snapshot',
419
+ 'db-cluster', 'db-cluster-snapshot', 'custom-engine-version', 'db-proxy',
420
+ 'blue-green-deployment', 'db-shard-group', 'zero-etl',
421
+ ];
422
+ /**
423
+ `rds describe-events`。
424
+
425
+ DB の停止・フェイルオーバー等のイベント履歴を引く。`--filters` は公開しない
426
+ (API が受ける属性は版で動くので、契約に固定できる範囲へ絞る)。
427
+
428
+ `duration`(現在から遡る分数)は `start_time` / `end_time` と意味が重なるので排他にする。
429
+ */
430
+ export const RDS_DESCRIBE_EVENTS = {
431
+ toolName: 'aws_rds_describe_events',
432
+ service: 'rds',
433
+ subcommand: 'describe-events',
434
+ kind: 'read',
435
+ jsonOutput: true,
436
+ pagination: 'max-items',
437
+ inputs: [
438
+ { name: 'source_identifier', kind: 'string', required: false, awsFlag: '--source-identifier' },
439
+ {
440
+ name: 'source_type',
441
+ kind: 'enum',
442
+ required: false,
443
+ awsFlag: '--source-type',
444
+ values: RDS_SOURCE_TYPE_VALUES,
445
+ },
446
+ {
447
+ name: 'start_time',
448
+ kind: 'string',
449
+ required: false,
450
+ awsFlag: '--start-time',
451
+ pattern: TIMESTAMP_PATTERN,
452
+ },
453
+ {
454
+ name: 'end_time',
455
+ kind: 'string',
456
+ required: false,
457
+ awsFlag: '--end-time',
458
+ pattern: TIMESTAMP_PATTERN,
459
+ },
460
+ { name: 'duration', kind: 'integer', required: false, awsFlag: '--duration', min: 1 },
461
+ {
462
+ name: 'event_categories',
463
+ kind: 'string-list',
464
+ required: false,
465
+ awsFlag: '--event-categories',
466
+ },
467
+ ...MAX_ITEMS_INPUTS,
468
+ ],
469
+ exclusive: [['start_time', 'duration'], ['end_time', 'duration']],
470
+ };
471
+ export const RDS_DESCRIBE_DB_CLUSTERS = {
472
+ toolName: 'aws_rds_describe_db_clusters',
473
+ service: 'rds',
474
+ subcommand: 'describe-db-clusters',
475
+ kind: 'read',
476
+ jsonOutput: true,
477
+ pagination: 'max-items',
478
+ inputs: [
479
+ {
480
+ name: 'db_cluster_identifier',
481
+ kind: 'string',
482
+ required: false,
483
+ awsFlag: '--db-cluster-identifier',
484
+ },
485
+ ...MAX_ITEMS_INPUTS,
486
+ ],
487
+ };
488
+ export const RDS_DESCRIBE_DB_INSTANCES = {
489
+ toolName: 'aws_rds_describe_db_instances',
490
+ service: 'rds',
491
+ subcommand: 'describe-db-instances',
492
+ kind: 'read',
493
+ jsonOutput: true,
494
+ pagination: 'max-items',
495
+ inputs: [
496
+ {
497
+ name: 'db_instance_identifier',
498
+ kind: 'string',
499
+ required: false,
500
+ awsFlag: '--db-instance-identifier',
501
+ },
502
+ ...MAX_ITEMS_INPUTS,
503
+ ],
504
+ };
505
+ const RDS_ENTRIES = [
506
+ RDS_DESCRIBE_EVENTS,
507
+ RDS_DESCRIBE_DB_CLUSTERS,
508
+ RDS_DESCRIBE_DB_INSTANCES,
509
+ ];
510
+ export const SCHEDULER_LIST_SCHEDULES = {
511
+ toolName: 'aws_scheduler_list_schedules',
512
+ service: 'scheduler',
513
+ subcommand: 'list-schedules',
514
+ kind: 'read',
515
+ jsonOutput: true,
516
+ pagination: 'max-items',
517
+ inputs: [
518
+ { name: 'group_name', kind: 'string', required: false, awsFlag: '--group-name' },
519
+ { name: 'name_prefix', kind: 'string', required: false, awsFlag: '--name-prefix' },
520
+ {
521
+ name: 'state',
522
+ kind: 'enum',
523
+ required: false,
524
+ awsFlag: '--state',
525
+ values: ['ENABLED', 'DISABLED'],
526
+ },
527
+ ...MAX_ITEMS_INPUTS,
528
+ ],
529
+ };
530
+ export const SCHEDULER_GET_SCHEDULE = {
531
+ toolName: 'aws_scheduler_get_schedule',
532
+ service: 'scheduler',
533
+ subcommand: 'get-schedule',
534
+ kind: 'read',
535
+ jsonOutput: true,
536
+ pagination: 'none',
537
+ inputs: [
538
+ { name: 'name', kind: 'string', required: true, awsFlag: '--name' },
539
+ { name: 'group_name', kind: 'string', required: false, awsFlag: '--group-name' },
540
+ ],
541
+ };
542
+ const SCHEDULER_ENTRIES = [
543
+ SCHEDULER_LIST_SCHEDULES,
544
+ SCHEDULER_GET_SCHEDULE,
545
+ ];
546
+ /**
547
+ `ecr describe-images`。
548
+
549
+ `tag_status` は awsFlag を持たない。shorthand の `--filter tagStatus=<値>` へ合成する
550
+ (Athena の `query_execution_context` と同型)。`--filter` の `imageStatus` は公開しない
551
+ ため、未指定時は API 既定の ACTIVE のイメージだけが返る。
552
+
553
+ `image_ids` と `starting_token` は排他。ECR の API が `imageIds` 指定時に `nextToken` を
554
+ 受け付けない(botocore のサービスモデル)ため、構文としては通っても実行できない。
555
+ */
556
+ export const ECR_DESCRIBE_IMAGES = {
557
+ toolName: 'aws_ecr_describe_images',
558
+ service: 'ecr',
559
+ subcommand: 'describe-images',
560
+ kind: 'read',
561
+ jsonOutput: true,
562
+ pagination: 'max-items',
563
+ inputs: [
564
+ { name: 'repository_name', kind: 'string', required: true, awsFlag: '--repository-name' },
565
+ {
566
+ name: 'registry_id',
567
+ kind: 'string',
568
+ required: false,
569
+ awsFlag: '--registry-id',
570
+ pattern: /^\d{12}$/,
571
+ },
572
+ {
573
+ name: 'image_ids',
574
+ kind: 'shorthand-list',
575
+ required: false,
576
+ awsFlag: '--image-ids',
577
+ elements: [
578
+ { key: 'imageTag', field: 'image_tag' },
579
+ { key: 'imageDigest', field: 'image_digest' },
580
+ ],
581
+ },
582
+ {
583
+ name: 'tag_status',
584
+ kind: 'enum',
585
+ required: false,
586
+ values: ['TAGGED', 'UNTAGGED', 'ANY'],
587
+ },
588
+ {
589
+ name: 'filter',
590
+ kind: 'shorthand',
591
+ required: false,
592
+ awsFlag: '--filter',
593
+ parts: [{ key: 'tagStatus', from: 'tag_status' }],
594
+ },
595
+ ...MAX_ITEMS_INPUTS,
596
+ ],
597
+ exclusive: [['image_ids', 'starting_token']],
598
+ };
599
+ const ECR_ENTRIES = [ECR_DESCRIBE_IMAGES];
600
+ /**
601
+ `ec2 describe-instances`。
602
+
603
+ 応答が大きくなりやすいので、description で max_items か filters による絞り込みを促している。
604
+ `--dry-run` と `--include-managed-resources` は公開しない。
605
+ */
606
+ export const EC2_DESCRIBE_INSTANCES = {
607
+ toolName: 'aws_ec2_describe_instances',
608
+ service: 'ec2',
609
+ subcommand: 'describe-instances',
610
+ kind: 'read',
611
+ jsonOutput: true,
612
+ pagination: 'max-items',
613
+ inputs: [
614
+ {
615
+ name: 'instance_ids',
616
+ kind: 'string-list',
617
+ required: false,
618
+ awsFlag: '--instance-ids',
619
+ pattern: /^i-[0-9a-f]+$/,
620
+ },
621
+ {
622
+ name: 'filters',
623
+ kind: 'shorthand-list',
624
+ required: false,
625
+ awsFlag: '--filters',
626
+ elements: [
627
+ { key: 'Name', field: 'name' },
628
+ { key: 'Values', field: 'values', list: true },
629
+ ],
630
+ },
631
+ ...MAX_ITEMS_INPUTS,
632
+ ],
633
+ };
634
+ const EC2_ENTRIES = [EC2_DESCRIBE_INSTANCES];
635
+ /**
636
+ 公開するエントリの一覧。並びは契約表の順で、tools/list の並びもこれに従う。
637
+ */
638
+ export const ALLOWLIST = [
639
+ ...STS_ENTRIES,
640
+ ...LAMBDA_ENTRIES,
641
+ ...LOGS_ENTRIES,
642
+ ...CLOUDWATCH_ENTRIES,
643
+ ...SQS_ENTRIES,
644
+ ...ATHENA_ENTRIES,
645
+ ...S3_ENTRIES,
646
+ ...RDS_ENTRIES,
647
+ ...SCHEDULER_ENTRIES,
648
+ ...ECR_ENTRIES,
649
+ ...EC2_ENTRIES,
650
+ ];
651
+ /**
652
+ ツール名からエントリを引く。見つからなければ undefined(呼び出し側が not-allowed にする)。
653
+ */
654
+ export function findAllowlistEntry(toolName, entries = ALLOWLIST) {
655
+ return entries.find(entry => entry.toolName === toolName);
656
+ }
657
+ //# sourceMappingURL=allowlist.js.map
@@ -0,0 +1,37 @@
1
+ import { type AllowlistEntry } from './allowlist.js';
2
+ /**
3
+ 検証で弾いたときの戻り値。awscli は起動しない。
4
+ */
5
+ export interface InvalidInput {
6
+ readonly category: 'invalid-input';
7
+ readonly message: string;
8
+ }
9
+ /**
10
+ 全エントリ共通の任意入力。指定時のみ awscli へ付与する。
11
+ */
12
+ export interface CommonOptions {
13
+ readonly profile?: string;
14
+ readonly region?: string;
15
+ }
16
+ /**
17
+ 入力を検証する。問題があれば invalid-input を、無ければ undefined を返す。
18
+
19
+ profile / region も同じ処理で検証する(別扱いにすると書式検証が抜ける)。
20
+ */
21
+ export declare function validateInput(entry: Readonly<AllowlistEntry>, input: Readonly<Record<string, unknown>>): InvalidInput | undefined;
22
+ /**
23
+ awscli へ渡す引数配列を組み立てる。
24
+
25
+ 並びは `<service> <subcommand> <位置引数…> <フラグ…> --output json --no-cli-pager
26
+ --profile <p> --region <r>`。位置引数を先・フラグを後に置くと、string-list(nargs が貪欲)と
27
+ 位置引数が同居しても awscli v2 の argparse が取り違えない(動作確認済み)。
28
+
29
+ `--no-cli-pager` は jsonOutput の有無に依らず常に付ける(非 tty では無害で、分岐を持たない方が単純)。
30
+
31
+ `--profile` / `--region` は末尾で 1 度だけ付ける。エントリ側が inputs に同名を宣言していても
32
+ フラグ列挙では飛ばす。
33
+
34
+ 値が '-' で始まる string は `--flag=value` の 1 トークンにする(flagTokens)。
35
+ */
36
+ export declare function buildArguments(entry: Readonly<AllowlistEntry>, input: Readonly<Record<string, unknown>>, common?: Readonly<CommonOptions>): string[];
37
+ //# sourceMappingURL=arguments.d.ts.map