@aws/agentcore 0.3.0-preview.2.1 → 0.3.0-preview.3.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.
Files changed (60) hide show
  1. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +415 -58
  2. package/dist/assets/cdk/README.md +19 -7
  3. package/dist/assets/cdk/bin/cdk.ts +37 -2
  4. package/dist/assets/cdk/lib/cdk-stack.ts +25 -2
  5. package/dist/assets/cdk/package.json +1 -1
  6. package/dist/assets/cdk/test/cdk.test.ts +18 -14
  7. package/dist/assets/cdk/tsconfig.json +4 -4
  8. package/dist/assets/container/python/Dockerfile +7 -1
  9. package/dist/assets/python/googleadk/base/main.py +10 -1
  10. package/dist/assets/python/googleadk/base/mcp_client/client.py +54 -3
  11. package/dist/assets/python/googleadk/base/pyproject.toml +2 -0
  12. package/dist/assets/python/langchain_langgraph/base/main.py +11 -1
  13. package/dist/assets/python/langchain_langgraph/base/mcp_client/client.py +52 -3
  14. package/dist/assets/python/langchain_langgraph/base/pyproject.toml +2 -1
  15. package/dist/assets/python/openaiagents/base/main.py +43 -3
  16. package/dist/assets/python/openaiagents/base/mcp_client/client.py +54 -3
  17. package/dist/assets/python/openaiagents/base/pyproject.toml +2 -0
  18. package/dist/assets/python/strands/base/README.md +1 -1
  19. package/dist/assets/python/strands/base/main.py +16 -3
  20. package/dist/assets/python/strands/base/mcp_client/client.py +56 -4
  21. package/dist/assets/python/strands/base/pyproject.toml +2 -0
  22. package/dist/cli/index.mjs +290 -286
  23. package/dist/lib/packaging/build-args.d.ts +6 -0
  24. package/dist/lib/packaging/build-args.d.ts.map +1 -0
  25. package/dist/lib/packaging/build-args.js +18 -0
  26. package/dist/lib/packaging/build-args.js.map +1 -0
  27. package/dist/lib/packaging/container.d.ts.map +1 -1
  28. package/dist/lib/packaging/container.js +2 -1
  29. package/dist/lib/packaging/container.js.map +1 -1
  30. package/dist/lib/schemas/io/cli-config.d.ts +10 -0
  31. package/dist/lib/schemas/io/cli-config.d.ts.map +1 -0
  32. package/dist/lib/schemas/io/cli-config.js +27 -0
  33. package/dist/lib/schemas/io/cli-config.js.map +1 -0
  34. package/dist/lib/schemas/io/index.d.ts +1 -0
  35. package/dist/lib/schemas/io/index.d.ts.map +1 -1
  36. package/dist/lib/schemas/io/index.js +3 -1
  37. package/dist/lib/schemas/io/index.js.map +1 -1
  38. package/dist/lib/utils/subprocess.d.ts.map +1 -1
  39. package/dist/lib/utils/subprocess.js +32 -10
  40. package/dist/lib/utils/subprocess.js.map +1 -1
  41. package/dist/schema/constants.d.ts.map +1 -1
  42. package/dist/schema/constants.js +0 -1
  43. package/dist/schema/constants.js.map +1 -1
  44. package/dist/schema/schemas/agentcore-project.d.ts +48 -5
  45. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -1
  46. package/dist/schema/schemas/agentcore-project.js +19 -4
  47. package/dist/schema/schemas/agentcore-project.js.map +1 -1
  48. package/dist/schema/schemas/aws-targets.js +1 -1
  49. package/dist/schema/schemas/aws-targets.js.map +1 -1
  50. package/dist/schema/schemas/deployed-state.d.ts +32 -0
  51. package/dist/schema/schemas/deployed-state.d.ts.map +1 -1
  52. package/dist/schema/schemas/deployed-state.js +11 -1
  53. package/dist/schema/schemas/deployed-state.js.map +1 -1
  54. package/dist/schema/schemas/mcp-defs.d.ts +1 -1
  55. package/dist/schema/schemas/mcp-defs.js +1 -1
  56. package/dist/schema/schemas/mcp.d.ts +146 -6
  57. package/dist/schema/schemas/mcp.d.ts.map +1 -1
  58. package/dist/schema/schemas/mcp.js +49 -4
  59. package/dist/schema/schemas/mcp.js.map +1 -1
  60. package/package.json +12 -6
