Skip to content
Open
4 changes: 2 additions & 2 deletions client-strands-agents-mcp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from strands.tools.mcp import MCPClient

# Add your API Gateway URL here as it outputs from the sam deploy command (include /mcp at the end):
api_gateway_url = "https://1234567890.execute-api.us-east-1.amazonaws.com/Prod/mcp"
auth_token = "1234567890"
api_gateway_url = "https://ma8rga14yj.execute-api.us-west-2.amazonaws.com/Prod/mcp"
auth_token = "juhui"

# This uses the Nova Pro model from Amazon Bedrock, in a US region:
bedrock_model = BedrockModel(
Expand Down
129 changes: 129 additions & 0 deletions server-http-python-lambda/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import random
import boto3
import os
import ipaddress
import json
import ast

# Get session table name from environment variable
session_table = os.environ.get('MCP_SESSION_TABLE', 'mcp_sessions')
Expand Down Expand Up @@ -72,6 +75,132 @@ def update_last_time(s):
# Catch-all for unexpected errors
return f"Error: An unexpected error occurred: {str(e)}"

@mcp_server.tool()
def create_vpc(params: dict) -> dict:
"""
Generalized VPC and Subnet Creator for OSS contribution.

Parameters expected in `params`:
- cidr_block: str
- az_list: list[str]
- public_subnets_per_az: int
- private_subnets_per_az: int
- name_tag: str

e.g.
createVpc(params={"cidr_block":"10.20.0.0/16","az_list":["us-west-2a","us-west-2b"],"public_subnets_per_az":1,"private_subnets_per_az":1,"name_tag":"mcp"})
"""
ec2 = boto3.client("ec2", region_name="us-west-2")
out = {}


if isinstance(params, str):
params = json.loads(params)
# Extract parameters with defaults
cidr_block = params.get("cidr_block", "10.0.0.0/16")
az_list = params.get("az_list", ["us-west-2a", "us-west-2b"])
public_subnets_per_az = params.get("public_subnets_per_az", 1)
private_subnets_per_az = params.get("private_subnets_per_az", 1)
name_tag = params.get("name_tag", "mcp-server")

total_subnets_needed = (public_subnets_per_az + private_subnets_per_az) * len(az_list)
subnet_blocks = list(ipaddress.ip_network(cidr_block).subnets(new_prefix=24))
if len(subnet_blocks) < total_subnets_needed:
raise Exception("Not enough subnet blocks in CIDR for requested subnets.")

# Check existing VPC
existing = ec2.describe_vpcs(Filters=[
{"Name": "tag:Name", "Values": [f"{name_tag}-vpc"]}
])["Vpcs"]
if existing:
vpc_id = existing[0]["VpcId"]
print(f"[INFO] Existing VPC found: {vpc_id}")
out["VpcId"] = vpc_id
return out

# Create VPC
vpc_id = ec2.create_vpc(CidrBlock=cidr_block)["Vpc"]["VpcId"]
ec2.modify_vpc_attribute(VpcId=vpc_id, EnableDnsSupport={"Value": True})
ec2.modify_vpc_attribute(VpcId=vpc_id, EnableDnsHostnames={"Value": True})
ec2.create_tags(Resources=[vpc_id],
Tags=[{"Key": "Name", "Value": f"{name_tag}-vpc"}])
out["VpcId"] = vpc_id

# IGW and main route
igw_id = ec2.create_internet_gateway()["InternetGateway"]["InternetGatewayId"]
ec2.attach_internet_gateway(VpcId=vpc_id, InternetGatewayId=igw_id)
out["InternetGatewayId"] = igw_id

main_rt_id = ec2.describe_route_tables(
Filters=[
{"Name": "vpc-id", "Values": [vpc_id]},
{"Name": "association.main", "Values": ["true"]}
]
)["RouteTables"][0]["RouteTableId"]
ec2.create_route(RouteTableId=main_rt_id,
DestinationCidrBlock="0.0.0.0/0",
GatewayId=igw_id)

out["PublicSubnets"] = []
out["PrivateSubnets"] = []

idx = 0
for az in az_list:
# Create public subnets
for i in range(public_subnets_per_az):
cidr_pub = str(subnet_blocks[idx])
idx += 1
pub_subnet = ec2.create_subnet(
VpcId=vpc_id, CidrBlock=cidr_pub, AvailabilityZone=az,
TagSpecifications=[{
"ResourceType": "subnet",
"Tags": [{"Key": "Name", "Value": f"{name_tag}-pub-{az}-{i}"}]
}]
)["Subnet"]
pub_id = pub_subnet["SubnetId"]
ec2.modify_subnet_attribute(SubnetId=pub_id, MapPublicIpOnLaunch={"Value": True})
out["PublicSubnets"].append(pub_id)

# Create NAT Gateway for private subnets
eip = ec2.allocate_address(Domain="vpc")["AllocationId"]
nat = ec2.create_nat_gateway(
SubnetId=pub_id, AllocationId=eip,
TagSpecifications=[{
"ResourceType": "natgateway",
"Tags": [{"Key": "Name", "Value": f"{name_tag}-nat-{az}"}]
}]
)["NatGateway"]
nat_id = nat["NatGatewayId"]

waiter = ec2.get_waiter("nat_gateway_available")
print(f"Waiting for NAT Gateway {nat_id} in {az}...")
waiter.wait(NatGatewayIds=[nat_id])
print(f"NAT Gateway {nat_id} is available.")

# Create private subnets
for i in range(private_subnets_per_az):
cidr_pri = str(subnet_blocks[idx])
idx += 1
pri_subnet = ec2.create_subnet(
VpcId=vpc_id, CidrBlock=cidr_pri, AvailabilityZone=az,
TagSpecifications=[{
"ResourceType": "subnet",
"Tags": [{"Key": "Name", "Value": f"{name_tag}-pri-{az}-{i}"}]
}]
)["Subnet"]
pri_id = pri_subnet["SubnetId"]
out["PrivateSubnets"].append(pri_id)

rt_priv = ec2.create_route_table(VpcId=vpc_id)["RouteTable"]["RouteTableId"]
ec2.associate_route_table(RouteTableId=rt_priv, SubnetId=pri_id)
ec2.create_route(RouteTableId=rt_priv,
DestinationCidrBlock="0.0.0.0/0",
NatGatewayId=nat_id)

return {
"Message": f"VPC {vpc_id} and related resources created successfully."
}

def lambda_handler(event, context):
"""AWS Lambda handler function."""
return mcp_server.handle_request(event, context)
22 changes: 21 additions & 1 deletion server-http-python-lambda/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Parameters:

Globals:
Function:
Timeout: 60
Timeout: 900
Runtime: python3.12
Architectures: [x86_64]

Expand Down Expand Up @@ -85,6 +85,26 @@ Resources:
- dynamodb:UpdateItem
- dynamodb:DescribeTable
Resource: !GetAtt McpSessionsTable.Arn
- Effect: Allow
Action:
- ec2:CreateVpc
- ec2:ModifyVpcAttribute
- ec2:CreateTags
- ec2:DescribeVpcs
- ec2:CreateInternetGateway
- ec2:AttachInternetGateway
- ec2:DescribeInternetGateways
- ec2:DescribeRouteTables
- ec2:CreateRoute
- ec2:CreateRouteTable
- ec2:AssociateRouteTable
- ec2:CreateSubnet
- ec2:ModifySubnetAttribute
- ec2:DescribeSubnets
- ec2:AllocateAddress
- ec2:CreateNatGateway
- ec2:DescribeNatGateways
Resource: "*"
Events:
McpAPI:
Type: Api
Expand Down