@aws/nx-plugin 1.0.0-rc.18 → 1.0.0-rc.19
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/package.json +1 -1
- package/src/py/agent/__snapshots__/generator.spec.ts.snap +15 -6
- package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +201 -0
- package/src/py/agent/a2a-connection/files/agent-connection/app/{__targetAgentSnakeCase___client.py.template → __targetAgentSnakeCase___client_strands.py.template} +7 -5
- package/src/py/agent/a2a-connection/generator.js +6 -5
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/files/http/main.py.template +2 -2
- package/src/py/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +197 -0
- package/src/py/agent/gateway-connection/files/agent-connection/app/{__gatewaySnakeCase___client.py.template → __gatewaySnakeCase___client_strands.py.template} +6 -6
- package/src/py/agent/gateway-connection/generator.js +5 -5
- package/src/py/agent/gateway-connection/generator.js.map +1 -1
- package/src/py/agent/generator.js +3 -0
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +157 -79
- package/src/py/agent/mcp-connection/files/agent-connection/app/{__mcpServerSnakeCase___client.py.template → __mcpServerSnakeCase___client_strands.py.template} +7 -5
- package/src/py/agent/mcp-connection/generator.js +5 -5
- package/src/py/agent/mcp-connection/generator.js.map +1 -1
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +37 -3
- package/src/py/fast-api/files/app/__name__/main.py.template +4 -1
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +13 -4
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +1 -0
- package/src/smithy/project/files/src/operations/echo.smithy.template +1 -0
- package/src/terraform/project/files/application/src/main.tf.template +6 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +35 -4
- package/src/trpc/backend/files/src/procedures/echo.ts.template +1 -1
- package/src/trpc/backend/files/src/schema/echo.ts.template +2 -2
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +14 -5
- package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +256 -0
- package/src/ts/agent/a2a-connection/files/agent-connection/app/{__targetAgentKebabCase__-client.ts.template → __targetAgentKebabCase__-client-strands.ts.template} +5 -5
- package/src/ts/agent/a2a-connection/generator.js +3 -3
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/files/http/router.ts.template +1 -1
- package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +220 -0
- package/src/ts/agent/gateway-connection/files/agent-connection/app/{__gatewayKebabCase__-client.ts.template → __gatewayKebabCase__-client-strands.ts.template} +5 -5
- package/src/ts/agent/gateway-connection/generator.js +3 -3
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/generator.js +3 -0
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +183 -110
- package/src/ts/agent/mcp-connection/files/agent-connection/app/{__mcpServerKebabCase__-client.ts.template → __mcpServerKebabCase__-client-strands.ts.template} +5 -5
- package/src/ts/agent/mcp-connection/generator.js +3 -3
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +13 -4
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +64 -24
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -4
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +9 -3
- package/src/utils/agent-connection/agent-connection.d.ts +50 -24
- package/src/utils/agent-connection/agent-connection.js +137 -45
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +93 -0
- package/src/utils/agent-connection/files/core-auth/agentcore-endpoints.ts.template +37 -0
- package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +54 -0
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +41 -0
- package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +70 -0
- package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +39 -0
- package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +61 -0
- package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +26 -0
- package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +27 -0
- package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client_config.py.template +43 -0
- package/src/utils/agent-connection/files/py-core-auth/agentcore_endpoints.py.template +47 -0
- package/src/utils/agent-connection/files/py-core-auth/auth/session.py.template +51 -0
- package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_transport.py.template +28 -0
- package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_transport.py.template +34 -0
- package/src/utils/agent-connection/files/py-core-shared/agentcore_transport.py.template +40 -0
- package/src/utils/agent-connection/files/py-core-strands/a2a/agentcore_a2a_client_strands.py.template +66 -0
- package/src/utils/agent-connection/files/py-core-strands/gateway/agentcore_gateway_mcp_client_strands.py.template +22 -0
- package/src/utils/agent-connection/files/py-core-strands/mcp/agentcore_mcp_client_strands.py.template +30 -0
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +7 -2
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +13 -4
- package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +9 -0
- package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +23 -1
- package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +9 -3
- package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +7 -2
- package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +9 -3
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +22 -8
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +10 -4
- package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +13 -4
- package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client.ts.template +0 -123
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-client.ts.template +0 -78
- package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-client.ts.template +0 -128
- package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client.py.template +0 -120
- package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_client.py.template +0 -78
- package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_client.py.template +0 -89
- /package/src/utils/agent-connection/files/{core-runtime-config/model-errors.ts.template → core-strands/base/model-errors-strands.ts.template} +0 -0
- /package/src/utils/agent-connection/files/{core-runtime-config/with-session-id.ts.template → core-strands/base/with-session-id-strands.ts.template} +0 -0
- /package/src/utils/agent-connection/files/{py-core-runtime-config/model_errors.py.template → py-core-strands/base/model_errors_strands.py.template} +0 -0
- /package/src/utils/agent-connection/files/{py-core-runtime-config/with_session_id.py.template → py-core-strands/base/with_session_id_strands.py.template} +0 -0
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ClientFactory,
|
|
3
|
-
ClientFactoryOptions,
|
|
4
|
-
DefaultAgentCardResolver,
|
|
5
|
-
JsonRpcTransportFactory,
|
|
6
|
-
} from '@a2a-js/sdk/client';
|
|
7
|
-
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
8
|
-
import { A2AAgent } from '@strands-agents/sdk/a2a';
|
|
9
|
-
import { AwsClient } from 'aws4fetch';
|
|
10
|
-
import { getCurrentSessionId } from './session-context.js';
|
|
11
|
-
|
|
12
|
-
const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Common options for creating an AgentCore A2A client.
|
|
16
|
-
*/
|
|
17
|
-
export interface AgentCoreA2aClientOptions {
|
|
18
|
-
/** The ARN of the Bedrock AgentCore Runtime to connect to. */
|
|
19
|
-
agentRuntimeArn: string;
|
|
20
|
-
/** Optional description for the remote agent. */
|
|
21
|
-
description?: string;
|
|
22
|
-
/** Optional friendly name for the remote agent. */
|
|
23
|
-
name?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Options for an IAM-authenticated A2A client. */
|
|
27
|
-
export interface AgentCoreA2aClientIamOptions
|
|
28
|
-
extends AgentCoreA2aClientOptions {
|
|
29
|
-
credentialProvider?: ReturnType<typeof fromNodeProviderChain>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Options for a JWT-authenticated A2A client. */
|
|
33
|
-
export interface AgentCoreA2aClientJwtOptions
|
|
34
|
-
extends AgentCoreA2aClientOptions {
|
|
35
|
-
accessTokenProvider: () => Promise<string>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Options for a no-auth A2A client (local dev). */
|
|
39
|
-
export interface AgentCoreA2aClientNoAuthOptions {
|
|
40
|
-
/** Full URL of the local A2A endpoint. */
|
|
41
|
-
url: string;
|
|
42
|
-
name?: string;
|
|
43
|
-
description?: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface BuildOptions {
|
|
47
|
-
name?: string;
|
|
48
|
-
description?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Factory for A2A clients that forward the current async-context session. */
|
|
52
|
-
export class AgentCoreA2aClient {
|
|
53
|
-
/**
|
|
54
|
-
* Construct the A2A invocations URL for an AgentCore runtime ARN and
|
|
55
|
-
* extract the region. A2A on AgentCore is mounted at `/invocations/`
|
|
56
|
-
* (trailing slash matters).
|
|
57
|
-
*/
|
|
58
|
-
private static buildUrl(agentRuntimeArn: string): {
|
|
59
|
-
region: string;
|
|
60
|
-
url: string;
|
|
61
|
-
} {
|
|
62
|
-
const region = agentRuntimeArn.split(':')[3];
|
|
63
|
-
const url = `https://bedrock-agentcore.${region}.amazonaws.com/runtimes/${encodeURIComponent(agentRuntimeArn)}/invocations/`;
|
|
64
|
-
return { region, url };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private static build(
|
|
68
|
-
url: string,
|
|
69
|
-
authFetch: typeof fetch,
|
|
70
|
-
options: BuildOptions,
|
|
71
|
-
): A2AAgent {
|
|
72
|
-
const sessionFetch: typeof fetch = (input, init) => {
|
|
73
|
-
const headers = new Headers(init?.headers);
|
|
74
|
-
const sessionId = getCurrentSessionId();
|
|
75
|
-
if (sessionId) headers.set(SESSION_HEADER, sessionId);
|
|
76
|
-
return authFetch(input, { ...init, headers });
|
|
77
|
-
};
|
|
78
|
-
const clientFactory = new ClientFactory({
|
|
79
|
-
...ClientFactoryOptions.default,
|
|
80
|
-
transports: [new JsonRpcTransportFactory({ fetchImpl: sessionFetch })],
|
|
81
|
-
cardResolver: new DefaultAgentCardResolver({ fetchImpl: sessionFetch }),
|
|
82
|
-
});
|
|
83
|
-
return new A2AAgent({
|
|
84
|
-
url,
|
|
85
|
-
clientFactory,
|
|
86
|
-
...(options.name ? { name: options.name } : {}),
|
|
87
|
-
...(options.description ? { description: options.description } : {}),
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
static withIamAuth(options: AgentCoreA2aClientIamOptions): A2AAgent {
|
|
92
|
-
const { region, url } = AgentCoreA2aClient.buildUrl(options.agentRuntimeArn);
|
|
93
|
-
const credentialProvider =
|
|
94
|
-
options.credentialProvider ?? fromNodeProviderChain();
|
|
95
|
-
const sigv4Fetch: typeof fetch = async (...args) => {
|
|
96
|
-
const client = new AwsClient({
|
|
97
|
-
...(await credentialProvider()),
|
|
98
|
-
service: 'bedrock-agentcore',
|
|
99
|
-
region,
|
|
100
|
-
});
|
|
101
|
-
return client.fetch(...args);
|
|
102
|
-
};
|
|
103
|
-
return AgentCoreA2aClient.build(url, sigv4Fetch, options);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static withJwtAuth(options: AgentCoreA2aClientJwtOptions): A2AAgent {
|
|
107
|
-
const { url } = AgentCoreA2aClient.buildUrl(options.agentRuntimeArn);
|
|
108
|
-
const bearerFetch: typeof fetch = async (input, init) => {
|
|
109
|
-
const headers = new Headers(init?.headers);
|
|
110
|
-
headers.set(
|
|
111
|
-
'Authorization',
|
|
112
|
-
`Bearer ${await options.accessTokenProvider()}`,
|
|
113
|
-
);
|
|
114
|
-
return fetch(input, { ...init, headers });
|
|
115
|
-
};
|
|
116
|
-
return AgentCoreA2aClient.build(url, bearerFetch, options);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** For local dev — plain HTTP, no auth. */
|
|
120
|
-
static withoutAuth(options: AgentCoreA2aClientNoAuthOptions): A2AAgent {
|
|
121
|
-
return AgentCoreA2aClient.build(options.url, fetch, options);
|
|
122
|
-
}
|
|
123
|
-
}
|
package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-client.ts.template
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { McpClient } from '@strands-agents/sdk';
|
|
2
|
-
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
-
import { AwsClient } from 'aws4fetch';
|
|
4
|
-
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
5
|
-
import { getCurrentSessionId } from './session-context.js';
|
|
6
|
-
|
|
7
|
-
const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
|
|
8
|
-
|
|
9
|
-
export interface AgentCoreGatewayMcpClientIamOptions {
|
|
10
|
-
/**
|
|
11
|
-
* The MCP URL of the AgentCore Gateway, of the form
|
|
12
|
-
* https://<gatewayId>.gateway.bedrock-agentcore.<region>.amazonaws.com/mcp
|
|
13
|
-
*/
|
|
14
|
-
gatewayUrl: string;
|
|
15
|
-
/** AWS region override; by default parsed from `gatewayUrl`. */
|
|
16
|
-
region?: string;
|
|
17
|
-
/** AWS credential provider; defaults to the standard provider chain. */
|
|
18
|
-
credentialProvider?: ReturnType<typeof fromNodeProviderChain>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Factory for MCP clients that connect to an AgentCore Gateway. Forwards the
|
|
23
|
-
* current async-context session via the AgentCore session header, which the
|
|
24
|
-
* gateway propagates to downstream MCP server targets.
|
|
25
|
-
*/
|
|
26
|
-
export class AgentCoreGatewayMcpClient {
|
|
27
|
-
/** Create a gateway MCP client authenticated with IAM SigV4. */
|
|
28
|
-
static withIamAuth(options: AgentCoreGatewayMcpClientIamOptions): McpClient {
|
|
29
|
-
const credentialProvider =
|
|
30
|
-
options.credentialProvider ?? fromNodeProviderChain();
|
|
31
|
-
const region =
|
|
32
|
-
options.region ?? parseRegionFromGatewayUrl(options.gatewayUrl);
|
|
33
|
-
|
|
34
|
-
const sigv4Fetch: typeof fetch = async (input, init) => {
|
|
35
|
-
const client = new AwsClient({
|
|
36
|
-
...(await credentialProvider()),
|
|
37
|
-
service: 'bedrock-agentcore',
|
|
38
|
-
region,
|
|
39
|
-
});
|
|
40
|
-
return client.fetch(input, {
|
|
41
|
-
...init,
|
|
42
|
-
headers: withSessionHeader(init?.headers),
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
return AgentCoreGatewayMcpClient.create(options.gatewayUrl, sigv4Fetch);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Plain-HTTP gateway client, for the local gateway started by serve-local. */
|
|
49
|
-
static withoutAuth(options: { gatewayUrl: string }): McpClient {
|
|
50
|
-
const plainFetch: typeof fetch = async (input, init) =>
|
|
51
|
-
fetch(input, { ...init, headers: withSessionHeader(init?.headers) });
|
|
52
|
-
return AgentCoreGatewayMcpClient.create(options.gatewayUrl, plainFetch);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private static create(gatewayUrl: string, fetchFn: typeof fetch): McpClient {
|
|
56
|
-
const transport = new StreamableHTTPClientTransport(new URL(gatewayUrl), {
|
|
57
|
-
fetch: fetchFn,
|
|
58
|
-
});
|
|
59
|
-
return new McpClient({ transport });
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const withSessionHeader = (init?: RequestInit['headers']): Headers => {
|
|
64
|
-
const headers = new Headers(init);
|
|
65
|
-
const sessionId = getCurrentSessionId();
|
|
66
|
-
if (sessionId) headers.set(SESSION_HEADER, sessionId);
|
|
67
|
-
return headers;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const parseRegionFromGatewayUrl = (gatewayUrl: string): string => {
|
|
71
|
-
const match = /\.bedrock-agentcore\.([^.]+)\.amazonaws\.com/.exec(gatewayUrl);
|
|
72
|
-
if (!match) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
`Cannot determine region from gateway URL '${gatewayUrl}'. Pass region explicitly.`,
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
return match[1];
|
|
78
|
-
};
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { McpClient } from '@strands-agents/sdk';
|
|
2
|
-
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
-
import { AwsClient } from 'aws4fetch';
|
|
4
|
-
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
5
|
-
import { getCurrentSessionId } from './session-context.js';
|
|
6
|
-
|
|
7
|
-
const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Common options for creating an AgentCore MCP client.
|
|
11
|
-
*/
|
|
12
|
-
export interface AgentCoreMcpClientOptions {
|
|
13
|
-
/**
|
|
14
|
-
* The ARN of the Bedrock AgentCore Runtime to connect to.
|
|
15
|
-
*/
|
|
16
|
-
agentRuntimeArn: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Options for creating an AgentCore MCP client with IAM authentication.
|
|
21
|
-
*/
|
|
22
|
-
export interface AgentCoreMcpClientIamOptions
|
|
23
|
-
extends AgentCoreMcpClientOptions {
|
|
24
|
-
/**
|
|
25
|
-
* Optional AWS credential provider. If not provided, uses the default
|
|
26
|
-
* credential provider chain from the AWS SDK.
|
|
27
|
-
*/
|
|
28
|
-
credentialProvider?: ReturnType<typeof fromNodeProviderChain>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Options for creating an AgentCore MCP client with JWT authentication.
|
|
33
|
-
*/
|
|
34
|
-
export interface AgentCoreMcpClientJwtOptions
|
|
35
|
-
extends AgentCoreMcpClientOptions {
|
|
36
|
-
/**
|
|
37
|
-
* A function which returns the JWT access token used to authenticate.
|
|
38
|
-
*/
|
|
39
|
-
accessTokenProvider: () => Promise<string>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Options for creating an MCP client with no auth (local dev).
|
|
44
|
-
*/
|
|
45
|
-
export interface AgentCoreMcpClientNoAuthOptions {
|
|
46
|
-
/** Full URL of the local MCP endpoint. */
|
|
47
|
-
url: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface CreateOptions {
|
|
51
|
-
url: string;
|
|
52
|
-
buildHeaders?: () => Promise<Record<string, string>>;
|
|
53
|
-
fetch?: typeof fetch;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Factory for MCP clients that forward the current async-context session. */
|
|
57
|
-
export class AgentCoreMcpClient {
|
|
58
|
-
/**
|
|
59
|
-
* Construct the invocation URL for an AgentCore runtime ARN and extract
|
|
60
|
-
* the region. ARN format: arn:partition:service:region:account-id:resource
|
|
61
|
-
*/
|
|
62
|
-
private static buildUrl(agentRuntimeArn: string): {
|
|
63
|
-
region: string;
|
|
64
|
-
url: string;
|
|
65
|
-
} {
|
|
66
|
-
const region = agentRuntimeArn.split(':')[3];
|
|
67
|
-
const url = `https://bedrock-agentcore.${region}.amazonaws.com/runtimes/${encodeURIComponent(agentRuntimeArn)}/invocations?qualifier=DEFAULT`;
|
|
68
|
-
return { region, url };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private static create(options: CreateOptions): McpClient {
|
|
72
|
-
const {
|
|
73
|
-
url,
|
|
74
|
-
buildHeaders = async (): Promise<Record<string, string>> => ({}),
|
|
75
|
-
fetch: customFetch,
|
|
76
|
-
} = options;
|
|
77
|
-
const fetchWithHeaders: typeof fetch = async (input, init) => {
|
|
78
|
-
const headers = new Headers(init?.headers);
|
|
79
|
-
const sessionId = getCurrentSessionId();
|
|
80
|
-
if (sessionId) headers.set(SESSION_HEADER, sessionId);
|
|
81
|
-
const extra = await buildHeaders();
|
|
82
|
-
for (const k of Object.keys(extra)) {
|
|
83
|
-
headers.set(k, extra[k]);
|
|
84
|
-
}
|
|
85
|
-
return (customFetch ?? fetch)(input, { ...init, headers });
|
|
86
|
-
};
|
|
87
|
-
const transport = new StreamableHTTPClientTransport(new URL(url), {
|
|
88
|
-
fetch: fetchWithHeaders,
|
|
89
|
-
});
|
|
90
|
-
return new McpClient({ transport });
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* SigV4-authenticated client for a Bedrock AgentCore runtime.
|
|
95
|
-
*/
|
|
96
|
-
static withIamAuth(options: AgentCoreMcpClientIamOptions): McpClient {
|
|
97
|
-
const { region, url } = AgentCoreMcpClient.buildUrl(options.agentRuntimeArn);
|
|
98
|
-
const credentialProvider =
|
|
99
|
-
options.credentialProvider ?? fromNodeProviderChain();
|
|
100
|
-
const sigv4Fetch: typeof fetch = async (...args) => {
|
|
101
|
-
const client = new AwsClient({
|
|
102
|
-
...(await credentialProvider()),
|
|
103
|
-
service: 'bedrock-agentcore',
|
|
104
|
-
region,
|
|
105
|
-
});
|
|
106
|
-
return client.fetch(...args);
|
|
107
|
-
};
|
|
108
|
-
return AgentCoreMcpClient.create({ url, fetch: sigv4Fetch });
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Bearer-authenticated client for a Bedrock AgentCore runtime.
|
|
113
|
-
*/
|
|
114
|
-
static withJwtAuth(options: AgentCoreMcpClientJwtOptions): McpClient {
|
|
115
|
-
const { url } = AgentCoreMcpClient.buildUrl(options.agentRuntimeArn);
|
|
116
|
-
return AgentCoreMcpClient.create({
|
|
117
|
-
url,
|
|
118
|
-
buildHeaders: async () => ({
|
|
119
|
-
Authorization: `Bearer ${await options.accessTokenProvider()}`,
|
|
120
|
-
}),
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** For local dev — plain HTTP, no auth. */
|
|
125
|
-
static withoutAuth(options: AgentCoreMcpClientNoAuthOptions): McpClient {
|
|
126
|
-
return AgentCoreMcpClient.create({ url: options.url });
|
|
127
|
-
}
|
|
128
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
from urllib.parse import quote
|
|
3
|
-
|
|
4
|
-
import boto3
|
|
5
|
-
import httpx
|
|
6
|
-
from a2a.client import ClientConfig
|
|
7
|
-
from strands.agent.a2a_agent import A2AAgent
|
|
8
|
-
|
|
9
|
-
from .auth import SigV4HTTPXAuth
|
|
10
|
-
from .session_context import get_current_session_id
|
|
11
|
-
|
|
12
|
-
SESSION_HEADER = "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class _SessionHeaderAuth(httpx.Auth):
|
|
16
|
-
"""Stamps the AgentCore session header from the current async context."""
|
|
17
|
-
|
|
18
|
-
requires_request_body = True
|
|
19
|
-
requires_response_body = True
|
|
20
|
-
|
|
21
|
-
def __init__(self, inner: httpx.Auth | None = None):
|
|
22
|
-
self._inner = inner
|
|
23
|
-
|
|
24
|
-
def auth_flow(self, request: httpx.Request): # type: ignore[override]
|
|
25
|
-
sid = get_current_session_id()
|
|
26
|
-
if sid:
|
|
27
|
-
request.headers[SESSION_HEADER] = sid
|
|
28
|
-
if self._inner is None:
|
|
29
|
-
yield request
|
|
30
|
-
return
|
|
31
|
-
yield from self._inner.auth_flow(request)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class AgentCoreA2aClient:
|
|
35
|
-
"""Factory for A2A clients that forward the current async-context session."""
|
|
36
|
-
|
|
37
|
-
@staticmethod
|
|
38
|
-
def _build_url(agent_runtime_arn: str) -> tuple[str, str]:
|
|
39
|
-
"""Extract region from ARN and construct the A2A invocations URL.
|
|
40
|
-
|
|
41
|
-
ARN format: arn:partition:service:region:account-id:resource
|
|
42
|
-
A2A on AgentCore is mounted at `/invocations/` (trailing slash matters).
|
|
43
|
-
"""
|
|
44
|
-
region = agent_runtime_arn.split(":")[3]
|
|
45
|
-
encoded_arn = quote(agent_runtime_arn, safe="")
|
|
46
|
-
url = (
|
|
47
|
-
f"https://bedrock-agentcore.{region}.amazonaws.com/runtimes/"
|
|
48
|
-
f"{encoded_arn}/invocations/"
|
|
49
|
-
)
|
|
50
|
-
return region, url
|
|
51
|
-
|
|
52
|
-
@staticmethod
|
|
53
|
-
def _build(
|
|
54
|
-
url: str,
|
|
55
|
-
auth: httpx.Auth | None,
|
|
56
|
-
headers: dict | None,
|
|
57
|
-
*,
|
|
58
|
-
name: str | None,
|
|
59
|
-
description: str | None,
|
|
60
|
-
) -> A2AAgent:
|
|
61
|
-
httpx_client = httpx.AsyncClient(
|
|
62
|
-
auth=_SessionHeaderAuth(auth),
|
|
63
|
-
headers=headers or {},
|
|
64
|
-
timeout=120,
|
|
65
|
-
)
|
|
66
|
-
client_config = ClientConfig(httpx_client=httpx_client, streaming=False)
|
|
67
|
-
kwargs: dict = {"endpoint": url, "client_config": client_config}
|
|
68
|
-
if name:
|
|
69
|
-
kwargs["name"] = name
|
|
70
|
-
if description:
|
|
71
|
-
kwargs["description"] = description
|
|
72
|
-
return A2AAgent(**kwargs)
|
|
73
|
-
|
|
74
|
-
@staticmethod
|
|
75
|
-
def with_iam_auth(
|
|
76
|
-
agent_runtime_arn: str,
|
|
77
|
-
*,
|
|
78
|
-
name: str | None = None,
|
|
79
|
-
description: str | None = None,
|
|
80
|
-
) -> A2AAgent:
|
|
81
|
-
"""SigV4-authenticated client for a Bedrock AgentCore runtime."""
|
|
82
|
-
region, url = AgentCoreA2aClient._build_url(agent_runtime_arn)
|
|
83
|
-
credentials = boto3.Session(region_name=region).get_credentials()
|
|
84
|
-
return AgentCoreA2aClient._build(
|
|
85
|
-
url,
|
|
86
|
-
SigV4HTTPXAuth(credentials, "bedrock-agentcore", region),
|
|
87
|
-
None,
|
|
88
|
-
name=name,
|
|
89
|
-
description=description,
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
@staticmethod
|
|
93
|
-
def with_jwt_auth(
|
|
94
|
-
agent_runtime_arn: str,
|
|
95
|
-
access_token_provider: Callable[[], str],
|
|
96
|
-
*,
|
|
97
|
-
name: str | None = None,
|
|
98
|
-
description: str | None = None,
|
|
99
|
-
) -> A2AAgent:
|
|
100
|
-
"""Bearer-authenticated client for a Bedrock AgentCore runtime."""
|
|
101
|
-
_, url = AgentCoreA2aClient._build_url(agent_runtime_arn)
|
|
102
|
-
return AgentCoreA2aClient._build(
|
|
103
|
-
url,
|
|
104
|
-
None,
|
|
105
|
-
{"Authorization": f"Bearer {access_token_provider()}"},
|
|
106
|
-
name=name,
|
|
107
|
-
description=description,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
@staticmethod
|
|
111
|
-
def without_auth(
|
|
112
|
-
url: str,
|
|
113
|
-
*,
|
|
114
|
-
name: str | None = None,
|
|
115
|
-
description: str | None = None,
|
|
116
|
-
) -> A2AAgent:
|
|
117
|
-
"""Plain-HTTP client — for local dev."""
|
|
118
|
-
return AgentCoreA2aClient._build(
|
|
119
|
-
url, None, None, name=name, description=description
|
|
120
|
-
)
|
package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_client.py.template
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
|
|
3
|
-
import boto3
|
|
4
|
-
import httpx
|
|
5
|
-
from mcp.client.streamable_http import streamablehttp_client
|
|
6
|
-
from strands.tools.mcp.mcp_client import MCPClient
|
|
7
|
-
|
|
8
|
-
from .auth import SigV4HTTPXAuth
|
|
9
|
-
from .session_context import get_current_session_id
|
|
10
|
-
|
|
11
|
-
SESSION_HEADER = "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class _SessionHeaderAuth(httpx.Auth):
|
|
15
|
-
"""Stamps the AgentCore session header from the current async context."""
|
|
16
|
-
|
|
17
|
-
requires_request_body = True
|
|
18
|
-
requires_response_body = True
|
|
19
|
-
|
|
20
|
-
def __init__(self, inner: httpx.Auth | None = None):
|
|
21
|
-
self._inner = inner
|
|
22
|
-
|
|
23
|
-
def auth_flow(self, request: httpx.Request): # type: ignore[override]
|
|
24
|
-
sid = get_current_session_id()
|
|
25
|
-
if sid:
|
|
26
|
-
request.headers[SESSION_HEADER] = sid
|
|
27
|
-
if self._inner is None:
|
|
28
|
-
yield request
|
|
29
|
-
return
|
|
30
|
-
yield from self._inner.auth_flow(request)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _parse_region_from_gateway_url(gateway_url: str) -> str:
|
|
34
|
-
match = re.search(r"\.bedrock-agentcore\.([^.]+)\.amazonaws\.com", gateway_url)
|
|
35
|
-
if not match:
|
|
36
|
-
raise ValueError(
|
|
37
|
-
f"Cannot determine region from gateway URL '{gateway_url}'. "
|
|
38
|
-
"Pass region explicitly."
|
|
39
|
-
)
|
|
40
|
-
return match.group(1)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class AgentCoreGatewayMCPClient:
|
|
44
|
-
"""Factory for MCP clients that connect to an AgentCore Gateway. Forwards
|
|
45
|
-
the current async-context session via the AgentCore session header, which
|
|
46
|
-
the gateway propagates to downstream MCP server targets.
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
@staticmethod
|
|
50
|
-
def with_iam_auth(
|
|
51
|
-
gateway_url: str,
|
|
52
|
-
region: str | None = None,
|
|
53
|
-
) -> MCPClient:
|
|
54
|
-
"""Create a gateway MCP client authenticated with IAM SigV4."""
|
|
55
|
-
resolved_region = region or _parse_region_from_gateway_url(gateway_url)
|
|
56
|
-
credentials = boto3.Session(region_name=resolved_region).get_credentials()
|
|
57
|
-
return _create_client(
|
|
58
|
-
gateway_url,
|
|
59
|
-
_SessionHeaderAuth(
|
|
60
|
-
SigV4HTTPXAuth(credentials, "bedrock-agentcore", resolved_region),
|
|
61
|
-
),
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
@staticmethod
|
|
65
|
-
def without_auth(gateway_url: str) -> MCPClient:
|
|
66
|
-
"""Plain-HTTP gateway client, for the local gateway started by serve-local."""
|
|
67
|
-
return _create_client(gateway_url, _SessionHeaderAuth())
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _create_client(gateway_url: str, auth: httpx.Auth) -> MCPClient:
|
|
71
|
-
return MCPClient(
|
|
72
|
-
lambda: streamablehttp_client(
|
|
73
|
-
gateway_url,
|
|
74
|
-
auth=auth,
|
|
75
|
-
timeout=120,
|
|
76
|
-
terminate_on_close=False,
|
|
77
|
-
)
|
|
78
|
-
)
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
|
|
3
|
-
import boto3
|
|
4
|
-
import httpx
|
|
5
|
-
from mcp.client.streamable_http import streamablehttp_client
|
|
6
|
-
from strands.tools.mcp.mcp_client import MCPClient
|
|
7
|
-
|
|
8
|
-
from .auth import SigV4HTTPXAuth
|
|
9
|
-
from .session_context import get_current_session_id
|
|
10
|
-
|
|
11
|
-
SESSION_HEADER = "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class _SessionHeaderAuth(httpx.Auth):
|
|
15
|
-
"""Stamps the AgentCore session header from the current async context."""
|
|
16
|
-
|
|
17
|
-
requires_request_body = True
|
|
18
|
-
requires_response_body = True
|
|
19
|
-
|
|
20
|
-
def __init__(self, inner: httpx.Auth | None = None):
|
|
21
|
-
self._inner = inner
|
|
22
|
-
|
|
23
|
-
def auth_flow(self, request: httpx.Request): # type: ignore[override]
|
|
24
|
-
sid = get_current_session_id()
|
|
25
|
-
if sid:
|
|
26
|
-
request.headers[SESSION_HEADER] = sid
|
|
27
|
-
if self._inner is None:
|
|
28
|
-
yield request
|
|
29
|
-
return
|
|
30
|
-
yield from self._inner.auth_flow(request)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class AgentCoreMCPClient:
|
|
34
|
-
"""Factory for MCP clients that forward the current async-context session."""
|
|
35
|
-
|
|
36
|
-
@staticmethod
|
|
37
|
-
def _build_url(agent_runtime_arn: str) -> tuple[str, str]:
|
|
38
|
-
"""Extract region from ARN and construct the invocation URL.
|
|
39
|
-
|
|
40
|
-
ARN format: arn:partition:service:region:account-id:resource
|
|
41
|
-
"""
|
|
42
|
-
region = agent_runtime_arn.split(":")[3]
|
|
43
|
-
encoded_arn = agent_runtime_arn.replace(":", "%3A").replace("/", "%2F")
|
|
44
|
-
url = (
|
|
45
|
-
f"https://bedrock-agentcore.{region}.amazonaws.com/runtimes/"
|
|
46
|
-
f"{encoded_arn}/invocations?qualifier=DEFAULT"
|
|
47
|
-
)
|
|
48
|
-
return region, url
|
|
49
|
-
|
|
50
|
-
@staticmethod
|
|
51
|
-
def _create(url: str, auth: httpx.Auth | None = None) -> MCPClient:
|
|
52
|
-
return MCPClient(
|
|
53
|
-
lambda: streamablehttp_client(
|
|
54
|
-
url,
|
|
55
|
-
auth=_SessionHeaderAuth(auth),
|
|
56
|
-
timeout=120,
|
|
57
|
-
terminate_on_close=False,
|
|
58
|
-
)
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
@staticmethod
|
|
62
|
-
def with_iam_auth(agent_runtime_arn: str) -> MCPClient:
|
|
63
|
-
"""SigV4-authenticated client for a Bedrock AgentCore runtime."""
|
|
64
|
-
region, url = AgentCoreMCPClient._build_url(agent_runtime_arn)
|
|
65
|
-
credentials = boto3.Session(region_name=region).get_credentials()
|
|
66
|
-
return AgentCoreMCPClient._create(
|
|
67
|
-
url, SigV4HTTPXAuth(credentials, "bedrock-agentcore", region)
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
@staticmethod
|
|
71
|
-
def with_jwt_auth(
|
|
72
|
-
agent_runtime_arn: str, access_token_provider: Callable[[], str]
|
|
73
|
-
) -> MCPClient:
|
|
74
|
-
"""Bearer-authenticated client for a Bedrock AgentCore runtime."""
|
|
75
|
-
_, url = AgentCoreMCPClient._build_url(agent_runtime_arn)
|
|
76
|
-
return MCPClient(
|
|
77
|
-
lambda: streamablehttp_client(
|
|
78
|
-
url,
|
|
79
|
-
auth=_SessionHeaderAuth(),
|
|
80
|
-
headers={"Authorization": f"Bearer {access_token_provider()}"},
|
|
81
|
-
timeout=120,
|
|
82
|
-
terminate_on_close=False,
|
|
83
|
-
)
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
@staticmethod
|
|
87
|
-
def without_auth(url: str) -> MCPClient:
|
|
88
|
-
"""Plain-HTTP client — for local dev."""
|
|
89
|
-
return AgentCoreMCPClient._create(url)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|