@@ -1,14 +1,26 @@
1
- # Welcome to your CDK TypeScript project
1
+ # AgentCore CDK Project
2
2
 
3
- This is a blank project for CDK development with TypeScript.
3
+ This CDK project is managed by the AgentCore CLI. It deploys your agent infrastructure into AWS using the `@aws/agentcore-cdk` L3 constructs.
4
4
 
5
- The `cdk.json` file tells the CDK Toolkit how to execute your app.
5
+ ## Structure
6
+
7
+ - `bin/cdk.ts` — Entry point. Reads project configuration from `agentcore/` and creates a stack per deployment target.
8
+ - `lib/cdk-stack.ts` — Defines `AgentCoreStack`, which wraps the `AgentCoreApplication` L3 construct.
9
+ - `test/cdk.test.ts` — Unit tests for stack synthesis.
6
10
 
7
11
  ## Useful commands
8
12
 
9
- - `npm run build` compile typescript to js
10
- - `npm run watch` watch for changes and compile
11
- - `npm run test` perform the jest unit tests
13
+ - `npm run build` compile TypeScript to JavaScript
14
+ - `npm run test` run unit tests
15
+ - `npx cdk synth` emit the synthesized CloudFormation template
12
16
  - `npx cdk deploy` deploy this stack to your default AWS account/region
13
17
  - `npx cdk diff` compare deployed stack with current state
14
- - `npx cdk synth` emits the synthesized CloudFormation template
18
+
19
+ ## Usage
20
+
21
+ You typically don't need to interact with this directory directly. The AgentCore CLI handles synthesis and deployment:
22
+
23
+ ```bash
24
+ agentcore deploy # synthesizes and deploys via CDK
25
+ agentcore status # checks deployment status
26
+ ```
@@ -3,6 +3,7 @@ import { AgentCoreStack } from '../lib/cdk-stack';
3
3
  import { ConfigIO, type AwsDeploymentTarget } from '@aws/agentcore-cdk';
4
4
  import { App, type Environment } from 'aws-cdk-lib';
5
5
  import * as path from 'path';
6
+ import * as fs from 'fs';
6
7
 
