@apono-io/mcp-aws 0.1.1 → 0.2.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/dist/failures.d.ts +16 -0
- package/dist/failures.d.ts.map +1 -0
- package/dist/failures.js +40 -0
- package/dist/failures.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/run.d.ts +3 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +22 -4
- package/dist/run.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const FailureCategory: {
|
|
2
|
+
readonly MissingEnv: "missing_env";
|
|
3
|
+
readonly CredentialExpired: "credential_expired";
|
|
4
|
+
readonly CredentialInvalid: "credential_invalid";
|
|
5
|
+
readonly AssumeRoleDenied: "assume_role_denied";
|
|
6
|
+
readonly RuntimeMissing: "runtime_missing";
|
|
7
|
+
};
|
|
8
|
+
export type FailureCategory = (typeof FailureCategory)[keyof typeof FailureCategory];
|
|
9
|
+
export declare class StartupFailure extends Error {
|
|
10
|
+
readonly category: FailureCategory;
|
|
11
|
+
constructor(category: FailureCategory, message: string);
|
|
12
|
+
}
|
|
13
|
+
export declare function stsFailureCategory(error: unknown): FailureCategory | undefined;
|
|
14
|
+
export declare function spawnFailureCategory(error: NodeJS.ErrnoException): FailureCategory | undefined;
|
|
15
|
+
export declare function reportFailure(error: unknown): void;
|
|
16
|
+
//# sourceMappingURL=failures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures.d.ts","sourceRoot":"","sources":["../src/failures.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe;;;;;;CAMlB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAYrF,qBAAa,cAAe,SAAQ,KAAK;IAErC,QAAQ,CAAC,QAAQ,EAAE,eAAe;gBAAzB,QAAQ,EAAE,eAAe,EAClC,OAAO,EAAE,MAAM;CAKlB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAG9E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG,eAAe,GAAG,SAAS,CAE9F;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAKlD"}
|
package/dist/failures.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const FailureCategory = {
|
|
2
|
+
MissingEnv: 'missing_env',
|
|
3
|
+
CredentialExpired: 'credential_expired',
|
|
4
|
+
CredentialInvalid: 'credential_invalid',
|
|
5
|
+
AssumeRoleDenied: 'assume_role_denied',
|
|
6
|
+
RuntimeMissing: 'runtime_missing',
|
|
7
|
+
};
|
|
8
|
+
const MARKER_PREFIX = 'APONO_MCP_ERROR:';
|
|
9
|
+
const STS_ERROR_CATEGORIES = [
|
|
10
|
+
['ExpiredToken', FailureCategory.CredentialExpired],
|
|
11
|
+
['InvalidClientTokenId', FailureCategory.CredentialInvalid],
|
|
12
|
+
['UnrecognizedClient', FailureCategory.CredentialInvalid],
|
|
13
|
+
['SignatureDoesNotMatch', FailureCategory.CredentialInvalid],
|
|
14
|
+
['AccessDenied', FailureCategory.AssumeRoleDenied],
|
|
15
|
+
];
|
|
16
|
+
export class StartupFailure extends Error {
|
|
17
|
+
category;
|
|
18
|
+
constructor(category, message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.category = category;
|
|
21
|
+
this.name = 'StartupFailure';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function stsFailureCategory(error) {
|
|
25
|
+
const name = error instanceof Error ? error.name : '';
|
|
26
|
+
return STS_ERROR_CATEGORIES.find(([code]) => name.includes(code))?.[1];
|
|
27
|
+
}
|
|
28
|
+
export function spawnFailureCategory(error) {
|
|
29
|
+
return error.code === 'ENOENT' ? FailureCategory.RuntimeMissing : undefined;
|
|
30
|
+
}
|
|
31
|
+
export function reportFailure(error) {
|
|
32
|
+
process.stderr.write(`Error: ${message(error)}\n`);
|
|
33
|
+
if (error instanceof StartupFailure) {
|
|
34
|
+
process.stderr.write(`${MARKER_PREFIX} ${error.category}\n`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function message(error) {
|
|
38
|
+
return error instanceof StartupFailure ? error.message : String(error);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=failures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures.js","sourceRoot":"","sources":["../src/failures.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EAAE,aAAa;IACzB,iBAAiB,EAAE,oBAAoB;IACvC,iBAAiB,EAAE,oBAAoB;IACvC,gBAAgB,EAAE,oBAAoB;IACtC,cAAc,EAAE,iBAAiB;CACzB,CAAC;AAIX,MAAM,aAAa,GAAG,kBAAkB,CAAC;AAEzC,MAAM,oBAAoB,GAAsD;IAC9E,CAAC,cAAc,EAAE,eAAe,CAAC,iBAAiB,CAAC;IACnD,CAAC,sBAAsB,EAAE,eAAe,CAAC,iBAAiB,CAAC;IAC3D,CAAC,oBAAoB,EAAE,eAAe,CAAC,iBAAiB,CAAC;IACzD,CAAC,uBAAuB,EAAE,eAAe,CAAC,iBAAiB,CAAC;IAC5D,CAAC,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC;CACnD,CAAC;AAEF,MAAM,OAAO,cAAe,SAAQ,KAAK;IAE5B;IADX,YACW,QAAyB,EAClC,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,aAAQ,GAAR,QAAQ,CAAiB;QAIlC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAA4B;IAC/D,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,aAAa,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,KAAK,YAAY,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { run } from './run.js';
|
|
3
|
+
import { reportFailure } from './failures.js';
|
|
3
4
|
run(process.env).catch((err) => {
|
|
4
|
-
|
|
5
|
+
reportFailure(err);
|
|
5
6
|
process.exit(1);
|
|
6
7
|
});
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtC,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/run.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { STSClient } from '@aws-sdk/client-sts';
|
|
2
|
+
export declare const VENDOR_SERVER = "awslabs.aws-api-mcp-server";
|
|
3
|
+
export declare const VENDOR_SERVER_SPEC = "awslabs.aws-api-mcp-server==1.5.1";
|
|
2
4
|
export interface AwsCredentials {
|
|
3
5
|
accessKeyId: string;
|
|
4
6
|
secretAccessKey: string;
|
|
@@ -10,5 +12,6 @@ export declare function validateEnv(env: NodeJS.ProcessEnv): {
|
|
|
10
12
|
region: string;
|
|
11
13
|
};
|
|
12
14
|
export declare function assumeRole(sts: STSClient, roleArn: string): Promise<AwsCredentials>;
|
|
15
|
+
export declare function assumeRoleOrFail(sts: STSClient, roleArn: string): Promise<AwsCredentials>;
|
|
13
16
|
export declare function run(env: NodeJS.ProcessEnv): Promise<void>;
|
|
14
17
|
//# sourceMappingURL=run.d.ts.map
|
package/dist/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,MAAM,qBAAqB,CAAC;AAiBnE,eAAO,MAAM,aAAa,+BAA+B,CAAC;AAE1D,eAAO,MAAM,kBAAkB,sCAA+C,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IACnD,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAmBA;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC,CAUzB;AAED,wBAAsB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC/D"}
|
package/dist/run.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { STSClient, AssumeRoleCommand } from '@aws-sdk/client-sts';
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
|
+
import { FailureCategory, StartupFailure, reportFailure, spawnFailureCategory, stsFailureCategory, } from './failures.js';
|
|
3
4
|
const REQUIRED_ENV = [
|
|
4
5
|
'AWS_ACCESS_KEY_ID',
|
|
5
6
|
'AWS_SECRET_ACCESS_KEY',
|
|
6
7
|
'AWS_SESSION_TOKEN',
|
|
7
8
|
'AWS_ROLE_ARN',
|
|
8
9
|
];
|
|
10
|
+
export const VENDOR_SERVER = 'awslabs.aws-api-mcp-server';
|
|
11
|
+
const VENDOR_SERVER_VERSION = '1.5.1';
|
|
12
|
+
export const VENDOR_SERVER_SPEC = `${VENDOR_SERVER}==${VENDOR_SERVER_VERSION}`;
|
|
9
13
|
export function validateEnv(env) {
|
|
10
14
|
for (const key of REQUIRED_ENV) {
|
|
11
15
|
if (!env[key]) {
|
|
12
|
-
throw new
|
|
16
|
+
throw new StartupFailure(FailureCategory.MissingEnv, `Missing required environment variable: ${key}`);
|
|
13
17
|
}
|
|
14
18
|
}
|
|
15
19
|
return {
|
|
@@ -37,11 +41,23 @@ export async function assumeRole(sts, roleArn) {
|
|
|
37
41
|
sessionToken: c.SessionToken,
|
|
38
42
|
};
|
|
39
43
|
}
|
|
44
|
+
export async function assumeRoleOrFail(sts, roleArn) {
|
|
45
|
+
try {
|
|
46
|
+
return await assumeRole(sts, roleArn);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const category = stsFailureCategory(error);
|
|
50
|
+
if (!category) {
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
throw new StartupFailure(category, `AssumeRole failed: ${String(error)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
40
56
|
export async function run(env) {
|
|
41
57
|
const { credentials, roleArn, region } = validateEnv(env);
|
|
42
58
|
const sts = new STSClient({ credentials, region });
|
|
43
|
-
const assumed = await
|
|
44
|
-
const child = spawn('uvx', ['
|
|
59
|
+
const assumed = await assumeRoleOrFail(sts, roleArn);
|
|
60
|
+
const child = spawn('uvx', ['--from', VENDOR_SERVER_SPEC, VENDOR_SERVER], {
|
|
45
61
|
env: {
|
|
46
62
|
...env,
|
|
47
63
|
AWS_ACCESS_KEY_ID: assumed.accessKeyId,
|
|
@@ -57,7 +73,9 @@ export async function run(env) {
|
|
|
57
73
|
process.exit(code ?? 1);
|
|
58
74
|
});
|
|
59
75
|
child.on('error', (err) => {
|
|
60
|
-
|
|
76
|
+
const failed = `Failed to spawn ${VENDOR_SERVER}: ${err.message}`;
|
|
77
|
+
const category = spawnFailureCategory(err);
|
|
78
|
+
reportFailure(category ? new StartupFailure(category, failed) : new Error(failed));
|
|
61
79
|
process.exit(1);
|
|
62
80
|
});
|
|
63
81
|
}
|
package/dist/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|