@pecot/tools-mcp 1.0.1 → 1.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.
- package/.claude-plugin/plugin.json +1 -1
- package/cli/dist/cli.d.ts +1 -2
- package/cli/dist/cli.js +9 -13
- package/cli/dist/diagnostics.d.ts +38 -0
- package/cli/dist/diagnostics.js +46 -0
- package/cli/dist/domain/arguments.d.ts +2 -15
- package/cli/dist/domain/arguments.js +38 -99
- package/cli/dist/domain/athena-query.d.ts +2 -8
- package/cli/dist/domain/athena-query.js +10 -35
- package/cli/dist/domain/s3-input.d.ts +2 -9
- package/cli/dist/domain/s3-input.js +8 -21
- package/cli/dist/infra/awscli.d.ts +8 -36
- package/cli/dist/infra/awscli.js +15 -55
- package/cli/dist/infra/sso/login-registry.d.ts +4 -21
- package/cli/dist/infra/sso/login-registry.js +13 -56
- package/cli/dist/mcp/serve.d.ts +6 -28
- package/cli/dist/mcp/serve.js +20 -64
- package/cli/dist/mcp/server.d.ts +4 -20
- package/cli/dist/mcp/server.js +9 -35
- package/cli/dist/mcp/tools/_shared.d.ts +6 -27
- package/cli/dist/mcp/tools/_shared.js +36 -65
- package/cli/dist/mcp/tools/athena.js +17 -27
- package/cli/dist/mcp/tools/cloudwatch.js +13 -15
- package/cli/dist/mcp/tools/ec2.js +7 -10
- package/cli/dist/mcp/tools/ecr.js +10 -16
- package/cli/dist/mcp/tools/index.js +1 -5
- package/cli/dist/mcp/tools/lambda.js +10 -10
- package/cli/dist/mcp/tools/logs.js +22 -22
- package/cli/dist/mcp/tools/rds.js +15 -18
- package/cli/dist/mcp/tools/s3.js +19 -29
- package/cli/dist/mcp/tools/scheduler.js +10 -13
- package/cli/dist/mcp/tools/sqs.js +8 -8
- package/cli/dist/mcp/tools/sso.d.ts +1 -5
- package/cli/dist/mcp/tools/sso.js +33 -59
- package/cli/dist/mcp/tools/sts.js +2 -2
- package/cli/dist/node-runtime.d.ts +6 -1
- package/cli/dist/node-runtime.js +16 -8
- package/npm-shrinkwrap.json +3 -3
- package/package.json +2 -2
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
// Athena 系のツール定義。
|
|
2
|
-
//
|
|
3
|
-
// start-query-execution だけは許可リストの静的宣言でクエリ内容を縛れないため、
|
|
4
|
-
// 実行前拒否(reject)で参照専用クエリ以外を落とす。
|
|
1
|
+
// Athena 系のツール定義。start-query-execution は静的宣言でクエリを縛れないため、実行前拒否で参照専用以外を落とす。
|
|
5
2
|
import { z } from 'zod';
|
|
6
3
|
import { ATHENA_GET_QUERY_EXECUTION, ATHENA_GET_QUERY_RESULTS, ATHENA_START_QUERY_EXECUTION, } from '../../domain/allowlist.js';
|
|
7
4
|
import { classifyAthenaQuery } from '../../domain/athena-query.js';
|
|
8
5
|
import { allowlistedTool, COMMON_INPUT_SHAPE, MAX_ITEMS_PAGINATION_SHAPE, } from './_shared.js';
|
|
9
6
|
/**
|
|
10
|
-
参照専用でないクエリを not-allowed
|
|
11
|
-
|
|
12
|
-
query_string が文字列でない場合は undefined を返し、必須入力の検証(invalid-input)へ委ねる。
|
|
13
|
-
ここで別種別を返すと「必須入力の欠落」が「許可されていない操作」に化ける。
|
|
7
|
+
参照専用でないクエリを not-allowed で落とす。文字列でなければ undefined を返し、必須入力の検証へ委ねる。
|
|
14
8
|
*/
|
|
15
9
|
function rejectNonReadOnlyQuery(arguments_) {
|
|
16
10
|
const query = arguments_['query_string'];
|
|
@@ -22,18 +16,14 @@ function rejectNonReadOnlyQuery(arguments_) {
|
|
|
22
16
|
: { category: 'not-allowed', message: classified.message };
|
|
23
17
|
}
|
|
24
18
|
/**
|
|
25
|
-
catalog の単独指定を invalid-input
|
|
26
|
-
|
|
27
|
-
契約書は catalog を「database と併用」と定めている。
|
|
28
|
-
組み立て自体は `--query-execution-context Catalog=…` を作れてしまう。
|
|
29
|
-
ただし Database を欠いた QueryExecutionContext を実 Athena API が受けるかは未確認なので、契約の範囲へ寄せる。
|
|
19
|
+
catalog の単独指定を invalid-input で落とす。契約は「database と併用」で、Database 無しを Athena API が受けるかは未確認。
|
|
30
20
|
*/
|
|
31
21
|
function rejectCatalogWithoutDatabase(arguments_) {
|
|
32
22
|
if ((typeof arguments_['catalog'] !== 'string') || (typeof arguments_['database'] === 'string'))
|
|
33
23
|
return undefined;
|
|
34
24
|
return {
|
|
35
25
|
category: 'invalid-input',
|
|
36
|
-
message: 'catalog
|
|
26
|
+
message: 'Specify catalog together with database',
|
|
37
27
|
};
|
|
38
28
|
}
|
|
39
29
|
/**
|
|
@@ -46,33 +36,33 @@ export function athenaTools(options = {}) {
|
|
|
46
36
|
return [
|
|
47
37
|
allowlistedTool({
|
|
48
38
|
entry: ATHENA_START_QUERY_EXECUTION,
|
|
49
|
-
title: '
|
|
50
|
-
description: '
|
|
39
|
+
title: 'Start query execution',
|
|
40
|
+
description: 'Starts a read-only query (SELECT / WITH / SHOW / DESCRIBE / EXPLAIN) and returns query_execution_id. Mutating queries and multiple statements are rejected before running. Wait for completion with aws_athena_get_query_execution, then fetch results with aws_athena_get_query_results',
|
|
51
41
|
inputSchema: z.object({
|
|
52
|
-
query_string: z.string().describe('
|
|
53
|
-
work_group: z.string().optional().describe('
|
|
54
|
-
database: z.string().optional().describe('
|
|
55
|
-
catalog: z.string().optional().describe('
|
|
56
|
-
output_location: z.string().optional().describe('
|
|
42
|
+
query_string: z.string().describe('Read-only query to run. Give a single statement that starts with SELECT / WITH / SHOW / DESCRIBE / EXPLAIN (no enclosing parentheses)'),
|
|
43
|
+
work_group: z.string().optional().describe('Workgroup name'),
|
|
44
|
+
database: z.string().optional().describe('Default database name'),
|
|
45
|
+
catalog: z.string().optional().describe('Data catalog name. Specify together with database (not on its own)'),
|
|
46
|
+
output_location: z.string().optional().describe('Output location for results (starts with s3://)'),
|
|
57
47
|
...COMMON_INPUT_SHAPE,
|
|
58
48
|
}),
|
|
59
49
|
reject: rejectStartQueryExecution,
|
|
60
50
|
}, options),
|
|
61
51
|
allowlistedTool({
|
|
62
52
|
entry: ATHENA_GET_QUERY_EXECUTION,
|
|
63
|
-
title: '
|
|
64
|
-
description: '
|
|
53
|
+
title: 'Get query execution status',
|
|
54
|
+
description: 'Returns the query execution state (QUEUED / RUNNING / SUCCEEDED / FAILED / CANCELLED) and statistics',
|
|
65
55
|
inputSchema: z.object({
|
|
66
|
-
query_execution_id: z.string().describe('
|
|
56
|
+
query_execution_id: z.string().describe('ID returned by aws_athena_start_query_execution'),
|
|
67
57
|
...COMMON_INPUT_SHAPE,
|
|
68
58
|
}),
|
|
69
59
|
}, options),
|
|
70
60
|
allowlistedTool({
|
|
71
61
|
entry: ATHENA_GET_QUERY_RESULTS,
|
|
72
|
-
title: '
|
|
73
|
-
description: '
|
|
62
|
+
title: 'Get query results',
|
|
63
|
+
description: 'Returns the result rows of a completed query. For many rows, split with max_items and starting_token',
|
|
74
64
|
inputSchema: z.object({
|
|
75
|
-
query_execution_id: z.string().describe('
|
|
65
|
+
query_execution_id: z.string().describe('ID returned by aws_athena_start_query_execution'),
|
|
76
66
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
77
67
|
...COMMON_INPUT_SHAPE,
|
|
78
68
|
}),
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
// CloudWatch
|
|
2
|
-
//
|
|
3
|
-
// ログ系は logs.ts が持つ。こちらはメトリクスの統計取得だけを公開する。
|
|
1
|
+
// CloudWatch(メトリクス)系のツール定義。ログ系は logs.ts が持つ。
|
|
4
2
|
import { z } from 'zod';
|
|
5
3
|
import { CLOUDWATCH_GET_METRIC_STATISTICS, CLOUDWATCH_UNIT_VALUES } from '../../domain/allowlist.js';
|
|
6
4
|
import { allowlistedTool, COMMON_INPUT_SHAPE } from './_shared.js';
|
|
@@ -9,8 +7,8 @@ import { allowlistedTool, COMMON_INPUT_SHAPE } from './_shared.js';
|
|
|
9
7
|
JSON Schema では `items.additionalProperties: false` になり、SDK が入力検証エラーで拒否する。
|
|
10
8
|
*/
|
|
11
9
|
const DIMENSION_ELEMENT = z.strictObject({
|
|
12
|
-
name: z.string().describe('
|
|
13
|
-
value: z.string().describe('
|
|
10
|
+
name: z.string().describe('Dimension name (e.g. QueueName, FunctionName)'),
|
|
11
|
+
value: z.string().describe('Dimension value'),
|
|
14
12
|
});
|
|
15
13
|
/**
|
|
16
14
|
取得できる統計値。パーセンタイル(ExtendedStatistics)は公開しない。
|
|
@@ -24,20 +22,20 @@ export function cloudwatchTools(options = {}) {
|
|
|
24
22
|
return [
|
|
25
23
|
allowlistedTool({
|
|
26
24
|
entry: CLOUDWATCH_GET_METRIC_STATISTICS,
|
|
27
|
-
title: '
|
|
28
|
-
description: '
|
|
25
|
+
title: 'Get metric statistics',
|
|
26
|
+
description: 'Gets statistics of one metric over a time range. Specify all dimensions exactly as when the metric was published, or the result is empty',
|
|
29
27
|
inputSchema: z.object({
|
|
30
|
-
namespace: z.string().describe('
|
|
31
|
-
metric_name: z.string().describe('
|
|
28
|
+
namespace: z.string().describe('Metric namespace (e.g. AWS/SQS, AWS/Lambda)'),
|
|
29
|
+
metric_name: z.string().describe('Metric name (e.g. NumberOfMessagesSent)'),
|
|
32
30
|
dimensions: z.array(DIMENSION_ELEMENT).max(30).optional()
|
|
33
|
-
.describe('
|
|
34
|
-
start_time: z.string().describe('
|
|
35
|
-
end_time: z.string().describe('
|
|
36
|
-
period: z.number().int().min(1).describe('
|
|
31
|
+
.describe('Dimensions to filter by. Specify exactly the combination the metric has'),
|
|
32
|
+
start_time: z.string().describe('Start time. ISO 8601 with a required timezone (Z or +09:00 form), e.g. 2026-09-01T00:00:00Z / 2026-09-01T09:00:00+09:00'),
|
|
33
|
+
end_time: z.string().describe('End time. ISO 8601 with a required timezone (Z or +09:00 form), same format as start_time'),
|
|
34
|
+
period: z.number().int().min(1).describe('Aggregation period in seconds. Must be a multiple of 60'),
|
|
37
35
|
statistics: z.array(STATISTIC_ENUM).min(1).max(5)
|
|
38
|
-
.describe('
|
|
36
|
+
.describe('Statistics to get. Specify 1 to 5'),
|
|
39
37
|
unit: UNIT_ENUM.optional()
|
|
40
|
-
.describe('
|
|
38
|
+
.describe('Unit to filter by. The result is empty if it does not match the unit of the data'),
|
|
41
39
|
...COMMON_INPUT_SHAPE,
|
|
42
40
|
}),
|
|
43
41
|
}, options),
|
|
@@ -3,25 +3,22 @@ import { z } from 'zod';
|
|
|
3
3
|
import { EC2_DESCRIBE_INSTANCES } from '../../domain/allowlist.js';
|
|
4
4
|
import { allowlistedTool, COMMON_INPUT_SHAPE, MAX_ITEMS_PAGINATION_SHAPE, } from './_shared.js';
|
|
5
5
|
/**
|
|
6
|
-
絞り込み条件 1 件。`values` のいずれかに一致すれば対象になる。
|
|
7
|
-
|
|
8
|
-
`z.object` は宣言外のキーを通知せず削るため strictObject を使う。
|
|
9
|
-
JSON Schema では `items.additionalProperties: false` になり、SDK が入力検証エラーで拒否する。
|
|
6
|
+
絞り込み条件 1 件。`values` のいずれかに一致すれば対象になる。strictObject は宣言外のキーを SDK に拒否させるため。
|
|
10
7
|
*/
|
|
11
8
|
const FILTER_ELEMENT = z.strictObject({
|
|
12
|
-
name: z.string().describe('
|
|
13
|
-
values: z.array(z.string()).min(1).describe('
|
|
9
|
+
name: z.string().describe('Filter name (e.g. instance-state-name, tag:Name)'),
|
|
10
|
+
values: z.array(z.string()).min(1).describe('Values; an instance matches if any one matches'),
|
|
14
11
|
});
|
|
15
|
-
const INSTANCE_IDS_INPUT = z.array(z.string()).min(1).optional().describe('
|
|
12
|
+
const INSTANCE_IDS_INPUT = z.array(z.string()).min(1).optional().describe('Instance IDs to get (i-... form)');
|
|
16
13
|
export function ec2Tools(options = {}) {
|
|
17
14
|
return [
|
|
18
15
|
allowlistedTool({
|
|
19
16
|
entry: EC2_DESCRIBE_INSTANCES,
|
|
20
|
-
title: 'EC2
|
|
21
|
-
description: '
|
|
17
|
+
title: 'List EC2 instances',
|
|
18
|
+
description: 'Returns instance state, type, tags, and network configuration. Output is large, so narrow it with max_items or filters',
|
|
22
19
|
inputSchema: z.object({
|
|
23
20
|
instance_ids: INSTANCE_IDS_INPUT,
|
|
24
|
-
filters: z.array(FILTER_ELEMENT).optional().describe('
|
|
21
|
+
filters: z.array(FILTER_ELEMENT).optional().describe('Filter conditions. With several, only instances matching all are returned'),
|
|
25
22
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
26
23
|
...COMMON_INPUT_SHAPE,
|
|
27
24
|
}),
|
|
@@ -1,33 +1,27 @@
|
|
|
1
|
-
// ECR 系のツール定義。
|
|
2
|
-
//
|
|
3
|
-
// tag_status は awscli の `--filter tagStatus=<値>` へ合成する(許可リスト側の shorthand)。
|
|
4
|
-
// 利用者に shorthand の文字列そのものを書かせないのは Athena と同じ理由。
|
|
1
|
+
// ECR 系のツール定義。tag_status は awscli の `--filter tagStatus=<値>` へ合成する(Athena と同じく shorthand を書かせない)。
|
|
5
2
|
import { z } from 'zod';
|
|
6
3
|
import { ECR_DESCRIBE_IMAGES } from '../../domain/allowlist.js';
|
|
7
4
|
import { allowlistedTool, COMMON_INPUT_SHAPE, MAX_ITEMS_PAGINATION_SHAPE, } from './_shared.js';
|
|
8
5
|
/**
|
|
9
|
-
取得するイメージの指定 1
|
|
10
|
-
|
|
11
|
-
`z.object` は宣言外のキーを通知せず削るため strictObject を使う。
|
|
12
|
-
JSON Schema では `items.additionalProperties: false` になり、SDK が入力検証エラーで拒否する。
|
|
6
|
+
取得するイメージの指定 1 件。タグとダイジェストのどちらか一方でよい。strictObject は宣言外のキーを SDK に拒否させるため。
|
|
13
7
|
*/
|
|
14
8
|
const IMAGE_ID_ELEMENT = z.strictObject({
|
|
15
|
-
image_tag: z.string().optional().describe('
|
|
16
|
-
image_digest: z.string().optional().describe('
|
|
9
|
+
image_tag: z.string().optional().describe('Image tag'),
|
|
10
|
+
image_digest: z.string().optional().describe('Image digest (sha256:... form)'),
|
|
17
11
|
});
|
|
18
12
|
export function ecrTools(options = {}) {
|
|
19
13
|
return [
|
|
20
14
|
allowlistedTool({
|
|
21
15
|
entry: ECR_DESCRIBE_IMAGES,
|
|
22
|
-
title: '
|
|
23
|
-
description: '
|
|
16
|
+
title: 'List container images',
|
|
17
|
+
description: 'Returns tags, digests, and push times of images in a repository. Use it to check deploy times. Only ACTIVE images are returned unless specified otherwise',
|
|
24
18
|
inputSchema: z.object({
|
|
25
|
-
repository_name: z.string().describe('
|
|
26
|
-
registry_id: z.string().optional().describe('
|
|
19
|
+
repository_name: z.string().describe('Repository name'),
|
|
20
|
+
registry_id: z.string().optional().describe('AWS account ID of the registry (12 digits). If omitted, the default registry'),
|
|
27
21
|
image_ids: z.array(IMAGE_ID_ELEMENT).max(100).optional()
|
|
28
|
-
.describe('
|
|
22
|
+
.describe('Images to get. Each element needs at least one of image_tag and image_digest. Cannot be combined with starting_token'),
|
|
29
23
|
tag_status: z.enum(['TAGGED', 'UNTAGGED', 'ANY']).optional()
|
|
30
|
-
.describe('
|
|
24
|
+
.describe('Filter by whether the image is tagged. If omitted, no filtering'),
|
|
31
25
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
32
26
|
...COMMON_INPUT_SHAPE,
|
|
33
27
|
}),
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// 並びは contracts/mcp-tools.md の表の順で、そのまま tools/list の並びになる。SSO の 2 件は
|
|
4
|
-
// 契約書で許可リストの表より前に置かれているため先頭に来る(許可リストには入らない)。
|
|
5
|
-
// 系統別の関数へ分けているのは、1 系統を足すときに触るファイルを閉じるため。
|
|
1
|
+
// 公開するツールの集約。並びがそのまま tools/list の並びになる(SSO の 2 件が先頭)。
|
|
6
2
|
import { athenaTools } from './athena.js';
|
|
7
3
|
import { cloudwatchTools } from './cloudwatch.js';
|
|
8
4
|
import { ec2Tools } from './ec2.js';
|
|
@@ -6,27 +6,27 @@ export function lambdaTools(options = {}) {
|
|
|
6
6
|
return [
|
|
7
7
|
allowlistedTool({
|
|
8
8
|
entry: LAMBDA_LIST_FUNCTIONS,
|
|
9
|
-
title: 'Lambda
|
|
10
|
-
description: '
|
|
9
|
+
title: 'List Lambda functions',
|
|
10
|
+
description: 'Lists Lambda functions in the region. For many functions, split with max_items and starting_token',
|
|
11
11
|
inputSchema: z.object({ ...MAX_ITEMS_PAGINATION_SHAPE, ...COMMON_INPUT_SHAPE }),
|
|
12
12
|
}, options),
|
|
13
13
|
allowlistedTool({
|
|
14
14
|
entry: LAMBDA_GET_FUNCTION_CONFIGURATION,
|
|
15
|
-
title: 'Lambda
|
|
16
|
-
description: '
|
|
15
|
+
title: 'Get Lambda function configuration',
|
|
16
|
+
description: 'Returns the configuration of one function (runtime, handler, environment variables, timeout, etc.)',
|
|
17
17
|
inputSchema: z.object({
|
|
18
|
-
function_name: z.string().describe('
|
|
19
|
-
qualifier: z.string().optional().describe('
|
|
18
|
+
function_name: z.string().describe('Function name, partial ARN, or full ARN'),
|
|
19
|
+
qualifier: z.string().optional().describe('Version number or alias name. If omitted, $LATEST'),
|
|
20
20
|
...COMMON_INPUT_SHAPE,
|
|
21
21
|
}),
|
|
22
22
|
}, options),
|
|
23
23
|
allowlistedTool({
|
|
24
24
|
entry: LAMBDA_LIST_EVENT_SOURCE_MAPPINGS,
|
|
25
|
-
title: '
|
|
26
|
-
description: '
|
|
25
|
+
title: 'List event source mappings',
|
|
26
|
+
description: 'Lists the mappings between functions and event sources (SQS queues, DynamoDB streams, etc.). Filter by event_source_arn or function_name',
|
|
27
27
|
inputSchema: z.object({
|
|
28
|
-
event_source_arn: z.string().optional().describe('
|
|
29
|
-
function_name: z.string().optional().describe('
|
|
28
|
+
event_source_arn: z.string().optional().describe('ARN of the event source (starts with arn:)'),
|
|
29
|
+
function_name: z.string().optional().describe('Function name, partial ARN, or full ARN'),
|
|
30
30
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
31
31
|
...COMMON_INPUT_SHAPE,
|
|
32
32
|
}),
|
|
@@ -5,39 +5,39 @@ import { allowlistedTool, COMMON_INPUT_SHAPE, LIMIT_NEXT_TOKEN_PAGINATION_SHAPE,
|
|
|
5
5
|
/**
|
|
6
6
|
並び順の指定。既定は昇順(false)。
|
|
7
7
|
*/
|
|
8
|
-
const DESCENDING_INPUT = z.boolean().default(false).describe('true
|
|
8
|
+
const DESCENDING_INPUT = z.boolean().default(false).describe('If true, sorts in descending order');
|
|
9
9
|
/**
|
|
10
|
-
|
|
10
|
+
検索Target log stream nameの一覧。
|
|
11
11
|
*/
|
|
12
12
|
const LOG_STREAM_NAMES_INPUT = z.array(z.string()).optional()
|
|
13
|
-
.describe('
|
|
13
|
+
.describe('Log stream names to search. Cannot be combined with log_stream_name_prefix');
|
|
14
14
|
/**
|
|
15
15
|
期間の絞り込み。epoch ミリ秒で、両ツールとも同じ意味を持つ。
|
|
16
16
|
*/
|
|
17
17
|
const TIME_RANGE_SHAPE = {
|
|
18
|
-
start_time: z.number().int().optional().describe('
|
|
19
|
-
end_time: z.number().int().optional().describe('
|
|
18
|
+
start_time: z.number().int().optional().describe('Start time (UNIX epoch milliseconds)'),
|
|
19
|
+
end_time: z.number().int().optional().describe('End time (UNIX epoch milliseconds)'),
|
|
20
20
|
};
|
|
21
21
|
export function logsTools(options = {}) {
|
|
22
22
|
return [
|
|
23
23
|
allowlistedTool({
|
|
24
24
|
entry: LOGS_DESCRIBE_LOG_GROUPS,
|
|
25
|
-
title: '
|
|
26
|
-
description: 'CloudWatch Logs
|
|
25
|
+
title: 'List log groups',
|
|
26
|
+
description: 'Lists CloudWatch Logs log groups. Narrow by prefix with log_group_name_prefix',
|
|
27
27
|
inputSchema: z.object({
|
|
28
|
-
log_group_name_prefix: z.string().optional().describe('
|
|
28
|
+
log_group_name_prefix: z.string().optional().describe('Log group name prefix'),
|
|
29
29
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
30
30
|
...COMMON_INPUT_SHAPE,
|
|
31
31
|
}),
|
|
32
32
|
}, options),
|
|
33
33
|
allowlistedTool({
|
|
34
34
|
entry: LOGS_DESCRIBE_LOG_STREAMS,
|
|
35
|
-
title: '
|
|
36
|
-
description: '
|
|
35
|
+
title: 'List log streams',
|
|
36
|
+
description: 'Lists log streams in a log group. To find the latest stream, set order_by to LastEventTime and descending to true',
|
|
37
37
|
inputSchema: z.object({
|
|
38
|
-
log_group_name: z.string().describe('
|
|
39
|
-
log_stream_name_prefix: z.string().optional().describe('
|
|
40
|
-
order_by: z.enum(['LogStreamName', 'LastEventTime']).optional().describe('
|
|
38
|
+
log_group_name: z.string().describe('Target log group name'),
|
|
39
|
+
log_stream_name_prefix: z.string().optional().describe('Log stream name prefix'),
|
|
40
|
+
order_by: z.enum(['LogStreamName', 'LastEventTime']).optional().describe('Sort key'),
|
|
41
41
|
descending: DESCENDING_INPUT,
|
|
42
42
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
43
43
|
...COMMON_INPUT_SHAPE,
|
|
@@ -45,11 +45,11 @@ export function logsTools(options = {}) {
|
|
|
45
45
|
}, options),
|
|
46
46
|
allowlistedTool({
|
|
47
47
|
entry: LOGS_GET_LOG_EVENTS,
|
|
48
|
-
title: '
|
|
49
|
-
description: '
|
|
48
|
+
title: 'Get log events',
|
|
49
|
+
description: 'Gets events of one log stream. To continue, pass nextForwardToken from the response as next_token',
|
|
50
50
|
inputSchema: z.object({
|
|
51
|
-
log_group_name: z.string().describe('
|
|
52
|
-
log_stream_name: z.string().describe('
|
|
51
|
+
log_group_name: z.string().describe('Target log group name'),
|
|
52
|
+
log_stream_name: z.string().describe('Target log stream name'),
|
|
53
53
|
...TIME_RANGE_SHAPE,
|
|
54
54
|
...LIMIT_NEXT_TOKEN_PAGINATION_SHAPE,
|
|
55
55
|
...COMMON_INPUT_SHAPE,
|
|
@@ -57,13 +57,13 @@ export function logsTools(options = {}) {
|
|
|
57
57
|
}, options),
|
|
58
58
|
allowlistedTool({
|
|
59
59
|
entry: LOGS_FILTER_LOG_EVENTS,
|
|
60
|
-
title: '
|
|
61
|
-
description: '
|
|
60
|
+
title: 'Search log events',
|
|
61
|
+
description: 'Searches log events across a log group. log_stream_names and log_stream_name_prefix cannot be specified together',
|
|
62
62
|
inputSchema: z.object({
|
|
63
|
-
log_group_name: z.string().describe('
|
|
63
|
+
log_group_name: z.string().describe('Target log group name'),
|
|
64
64
|
log_stream_names: LOG_STREAM_NAMES_INPUT,
|
|
65
|
-
log_stream_name_prefix: z.string().optional().describe('
|
|
66
|
-
filter_pattern: z.string().optional().describe('CloudWatch Logs
|
|
65
|
+
log_stream_name_prefix: z.string().optional().describe('Prefix of log stream names to search. Cannot be combined with log_stream_names'),
|
|
66
|
+
filter_pattern: z.string().optional().describe('CloudWatch Logs filter pattern'),
|
|
67
67
|
...TIME_RANGE_SHAPE,
|
|
68
68
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
69
69
|
...COMMON_INPUT_SHAPE,
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
// RDS
|
|
2
|
-
//
|
|
3
|
-
// 3 件とも `--filters` は公開しない。API が受ける属性はバージョンで変わるため、契約に固定できる
|
|
4
|
-
// 引数だけに絞っている。
|
|
1
|
+
// RDS 系のツール定義。`--filters` は公開しない。API の受ける属性がバージョンで変わるため。
|
|
5
2
|
import { z } from 'zod';
|
|
6
3
|
import { RDS_DESCRIBE_DB_CLUSTERS, RDS_DESCRIBE_DB_INSTANCES, RDS_DESCRIBE_EVENTS, RDS_SOURCE_TYPE_VALUES, } from '../../domain/allowlist.js';
|
|
7
4
|
import { allowlistedTool, COMMON_INPUT_SHAPE, MAX_ITEMS_PAGINATION_SHAPE, } from './_shared.js';
|
|
@@ -13,23 +10,23 @@ const SOURCE_TYPE_ENUM = z.enum(RDS_SOURCE_TYPE_VALUES);
|
|
|
13
10
|
絞り込むイベントカテゴリ。
|
|
14
11
|
*/
|
|
15
12
|
const EVENT_CATEGORIES_INPUT = z.array(z.string()).min(1).optional()
|
|
16
|
-
.describe('
|
|
13
|
+
.describe('Event categories to filter by (e.g. availability, failover)');
|
|
17
14
|
export function rdsTools(options = {}) {
|
|
18
15
|
return [
|
|
19
16
|
allowlistedTool({
|
|
20
17
|
entry: RDS_DESCRIBE_EVENTS,
|
|
21
|
-
title: 'RDS
|
|
22
|
-
description: 'DB
|
|
18
|
+
title: 'Get RDS events',
|
|
19
|
+
description: 'Returns the event history of DB instances and clusters (stop, start, failover, etc.). Without a range, covers the last 1 hour; events are retained for 14 days',
|
|
23
20
|
inputSchema: z.object({
|
|
24
21
|
source_identifier: z.string().optional()
|
|
25
|
-
.describe('
|
|
26
|
-
source_type: SOURCE_TYPE_ENUM.optional().describe('
|
|
22
|
+
.describe('Identifier of the event source. When specified, also specify source_type'),
|
|
23
|
+
source_type: SOURCE_TYPE_ENUM.optional().describe('Type of the event source'),
|
|
27
24
|
start_time: z.string().optional()
|
|
28
|
-
.describe('
|
|
25
|
+
.describe('Start time. ISO 8601 with a required timezone (Z or +09:00 form), e.g. 2026-09-01T00:00:00Z / 2026-09-01T09:00:00+09:00'),
|
|
29
26
|
end_time: z.string().optional()
|
|
30
|
-
.describe('
|
|
27
|
+
.describe('End time. ISO 8601 with a required timezone (Z or +09:00 form), same format as start_time'),
|
|
31
28
|
duration: z.number().int().min(1).optional()
|
|
32
|
-
.describe('
|
|
29
|
+
.describe('Number of minutes back from now. Cannot be combined with start_time / end_time'),
|
|
33
30
|
event_categories: EVENT_CATEGORIES_INPUT,
|
|
34
31
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
35
32
|
...COMMON_INPUT_SHAPE,
|
|
@@ -37,20 +34,20 @@ export function rdsTools(options = {}) {
|
|
|
37
34
|
}, options),
|
|
38
35
|
allowlistedTool({
|
|
39
36
|
entry: RDS_DESCRIBE_DB_CLUSTERS,
|
|
40
|
-
title: 'DB
|
|
41
|
-
description: 'Aurora / Multi-AZ DB
|
|
37
|
+
title: 'List DB clusters',
|
|
38
|
+
description: 'Returns the configuration and state of Aurora / Multi-AZ DB clusters. Narrow to one with db_cluster_identifier',
|
|
42
39
|
inputSchema: z.object({
|
|
43
|
-
db_cluster_identifier: z.string().optional().describe('
|
|
40
|
+
db_cluster_identifier: z.string().optional().describe('Cluster identifier or ARN. If omitted, all clusters'),
|
|
44
41
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
45
42
|
...COMMON_INPUT_SHAPE,
|
|
46
43
|
}),
|
|
47
44
|
}, options),
|
|
48
45
|
allowlistedTool({
|
|
49
46
|
entry: RDS_DESCRIBE_DB_INSTANCES,
|
|
50
|
-
title: 'DB
|
|
51
|
-
description: 'DB
|
|
47
|
+
title: 'List DB instances',
|
|
48
|
+
description: 'Returns the configuration and state of DB instances (DBInstanceStatus, endpoint, etc.). Narrow to one with db_instance_identifier',
|
|
52
49
|
inputSchema: z.object({
|
|
53
|
-
db_instance_identifier: z.string().optional().describe('
|
|
50
|
+
db_instance_identifier: z.string().optional().describe('Instance identifier or ARN. If omitted, all instances'),
|
|
54
51
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
55
52
|
...COMMON_INPUT_SHAPE,
|
|
56
53
|
}),
|
package/cli/dist/mcp/tools/s3.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
// S3
|
|
2
|
-
//
|
|
3
|
-
// 取得方向(S3 → ローカル)は入力の型で固定されており、逆方向は表現できない(research R7)。
|
|
4
|
-
// 残る上書き規則だけを実行前拒否(reject)で見て、書き出し先を artifacts に載せる。
|
|
1
|
+
// S3 系のツール定義。取得方向は入力の型で固定され(research R7)、残る上書き規則だけを実行前拒否で見る。
|
|
5
2
|
import { z } from 'zod';
|
|
6
3
|
import { S3API_GET_OBJECT, S3_CP, S3_LS } from '../../domain/allowlist.js';
|
|
7
4
|
import { doesFileExist, isDirectory } from '../../infra/local-file.js';
|
|
@@ -12,14 +9,7 @@ function targetOf(arguments_, name) {
|
|
|
12
9
|
return typeof value === 'string' ? value : undefined;
|
|
13
10
|
}
|
|
14
11
|
/**
|
|
15
|
-
書き出し先を実行前に見る(research R7 の
|
|
16
|
-
|
|
17
|
-
ディレクトリは overwrite に依らず拒否する。
|
|
18
|
-
`aws s3 cp s3://b/k /dir` は `/dir/k` を書く。
|
|
19
|
-
「上書きするなら overwrite に true を」の案内どおりに再実行しても、artifacts に載る書き出し先(`/dir`)と実体がずれたまま成功してしまう。
|
|
20
|
-
|
|
21
|
-
既存ファイルは overwrite が無ければ拒否する。書き出し先が未指定・非文字列のときは undefined を
|
|
22
|
-
返し、必須入力の検証へ委ねる。
|
|
12
|
+
書き出し先を実行前に見る(research R7)。ディレクトリは overwrite に依らず拒否する。`/dir/k` に書かれ、artifacts の `/dir` とずれるため。
|
|
23
13
|
*/
|
|
24
14
|
function rejectExistingTarget(name) {
|
|
25
15
|
return (arguments_) => {
|
|
@@ -29,14 +19,14 @@ function rejectExistingTarget(name) {
|
|
|
29
19
|
if (isDirectory(target)) {
|
|
30
20
|
return {
|
|
31
21
|
category: 'invalid-input',
|
|
32
|
-
message: `${name}
|
|
22
|
+
message: `${name} must not be a directory. Specify the absolute path of the file to write: ${target}`,
|
|
33
23
|
};
|
|
34
24
|
}
|
|
35
25
|
if ((arguments_['overwrite'] === true) || !doesFileExist(target))
|
|
36
26
|
return;
|
|
37
27
|
return {
|
|
38
28
|
category: 'invalid-input',
|
|
39
|
-
message: `${name}
|
|
29
|
+
message: `${name} already exists. To overwrite, set overwrite to true: ${target}`,
|
|
40
30
|
};
|
|
41
31
|
};
|
|
42
32
|
}
|
|
@@ -50,25 +40,25 @@ function artifactsOfTarget(name) {
|
|
|
50
40
|
};
|
|
51
41
|
}
|
|
52
42
|
const OVERWRITE_INPUT = z.boolean().default(false)
|
|
53
|
-
.describe('true
|
|
43
|
+
.describe('If true, overwrites the destination even if it already exists');
|
|
54
44
|
export function s3Tools(options = {}) {
|
|
55
45
|
return [
|
|
56
46
|
allowlistedTool({
|
|
57
47
|
entry: S3_LS,
|
|
58
|
-
title: 'S3
|
|
59
|
-
description: '
|
|
48
|
+
title: 'List S3',
|
|
49
|
+
description: 'Lists the entries directly under a bucket or prefix. Omit s3_uri to list buckets. The command has no JSON output, so results are returned per line in data.lines',
|
|
60
50
|
inputSchema: z.object({
|
|
61
|
-
s3_uri: z.string().optional().describe('
|
|
51
|
+
s3_uri: z.string().optional().describe('Target to list (s3://bucket or s3://bucket/prefix/). If omitted, lists buckets'),
|
|
62
52
|
...COMMON_INPUT_SHAPE,
|
|
63
53
|
}),
|
|
64
54
|
}, options),
|
|
65
55
|
allowlistedTool({
|
|
66
56
|
entry: S3_CP,
|
|
67
|
-
title: 'S3
|
|
68
|
-
description: 'S3
|
|
57
|
+
title: 'Get S3 object',
|
|
58
|
+
description: 'Downloads one S3 object to a local absolute path. Uploads and recursive copy are not exposed',
|
|
69
59
|
inputSchema: z.object({
|
|
70
|
-
s3_uri: z.string().describe('
|
|
71
|
-
local_path: z.string().describe('
|
|
60
|
+
s3_uri: z.string().describe('Source (s3://bucket/key)'),
|
|
61
|
+
local_path: z.string().describe('Local absolute path to write to'),
|
|
72
62
|
overwrite: OVERWRITE_INPUT,
|
|
73
63
|
...COMMON_INPUT_SHAPE,
|
|
74
64
|
}),
|
|
@@ -77,14 +67,14 @@ export function s3Tools(options = {}) {
|
|
|
77
67
|
}, options),
|
|
78
68
|
allowlistedTool({
|
|
79
69
|
entry: S3API_GET_OBJECT,
|
|
80
|
-
title: 'S3
|
|
81
|
-
description: '
|
|
70
|
+
title: 'Get S3 object (with metadata)',
|
|
71
|
+
description: 'Gets an object by bucket and key and returns its metadata as JSON. Use version_id to pick a version and range for a partial download',
|
|
82
72
|
inputSchema: z.object({
|
|
83
|
-
bucket: z.string().describe('
|
|
84
|
-
key: z.string().describe('
|
|
85
|
-
outfile: z.string().describe('
|
|
86
|
-
version_id: z.string().optional().describe('
|
|
87
|
-
range: z.string().optional().describe('
|
|
73
|
+
bucket: z.string().describe('Bucket name'),
|
|
74
|
+
key: z.string().describe('Object key'),
|
|
75
|
+
outfile: z.string().describe('Local absolute path to write to'),
|
|
76
|
+
version_id: z.string().optional().describe('Version ID to get'),
|
|
77
|
+
range: z.string().optional().describe('Byte range to get (bytes=0-1023)'),
|
|
88
78
|
overwrite: OVERWRITE_INPUT,
|
|
89
79
|
...COMMON_INPUT_SHAPE,
|
|
90
80
|
}),
|
|
@@ -3,38 +3,35 @@ import { z } from 'zod';
|
|
|
3
3
|
import { SCHEDULER_GET_SCHEDULE, SCHEDULER_LIST_SCHEDULES } from '../../domain/allowlist.js';
|
|
4
4
|
import { allowlistedTool, COMMON_INPUT_SHAPE, MAX_ITEMS_PAGINATION_SHAPE, } from './_shared.js';
|
|
5
5
|
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`list-schedules` の `--group-name` は未指定なら全グループが対象で、`get-schedule` の
|
|
9
|
-
既定(default グループ)とは意味が違うので定数を分ける。
|
|
6
|
+
一覧の絞り込みに使うスケジュールグループ名。未指定なら全グループが対象で、get-schedule の default とは意味が違う。
|
|
10
7
|
*/
|
|
11
8
|
const LIST_GROUP_NAME_INPUT = z.string().optional()
|
|
12
|
-
.describe('
|
|
9
|
+
.describe('Schedule group name to filter by. If omitted, lists all groups');
|
|
13
10
|
/**
|
|
14
11
|
単体取得の対象になるスケジュールグループ名。
|
|
15
12
|
*/
|
|
16
13
|
const GET_GROUP_NAME_INPUT = z.string().optional()
|
|
17
|
-
.describe('
|
|
14
|
+
.describe('Schedule group name. If omitted, the default group is used');
|
|
18
15
|
export function schedulerTools(options = {}) {
|
|
19
16
|
return [
|
|
20
17
|
allowlistedTool({
|
|
21
18
|
entry: SCHEDULER_LIST_SCHEDULES,
|
|
22
|
-
title: '
|
|
23
|
-
description: 'EventBridge Scheduler
|
|
19
|
+
title: 'List schedules',
|
|
20
|
+
description: 'Lists EventBridge Scheduler schedules. Get details (expression, target) with aws_scheduler_get_schedule',
|
|
24
21
|
inputSchema: z.object({
|
|
25
22
|
group_name: LIST_GROUP_NAME_INPUT,
|
|
26
|
-
name_prefix: z.string().optional().describe('
|
|
27
|
-
state: z.enum(['ENABLED', 'DISABLED']).optional().describe('
|
|
23
|
+
name_prefix: z.string().optional().describe('Schedule name prefix'),
|
|
24
|
+
state: z.enum(['ENABLED', 'DISABLED']).optional().describe('State to filter by'),
|
|
28
25
|
...MAX_ITEMS_PAGINATION_SHAPE,
|
|
29
26
|
...COMMON_INPUT_SHAPE,
|
|
30
27
|
}),
|
|
31
28
|
}, options),
|
|
32
29
|
allowlistedTool({
|
|
33
30
|
entry: SCHEDULER_GET_SCHEDULE,
|
|
34
|
-
title: '
|
|
35
|
-
description: '
|
|
31
|
+
title: 'Get schedule details',
|
|
32
|
+
description: 'Returns the schedule expression (ScheduleExpression), timezone, target, and state of one schedule',
|
|
36
33
|
inputSchema: z.object({
|
|
37
|
-
name: z.string().describe('
|
|
34
|
+
name: z.string().describe('Schedule name'),
|
|
38
35
|
group_name: GET_GROUP_NAME_INPUT,
|
|
39
36
|
...COMMON_INPUT_SHAPE,
|
|
40
37
|
}),
|