7
8
  function toEnvironment(target: AwsDeploymentTarget): Environment {
8
9
  return {
@@ -11,8 +12,12 @@ function toEnvironment(target: AwsDeploymentTarget): Environment {
11
12
  };
12
13
  }
13
14
 
15
+ function sanitize(name: string): string {
16
+ return name.replace(/_/g, '-');
17
+ }
18
+
14
19
  function toStackName(projectName: string, targetName: string): string {
15
- return `AgentCore-${projectName}-${targetName}`;
20
+ return `AgentCore-${sanitize(projectName)}-${sanitize(targetName)}`;
16
21
  }
17
22
 
18
23
  async function main() {
@@ -23,6 +28,22 @@ async function main() {
23
28
  const spec = await configIO.readProjectSpec();
24
29
  const targets = await configIO.readAWSDeploymentTargets();
25
30
 
31
+ // Read MCP configuration if it exists
32
+ let mcpSpec;
33
+ try {
34
+ mcpSpec = await configIO.readMcpSpec();
35
+ } catch {
36
+ // MCP config is optional
37
+ }
38
+
39
+ // Read deployed state for credential ARNs (populated by pre-deploy identity setup)
40
+ let deployedState: Record<string, unknown> | undefined;
41
+ try {
42
+ deployedState = JSON.parse(fs.readFileSync(path.join(configRoot, '.cli', 'deployed-state.json'), 'utf8'));
43
+ } catch {
44
+ // Deployed state may not exist on first deploy
45
+ }
46
+
26
47
  if (targets.length === 0) {
27
48
  throw new Error('No deployment targets configured. Please define targets in agentcore/aws-targets.json');
28
49
  }
@@ -33,8 +54,19 @@ async function main() {
33
54
  const env = toEnvironment(target);
34
55
  const stackName = toStackName(spec.name, target.name);
35
56
 
57
+ // Extract credentials from deployed state for this target
58
+ const targetState = (deployedState as Record<string, unknown>)?.targets as
59
+ | Record<string, Record<string, unknown>>
60
+ | undefined;
61
+ const targetResources = targetState?.[target.name]?.resources as Record<string, unknown> | undefined;
62
+ const credentials = targetResources?.credentials as
63
+ | Record<string, { credentialProviderArn: string; clientSecretArn?: string }>
64
+ | undefined;
65
+
36
66
  new AgentCoreStack(app, stackName, {
37
67
  spec,
68
+ mcpSpec,
69
+ credentials,
38
70
  env,
39
71
  description: `AgentCore stack for ${spec.name} deployed to ${target.name} (${target.region})`,
40
72
  tags: {
@@ -47,4 +79,7 @@ async function main() {
47
79
  app.synth();
48
80
  }
49
81
 
50
- main();
82
+ main().catch((error: unknown) => {
83
+ console.error('AgentCore CDK synthesis failed:', error instanceof Error ? error.message : error);
84
+ process.exitCode = 1;
85
+ });
@@ -1,4 +1,9 @@
1
- import { AgentCoreApplication, type AgentCoreProjectSpec } from '@aws/agentcore-cdk';
1
+ import {
2
+ AgentCoreApplication,
3
+ AgentCoreMcp,
4
+ type AgentCoreProjectSpec,
5
+ type AgentCoreMcpSpec,
6
+ } from '@aws/agentcore-cdk';
2
7
  import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
3
8
  import { Construct } from 'constructs';
4
9
 
@@ -7,6 +12,14 @@ export interface AgentCoreStackProps extends StackProps {
7
12
  * The AgentCore project specification containing agents, memories, and credentials.
8
13
  */
9
14
  spec: AgentCoreProjectSpec;
15
+ /**
16
+ * The MCP specification containing gateways and servers.
17
+ */
18
+ mcpSpec?: AgentCoreMcpSpec;
19
+ /**
20
+ * Credential provider ARNs from deployed state, keyed by credential name.
21
+ */
22
+ credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
10
23
  }
11
24
 
12
25
  /**
@@ -22,13 +35,23 @@ export class AgentCoreStack extends Stack {
22
35
  constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
23
36
  super(scope, id, props);
24
37
 
25
- const { spec } = props;
38
+ const { spec, mcpSpec, credentials } = props;
26
39
 
27
40
  // Create AgentCoreApplication with all agents
28
41
  this.application = new AgentCoreApplication(this, 'Application', {
29
42
  spec,
30
43
  });
31
44
 
45
+ // Create AgentCoreMcp if there are gateways configured
46
+ if (mcpSpec?.agentCoreGateways && mcpSpec.agentCoreGateways.length > 0) {
47
+ new AgentCoreMcp(this, 'Mcp', {
48
+ projectName: spec.name,
49
+ mcpSpec,
50
+ agentCoreApplication: this.application,
51
+ credentials,
52
+ });
53
+ }
54
+
32
55
  // Stack-level output
33
56
  new CfnOutput(this, 'StackNameOutput', {
34
57
  description: 'Name of the CloudFormation Stack',
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@aws/agentcore-cdk": "^0.1.0-alpha.1",
27
- "aws-cdk-lib": "2.234.1",
27
+ "aws-cdk-lib": "2.239.0",
28
28
  "constructs": "^10.0.0"
29
29
  }
30
30
  }
@@ -1,16 +1,20 @@
1
- // import * as cdk from 'aws-cdk-lib/core';
2
- // import { Template } from 'aws-cdk-lib/assertions';
3
- // import * as Cdk from '../lib/cdk-stack';
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import { Template } from 'aws-cdk-lib/assertions';
3
+ import { AgentCoreStack } from '../lib/cdk-stack';
4
4
 
5
- // example test. To run these tests, uncomment this file along with the
6
- // example resource in lib/cdk-stack.ts
7
- test('SQS Queue Created', () => {
8
- // const app = new cdk.App();
9
- // // WHEN
10
- // const stack = new Cdk.CdkStack(app, 'MyTestStack');
11
- // // THEN
12
- // const template = Template.fromStack(stack);
13
- // template.hasResourceProperties('AWS::SQS::Queue', {
14
- // VisibilityTimeout: 300
15
- // });
5
+ test('AgentCoreStack synthesizes with empty spec', () => {
6
+ const app = new cdk.App();
7
+ const stack = new AgentCoreStack(app, 'TestStack', {
8
+ spec: {
9
+ name: 'testproject',
10
+ version: 1,
11
+ agents: [],
12
+ memories: [],
13
+ credentials: [],
14
+ },
15
+ });
16
+ const template = Template.fromStack(stack);
17
+ template.hasOutput('StackNameOutput', {
18
+ Description: 'Name of the CloudFormation Stack',
19
+ });
16
20
  });
@@ -10,14 +10,14 @@
10
10
  "strictNullChecks": true,
11
11
  "noImplicitThis": true,
12
12
  "alwaysStrict": true,
13
- "noUnusedLocals": false,
14
- "noUnusedParameters": false,
13
+ "noUnusedLocals": true,
14
+ "noUnusedParameters": true,
15
15
  "noImplicitReturns": true,
16
- "noFallthroughCasesInSwitch": false,
16
+ "noFallthroughCasesInSwitch": true,
17
17
  "inlineSourceMap": true,
18
18
  "inlineSources": true,
19
19
  "experimentalDecorators": true,
20
- "strictPropertyInitialization": false,
20
+ "strictPropertyInitialization": true,
21
21
  "skipLibCheck": true,
22
22
  "typeRoots": ["./node_modules/@types"],
23
23
  "rootDir": ".",
@@ -1,12 +1,18 @@
1
1
  FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
2
2
 
3
+ ARG UV_DEFAULT_INDEX
4
+ ARG UV_INDEX
5
+
3
6
  WORKDIR /app
4
7
 
5
8
  ENV UV_SYSTEM_PYTHON=1 \
6
9
  UV_COMPILE_BYTECODE=1 \
7
10
  UV_NO_PROGRESS=1 \
8
11
  PYTHONUNBUFFERED=1 \
9
- DOCKER_CONTAINER=1
12
+ DOCKER_CONTAINER=1 \
13
+ UV_DEFAULT_INDEX=${UV_DEFAULT_INDEX} \
14
+ UV_INDEX=${UV_INDEX} \
15
+ PATH="/app/.venv/bin:$PATH"
10
16
 
11
17
  RUN useradd -m -u 1000 bedrock_agentcore
12
18
 
@@ -5,7 +5,11 @@ from google.adk.sessions import InMemorySessionService
5
5
  from google.genai import types
6
6
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
7
7
  from model.load import load_model
8
+ {{#if hasGateway}}
9
+ from mcp_client.client import get_all_gateway_mcp_toolsets
10
+ {{else}}
8
11
  from mcp_client.client import get_streamable_http_mcp_client
12
+ {{/if}}
9
13
 
10
14
  app = BedrockAgentCoreApp()
11
15
  log = app.logger
@@ -23,7 +27,12 @@ def add_numbers(a: int, b: int) -> int:
23
27
 
24
28
 
25
29
  # Get MCP Toolset
26
- mcp_toolset = [get_streamable_http_mcp_client()]
30
+ {{#if hasGateway}}
31
+ mcp_toolset = get_all_gateway_mcp_toolsets()
32
+ {{else}}
33
+ mcp_client = get_streamable_http_mcp_client()
34
+ mcp_toolset = [mcp_client] if mcp_client else []
35
+ {{/if}}
27
36
 
28
37
  _credentials_loaded = False
29
38
 
@@ -1,15 +1,66 @@
1
+ import os
2
+ import logging
1
3
  from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
2
4
  from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
3
5
 
6
+ logger = logging.getLogger(__name__)
7
+
8
+ {{#if hasGateway}}
9
+ {{#if (includes gatewayAuthTypes "AWS_IAM")}}
10
+ import httpx
11
+ from mcp_proxy_for_aws.sigv4_helper import SigV4HTTPXAuth, create_aws_session
12
+ {{/if}}
13
+ {{#if (includes gatewayAuthTypes "CUSTOM_JWT")}}
14
+ from bedrock_agentcore.identity import requires_access_token
15
+ {{/if}}
16
+
17
+ {{#each gatewayProviders}}
18
+ {{#if (eq authType "CUSTOM_JWT")}}
19
+ @requires_access_token(
20
+ provider_name="{{credentialProviderName}}",
21
+ scopes=[{{#if scopes}}"{{scopes}}"{{/if}}],
22
+ auth_flow="M2M",
23
+ )
24
+ def _get_bearer_token_{{snakeCase name}}(*, access_token: str):
25
+ """Obtain OAuth access token via AgentCore Identity for {{name}}."""
26
+ return access_token
27
+
28
+ {{/if}}
29
+ {{/each}}
30
+
31
+ def get_all_gateway_mcp_toolsets() -> list[MCPToolset]:
32
+ """Returns MCP Toolsets for all configured gateways."""
33
+ toolsets = []
34
+ {{#each gatewayProviders}}
35
+ url = os.environ.get("{{envVarName}}")
36
+ if url:
37
+ {{#if (eq authType "AWS_IAM")}}
38
+ session = create_aws_session()
39
+ auth = SigV4HTTPXAuth(session.get_credentials(), "bedrock-agentcore", session.region_name)
40
+ toolsets.append(MCPToolset(connection_params=StreamableHTTPConnectionParams(
41
+ url=url,
42
+ httpx_client_factory=lambda **kwargs: httpx.AsyncClient(auth=auth, **kwargs)
43
+ )))
44
+ {{else if (eq authType "CUSTOM_JWT")}}
45
+ token = _get_bearer_token_{{snakeCase name}}()
46
+ headers = {"Authorization": f"Bearer {token}"} if token else None
47
+ toolsets.append(MCPToolset(connection_params=StreamableHTTPConnectionParams(url=url, headers=headers)))
48
+ {{else}}
49
+ toolsets.append(MCPToolset(connection_params=StreamableHTTPConnectionParams(url=url)))
50
+ {{/if}}
51
+ else:
52
+ logger.warning("{{envVarName}} not set — {{name}} gateway tools unavailable")
53
+ {{/each}}
54
+ return toolsets
55
+ {{else}}
4
56
  # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
5
57
  EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
6
58
 
7
59
 
8
60
  def get_streamable_http_mcp_client() -> MCPToolset:
9
- """
10
- Returns an MCP Toolset compatible with Google ADK.
11
- """
61
+ """Returns an MCP Toolset compatible with Google ADK."""
12
62
  # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
13
63
  return MCPToolset(
14
64
  connection_params=StreamableHTTPConnectionParams(url=EXAMPLE_MCP_ENDPOINT)
15
65
  )
66
+ {{/if}}
@@ -14,6 +14,8 @@ dependencies = [
14
14
  "google-adk >= 1.17.0",
15
15
  "bedrock-agentcore >= 1.0.3",
16
16
  "botocore[crt] >= 1.35.0",
17
+ {{#if hasGateway}}{{#if (includes gatewayAuthTypes "AWS_IAM")}}"mcp-proxy-for-aws >= 1.1.0",
18
+ {{/if}}{{/if}}
17
19
  ]
18
20
 
19
21
  [tool.hatch.build.targets.wheel]
@@ -4,7 +4,11 @@ from langgraph.prebuilt import create_react_agent
4
4
  from langchain.tools import tool
5
5
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
6
6
  from model.load import load_model
7
+ {{#if hasGateway}}
8
+ from mcp_client.client import get_all_gateway_mcp_client
9
+ {{else}}
7
10
  from mcp_client.client import get_streamable_http_mcp_client
11
+ {{/if}}
8
12
 
9
13
  app = BedrockAgentCoreApp()
10
14
  log = app.logger
@@ -34,10 +38,16 @@ async def invoke(payload, context):
34
38
  log.info("Invoking Agent.....")
35
39
 
36
40
  # Get MCP Client
41
+ {{#if hasGateway}}
42
+ mcp_client = get_all_gateway_mcp_client()
43
+ {{else}}
37
44
  mcp_client = get_streamable_http_mcp_client()
45
+ {{/if}}
38
46
 
39
47
  # Load MCP Tools
40
- mcp_tools = await mcp_client.get_tools()
48
+ mcp_tools = []
49
+ if mcp_client:
50
+ mcp_tools = await mcp_client.get_tools()
41
51
 
42
52
  # Define the agent using create_react_agent
43
53
  graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools)
@@ -1,13 +1,61 @@
1
+ import os
2
+ import logging
1
3
  from langchain_mcp_adapters.client import MultiServerMCPClient
2
4
 
5
+ logger = logging.getLogger(__name__)
6
+
7
+ {{#if hasGateway}}
8
+ {{#if (includes gatewayAuthTypes "AWS_IAM")}}
9
+ from mcp_proxy_for_aws.sigv4_helper import SigV4HTTPXAuth, create_aws_session
10
+ {{/if}}
11
+ {{#if (includes gatewayAuthTypes "CUSTOM_JWT")}}
12
+ from bedrock_agentcore.identity import requires_access_token
13
+ {{/if}}
14
+
15
+ {{#each gatewayProviders}}
16
+ {{#if (eq authType "CUSTOM_JWT")}}
17
+ @requires_access_token(
18
+ provider_name="{{credentialProviderName}}",
19
+ scopes=[{{#if scopes}}"{{scopes}}"{{/if}}],
20
+ auth_flow="M2M",
21
+ )
22
+ def _get_bearer_token_{{snakeCase name}}(*, access_token: str):
23
+ """Obtain OAuth access token via AgentCore Identity for {{name}}."""
24
+ return access_token
25
+
26
+ {{/if}}
27
+ {{/each}}
28
+
29
+ def get_all_gateway_mcp_client() -> MultiServerMCPClient | None:
30
+ """Returns an MCP Client connected to all configured gateways."""
31
+ servers = {}
32
+ {{#each gatewayProviders}}
33
+ url = os.environ.get("{{envVarName}}")
34
+ if url:
35
+ {{#if (eq authType "AWS_IAM")}}
36
+ session = create_aws_session()
37
+ auth = SigV4HTTPXAuth(session.get_credentials(), "bedrock-agentcore", session.region_name)
38
+ servers["{{name}}"] = {"transport": "streamable_http", "url": url, "auth": auth}
39
+ {{else if (eq authType "CUSTOM_JWT")}}
40
+ token = _get_bearer_token_{{snakeCase name}}()
41
+ headers = {"Authorization": f"Bearer {token}"} if token else None
42
+ servers["{{name}}"] = {"transport": "streamable_http", "url": url, "headers": headers}
43
+ {{else}}
44
+ servers["{{name}}"] = {"transport": "streamable_http", "url": url}
45
+ {{/if}}
46
+ else:
47
+ logger.warning("{{envVarName}} not set — {{name}} gateway tools unavailable")
48
+ {{/each}}
49
+ if not servers:
50
+ return None
51
+ return MultiServerMCPClient(servers)
52
+ {{else}}
3
53
  # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
4
54
  EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
5
55
 
6
56
 
7
57
  def get_streamable_http_mcp_client() -> MultiServerMCPClient:
8
- """
9
- Returns an MCP Client compatible with LangChain/LangGraph.
10
- """
58
+ """Returns an MCP Client compatible with LangChain/LangGraph."""
11
59
  # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
12
60
  return MultiServerMCPClient(
13
61
  {
@@ -17,3 +65,4 @@ def get_streamable_http_mcp_client() -> MultiServerMCPClient:
17
65
  }
18
66
  }
19
67
  )
68
+ {{/if}}
@@ -15,7 +15,6 @@ dependencies = [
15
15
  "mcp >= 1.19.0",
16
16
  "langchain-mcp-adapters >= 0.1.11",
17
17
  "langchain >= 1.0.3",
18
- "tiktoken == 0.11.0",
19
18
  "bedrock-agentcore >= 1.0.3",
20
19
  "botocore[crt] >= 1.35.0",
21
20
  {{#if (eq modelProvider "Bedrock")}}
@@ -30,6 +29,8 @@ dependencies = [
30
29
  {{#if (eq modelProvider "Gemini")}}
31
30
  "langchain-google-genai >= 3.0.3",
32
31
  {{/if}}
32
+ {{#if hasGateway}}{{#if (includes gatewayAuthTypes "AWS_IAM")}}"mcp-proxy-for-aws >= 1.1.0",
33
+ {{/if}}{{/if}}
33
34
  ]
34
35
 
35
36
  [tool.hatch.build.targets.wheel]
@@ -2,13 +2,22 @@ import os
2
2
  from agents import Agent, Runner, function_tool
3
3
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
4
4
  from model.load import load_model
5
+ {{#if hasGateway}}
6
+ from mcp_client.client import get_all_gateway_mcp_servers
7
+ {{else}}
5
8
  from mcp_client.client import get_streamable_http_mcp_client
9
+ {{/if}}
6
10
 
7
11
  app = BedrockAgentCoreApp()
8
12
  log = app.logger
9
13
 
10
14
  # Get MCP Server
15
+ {{#if hasGateway}}
16
+ mcp_servers = get_all_gateway_mcp_servers()
17
+ {{else}}
11
18
  mcp_server = get_streamable_http_mcp_client()
19
+ mcp_servers = [mcp_server] if mcp_server else []
20
+ {{/if}}
12
21
 
13
22
  _credentials_loaded = False
14
23
 
@@ -30,16 +39,47 @@ def add_numbers(a: int, b: int) -> int:
30
39
  async def main(query):
31
40
  ensure_credentials_loaded()
32
41
  try:
33
- async with mcp_server as server:
34
- active_servers = [server] if server else []
42
+ {{#if hasGateway}}
43
+ if mcp_servers:
35
44
  agent = Agent(
36
45
  name="{{ name }}",
37
46
  model="gpt-4.1",
38
- mcp_servers=active_servers,
47
+ mcp_servers=mcp_servers,
39
48
  tools=[add_numbers]
40
49
  )
41
50
  result = await Runner.run(agent, query)
42
51
  return result
52
+ else:
53
+ agent = Agent(
54
+ name="{{ name }}",
55
+ model="gpt-4.1",
56
+ mcp_servers=[],
57
+ tools=[add_numbers]
58
+ )
59
+ result = await Runner.run(agent, query)
60
+ return result
61
+ {{else}}
62
+ if mcp_servers:
63
+ async with mcp_servers[0] as server:
64
+ active_servers = [server]
65
+ agent = Agent(
66
+ name="{{ name }}",
67
+ model="gpt-4.1",
68
+ mcp_servers=active_servers,
69
+ tools=[add_numbers]
70
+ )
71
+ result = await Runner.run(agent, query)
72
+ return result
73
+ else:
74
+ agent = Agent(
75
+ name="{{ name }}",
76
+ model="gpt-4.1",
77
+ mcp_servers=[],
78
+ tools=[add_numbers]
79
+ )
80
+ result = await Runner.run(agent, query)
81
+ return result
82
+ {{/if}}
43
83
  except Exception as e:
44
84
  log.error(f"Error during agent execution: {e}", exc_info=True)
45
85
  raise e
@@ -1,14 +1,65 @@
1
+ import os
2
+ import logging
1
3
  from agents.mcp import MCPServerStreamableHttp
2
4
 
5
+ logger = logging.getLogger(__name__)
6
+
7
+ {{#if hasGateway}}
8
+ {{#if (includes gatewayAuthTypes "AWS_IAM")}}
9
+ import httpx
10
+ from mcp_proxy_for_aws.sigv4_helper import SigV4HTTPXAuth, create_aws_session
11
+ {{/if}}
12
+ {{#if (includes gatewayAuthTypes "CUSTOM_JWT")}}
13
+ from bedrock_agentcore.identity import requires_access_token
14
+ {{/if}}
15
+
16
+ {{#each gatewayProviders}}
17
+ {{#if (eq authType "CUSTOM_JWT")}}
18
+ @requires_access_token(
19
+ provider_name="{{credentialProviderName}}",
20
+ scopes=[{{#if scopes}}"{{scopes}}"{{/if}}],
21
+ auth_flow="M2M",
22
+ )
23
+ def _get_bearer_token_{{snakeCase name}}(*, access_token: str):
24
+ """Obtain OAuth access token via AgentCore Identity for {{name}}."""
25
+ return access_token
26
+
27
+ {{/if}}
28
+ {{/each}}
29
+
30
+ def get_all_gateway_mcp_servers() -> list[MCPServerStreamableHttp]:
31
+ """Returns MCP servers for all configured gateways."""
32
+ servers = []
33
+ {{#each gatewayProviders}}
34
+ url = os.environ.get("{{envVarName}}")
35
+ if url:
36
+ {{#if (eq authType "AWS_IAM")}}
37
+ session = create_aws_session()
38
+ auth = SigV4HTTPXAuth(session.get_credentials(), "bedrock-agentcore", session.region_name)
39
+ servers.append(MCPServerStreamableHttp(
40
+ name="{{name}}",
41
+ params={"url": url, "httpx_client_factory": lambda **kwargs: httpx.AsyncClient(auth=auth, **kwargs)}
42
+ ))
43
+ {{else if (eq authType "CUSTOM_JWT")}}
44
+ token = _get_bearer_token_{{snakeCase name}}()
45
+ headers = {"Authorization": f"Bearer {token}"} if token else {}
46
+ servers.append(MCPServerStreamableHttp(name="{{name}}", params={"url": url, "headers": headers}))
47
+ {{else}}
48
+ servers.append(MCPServerStreamableHttp(name="{{name}}", params={"url": url}))
49
+ {{/if}}
50
+ else:
51
+ logger.warning("{{envVarName}} not set — {{name}} gateway tools unavailable")
52
+ {{/each}}
53
+ return servers
54
+ {{else}}
3
55
  # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
4
56
  EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
5
57
 
6
58
 
7
59
  def get_streamable_http_mcp_client() -> MCPServerStreamableHttp:
8
- """
9
- Returns an MCP Client compatible with OpenAI Agents SDK.
10
- """
60
+ """Returns an MCP Client compatible with OpenAI Agents SDK."""
11
61
  # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
12
62
  return MCPServerStreamableHttp(
13
63
  name="AgentCore Gateway MCP", params={"url": EXAMPLE_MCP_ENDPOINT}
14
64
  )
65
+ {{/if}}
@@ -13,6 +13,8 @@ dependencies = [
13
13
  "openai-agents >= 0.4.2",
14
14
  "bedrock-agentcore >= 1.0.3",
15
15
  "botocore[crt] >= 1.35.0",
16
+ {{#if hasGateway}}{{#if (includes gatewayAuthTypes "AWS_IAM")}}"mcp-proxy-for-aws >= 1.1.0",
17
+ {{/if}}{{/if}}
16
18
  ]
17
19
 
18
20
  [tool.hatch.build.targets.wheel]
@@ -1,4 +1,4 @@
1
- This is a project generated by the agentcore create basic CLI tool!
1
+ This is a project generated by the AgentCore CLI!
2
2
 
3
3
  # Layout
4
4