Skip to content
Merged
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aws/agentcore",
"version": "0.3.0-preview.2.1",
"version": "0.3.0-preview.3",
"description": "CLI for Amazon Bedrock AgentCore",
"license": "Apache-2.0",
"repository": {
Expand Down
38 changes: 24 additions & 14 deletions src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,20 @@ async function main() {

// Read MCP configuration if it exists
let mcpSpec;
let mcpDeployedState;
try {
mcpSpec = await configIO.readMcpSpec();
const deployedState = JSON.parse(fs.readFileSync(path.join(configRoot, '.cli', 'deployed-state.json'), 'utf8'));
mcpDeployedState = deployedState?.mcp;
} catch {
// MCP config is optional
}

// Read deployed state for credential ARNs (populated by pre-deploy identity setup)
let deployedState: Record<string, unknown> | undefined;
try {
deployedState = JSON.parse(fs.readFileSync(path.join(configRoot, '.cli', 'deployed-state.json'), 'utf8'));
} catch {
// Deployed state may not exist on first deploy
}

if (targets.length === 0) {
throw new Error('No deployment targets configured. Please define targets in agentcore/aws-targets.json');
}
Expand All @@ -78,10 +83,15 @@ async function main() {
const env = toEnvironment(target);
const stackName = toStackName(spec.name, target.name);

// Extract credentials from deployed state for this target
const targetState = (deployedState as Record<string, unknown>)?.targets as Record<string, Record<string, unknown>> | undefined;
const targetResources = targetState?.[target.name]?.resources as Record<string, unknown> | undefined;
const credentials = targetResources?.credentials as Record<string, { credentialProviderArn: string; clientSecretArn?: string }> | undefined;

new AgentCoreStack(app, stackName, {
spec,
mcpSpec,
mcpDeployedState,
credentials,
env,
description: \`AgentCore stack for \${spec.name} deployed to \${target.name} (\${target.region})\`,
tags: {
Expand Down Expand Up @@ -221,8 +231,7 @@ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/lib/cdk-stack.ts shou
AgentCoreApplication,
AgentCoreMcp,
type AgentCoreProjectSpec,
type McpSpec,
type McpDeployedState,
type AgentCoreMcpSpec,
} from '@aws/agentcore-cdk';
import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
Expand All @@ -235,11 +244,11 @@ export interface AgentCoreStackProps extends StackProps {
/**
* The MCP specification containing gateways and servers.
*/
mcpSpec?: McpSpec;
mcpSpec?: AgentCoreMcpSpec;
/**
* The MCP deployed state.
* Credential provider ARNs from deployed state, keyed by credential name.
*/
mcpDeployedState?: McpDeployedState;
credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
}

/**
Expand All @@ -255,7 +264,7 @@ export class AgentCoreStack extends Stack {
constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
super(scope, id, props);

const { spec, mcpSpec, mcpDeployedState } = props;
const { spec, mcpSpec, credentials } = props;

// Create AgentCoreApplication with all agents
this.application = new AgentCoreApplication(this, 'Application', {
Expand All @@ -265,9 +274,10 @@ export class AgentCoreStack extends Stack {
// Create AgentCoreMcp if there are gateways configured
if (mcpSpec?.agentCoreGateways && mcpSpec.agentCoreGateways.length > 0) {
new AgentCoreMcp(this, 'Mcp', {
spec: mcpSpec,
deployedState: mcpDeployedState,
application: this.application,
projectName: spec.name,
mcpSpec,
agentCoreApplication: this.application,
credentials,
});
}

Expand Down Expand Up @@ -318,7 +328,7 @@ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/package.json should m
},
"dependencies": {
"@aws/agentcore-cdk": "^0.1.0-alpha.1",
"aws-cdk-lib": "2.234.1",
"aws-cdk-lib": "2.239.0",
"constructs": "^10.0.0"
}
}
Expand Down
18 changes: 14 additions & 4 deletions src/assets/cdk/bin/cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,20 @@ async function main() {

// Read MCP configuration if it exists
let mcpSpec;
let mcpDeployedState;
try {
mcpSpec = await configIO.readMcpSpec();
const deployedState = JSON.parse(fs.readFileSync(path.join(configRoot, '.cli', 'deployed-state.json'), 'utf8'));
mcpDeployedState = deployedState?.mcp;
} catch {
// MCP config is optional
}

// Read deployed state for credential ARNs (populated by pre-deploy identity setup)
let deployedState: Record<string, unknown> | undefined;
try {
deployedState = JSON.parse(fs.readFileSync(path.join(configRoot, '.cli', 'deployed-state.json'), 'utf8'));
} catch {
// Deployed state may not exist on first deploy
}

if (targets.length === 0) {
throw new Error('No deployment targets configured. Please define targets in agentcore/aws-targets.json');
}
Expand All @@ -45,10 +50,15 @@ async function main() {
const env = toEnvironment(target);
const stackName = toStackName(spec.name, target.name);

// Extract credentials from deployed state for this target
const targetState = (deployedState as Record<string, unknown>)?.targets as Record<string, Record<string, unknown>> | undefined;
const targetResources = targetState?.[target.name]?.resources as Record<string, unknown> | undefined;
const credentials = targetResources?.credentials as Record<string, { credentialProviderArn: string; clientSecretArn?: string }> | undefined;

new AgentCoreStack(app, stackName, {
spec,
mcpSpec,
mcpDeployedState,
credentials,
env,
description: `AgentCore stack for ${spec.name} deployed to ${target.name} (${target.region})`,
tags: {
Expand Down
18 changes: 9 additions & 9 deletions src/assets/cdk/lib/cdk-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import {
AgentCoreApplication,
AgentCoreMcp,
type AgentCoreProjectSpec,
type McpSpec,
type McpDeployedState,
type AgentCoreMcpSpec,
} from '@aws/agentcore-cdk';
import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
Expand All @@ -16,11 +15,11 @@ export interface AgentCoreStackProps extends StackProps {
/**
* The MCP specification containing gateways and servers.
*/
mcpSpec?: McpSpec;
mcpSpec?: AgentCoreMcpSpec;
/**
* The MCP deployed state.
* Credential provider ARNs from deployed state, keyed by credential name.
*/
mcpDeployedState?: McpDeployedState;
credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
}

/**
Expand All @@ -36,7 +35,7 @@ export class AgentCoreStack extends Stack {
constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
super(scope, id, props);

const { spec, mcpSpec, mcpDeployedState } = props;
const { spec, mcpSpec, credentials } = props;

// Create AgentCoreApplication with all agents
this.application = new AgentCoreApplication(this, 'Application', {
Expand All @@ -46,9 +45,10 @@ export class AgentCoreStack extends Stack {
// Create AgentCoreMcp if there are gateways configured
if (mcpSpec?.agentCoreGateways && mcpSpec.agentCoreGateways.length > 0) {
new AgentCoreMcp(this, 'Mcp', {
spec: mcpSpec,
deployedState: mcpDeployedState,
application: this.application,
projectName: spec.name,
mcpSpec,
agentCoreApplication: this.application,
credentials,
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/assets/cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"dependencies": {
"@aws/agentcore-cdk": "^0.1.0-alpha.1",
"aws-cdk-lib": "2.234.1",
"aws-cdk-lib": "2.239.0",
"constructs": "^10.0.0"
}
}
4 changes: 2 additions & 2 deletions src/cli/cloudformation/outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export function parseGatewayOutputs(
const gatewayNames = Object.keys(gatewaySpecs);
const gatewayIdMap = new Map(gatewayNames.map(name => [toPascalId(name), name]));

// Match pattern: Gateway{GatewayName}UrlOutput
const outputPattern = /^Gateway(.+?)UrlOutput/;
// Match patterns: Gateway{Name}{Type}Output or McpGateway{Name}{Type}Output
const outputPattern = /^(?:Mcp)?Gateway(.+?)(Id|Arn|Url)Output/;

for (const [key, value] of Object.entries(outputs)) {
const match = outputPattern.exec(key);
Expand Down
Loading
Loading