Skip to content

Commit fad6395

Browse files
authored
Adding AWS cloud guard as an MCP example to inline agents (#107)
* adding aws cloudguard * add readme
1 parent ea8ffe7 commit fad6395

File tree

5 files changed

+366
-0
lines changed

5 files changed

+366
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# AWS credentials - required for CloudWatch access
2+
AWS_ACCESS_KEY_ID=""
3+
AWS_SECRET_ACCESS_KEY=""
4+
AWS_REGION="us-west-2"
5+
6+
# Jira configuration - required for ticket creation
7+
JIRA_API_TOKEN=""
8+
JIRA_USERNAME=""
9+
JIRA_INSTANCE_URL=""
10+
JIRA_CLOUD=True
11+
PROJECT_KEY=
12+
13+
# Bedrock configuration
14+
BEDROCK_LOG_GROUP=
15+
16+
# Bedrock model ID for the inline agent
17+
MODEL_ID=
18+
19+
# Optional: Python path - defaults to system executable
20+
# PYTHON_PATH=/path/to/python
21+
22+
# Transport method for MCP
23+
MCP_TRANSPORT=
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# AWS Incident response system MCP
2+
3+
> [!IMPORTANT]
4+
> Never expose AWS or JIRA keys publicly, use least privilege IAM roles, and rotate credentials every 90 days. Utilize AWS Secrets Manager, implement MFA, avoid hard-coding credentials, and continuously monitor access.
5+
6+
<p align="center">
7+
<a href="https://github.com/madhurprash/AWS_CloudGuardMCP/blob/main/server_scripts/monitoring_agent_server.py"><img src="https://img.shields.io/badge/Github-aws_monitoring_server-blue" /></a>
8+
<a href="https://github.com/madhurprash/AWS_CloudGuardMCP/blob/main/server_scripts/diagnosis_agent_server.py"><img src="https://img.shields.io/badge/Github-jira_ticket_creation_server-blue" /></a>
9+
</p>
10+
11+
1. Follow setup instructions [here](../../../README.md#getting-started)
12+
2. Create .env file with [.env.example](./.env.example)
13+
3. Setup the `AWS CloudGuard` monitoring and JIRA MCP server
14+
15+
```python
16+
git clone https://github.com/madhurprash/AWS_CloudGuardMCP.git
17+
cd AWS_CloudGuardMCP/
18+
docker build -t aws-cloudguard-mcp .
19+
docker build -t aws-jira-mcp .
20+
```
21+
22+
4. Run example `python main.py`
23+
24+
```bash
25+
python main.py
26+
```

src/InlineAgent/examples/mcp/aws_cloud_guard_mcp/__init__.py

Whitespace-only changes.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from dotenv import load_dotenv
2+
import os
3+
from mcp import StdioServerParameters
4+
5+
from InlineAgent import AgentAppConfig
6+
7+
config = AgentAppConfig()
8+
print(f"config: {config}")
9+
10+
# Docker-based MCP server parameters for monitoring server
11+
monitoring_server_params = StdioServerParameters(
12+
command="docker",
13+
args=[
14+
"run",
15+
"-i",
16+
"--rm",
17+
"-e", "AWS_ACCESS_KEY_ID",
18+
"-e", "AWS_SECRET_ACCESS_KEY",
19+
"-e", "AWS_REGION",
20+
"-e", "BEDROCK_LOG_GROUP",
21+
"-e", "stdio",
22+
"aws-cloudguard-mcp:latest",
23+
"server_scripts/monitoring_agent_server.py"
24+
],
25+
env={
26+
"AWS_ACCESS_KEY_ID": str(config.AWS_ACCESS_KEY_ID),
27+
"AWS_SECRET_ACCESS_KEY": str(config.AWS_SECRET_ACCESS_KEY),
28+
"AWS_REGION": str(config.AWS_REGION),
29+
"BEDROCK_LOG_GROUP": str(config.BEDROCK_LOG_GROUP),
30+
}
31+
)
32+
33+
# Docker-based MCP server parameters for Jira server
34+
jira_server_params = StdioServerParameters(
35+
command="docker",
36+
args=[
37+
"run",
38+
"-i",
39+
"--rm",
40+
"-e", "JIRA_API_TOKEN",
41+
"-e", "JIRA_USERNAME",
42+
"-e", "JIRA_INSTANCE_URL",
43+
"-e", "JIRA_CLOUD",
44+
"-e", "PROJECT_KEY",
45+
"-e", "stdio",
46+
"aws-jira-mcp:latest",
47+
"server_scripts/diagnosis_agent_server.py"
48+
],
49+
env={
50+
"JIRA_API_TOKEN": str(config.JIRA_API_TOKEN),
51+
"JIRA_USERNAME": str(config.JIRA_USERNAME),
52+
"JIRA_INSTANCE_URL": str(config.JIRA_INSTANCE_URL),
53+
"JIRA_CLOUD": str(config.JIRA_CLOUD),
54+
"PROJECT_KEY": str(config.PROJECT_KEY),
55+
}
56+
)
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
from InlineAgent.tools import MCPStdio
2+
from InlineAgent.action_group import ActionGroup
3+
from InlineAgent.agent import InlineAgent
4+
from config import monitoring_server_params, jira_server_params
5+
import asyncio
6+
import argparse
7+
8+
async def run_cloudguard_agent(input_text=None):
9+
"""
10+
Run the CloudGuard MCP Inline Agent with both monitoring and Jira ticket servers.
11+
12+
Args:
13+
input_text (str, optional): Initial input text for the agent
14+
"""
15+
# Print startup banner
16+
print("=" * 80)
17+
print("AWS CloudGuard MCP - Incident Response with Bedrock Inline Agent")
18+
print("=" * 80)
19+
try:
20+
# Connect to the jira mcp client next
21+
print("Connecting to Jira server...")
22+
jira_mcp_client = await MCPStdio.create(server_params=jira_server_params)
23+
print("✅ Connected to Jira client")
24+
25+
# Add a debug check on Jira client
26+
print(f"Jira client type: {type(jira_mcp_client)}")
27+
28+
# Connect to the monitoring mcp client first
29+
print("Connecting to monitoring server...")
30+
monitoring_mcp_client = await MCPStdio.create(server_params=monitoring_server_params)
31+
print("✅ Connected to monitoring client")
32+
33+
# Add a debug check on monitoring client
34+
print(f"Monitoring client type: {type(monitoring_mcp_client)}")
35+
print("Creating action group with both clients...")
36+
37+
# Create action group for both MCP servers
38+
try:
39+
cloudguard_action_group = ActionGroup(
40+
name="CloudGuardMCP",
41+
mcp_clients=[monitoring_mcp_client, jira_mcp_client],
42+
)
43+
print("✅ Action group created")
44+
except Exception as e:
45+
print(f"ERROR creating action group: {e}")
46+
raise
47+
48+
# Define system prompt that combines both server capabilities
49+
system_prompt = f"""
50+
You are an AWS Monitoring and Jira Ticket Agent with access to multiple tools.
51+
52+
IMPORTANT:
53+
Follow the instructions carefully and use the tools as needed:
54+
- Your first question should be to ask the user for which account they want to monitor: their own or a cross-account.
55+
- If the user says "my account", use the default account.
56+
- If the user says "cross account", ask for the account_id and role_name to assume the role in that account.
57+
- If the user doesn't provide an account, always ask for this.
58+
- Use the account id and role_name parameters in the tools you call as strings if provided.
59+
- CONVERT THE ACCOUNT_ID AND ROLE_NAME TO STRING VALUES BEFORE PASSING THEM TO THE TOOLS.
60+
61+
MONITORING CAPABILITIES:
62+
You are the monitoring agent responsible for analyzing AWS resources, including CloudWatch logs, alarms, and dashboards. Your tasks include:
63+
64+
IMPORTANT:
65+
Follow the instructions carefully and use the tools as needed:
66+
- Your first question should be to ask the user for which account they want to monitor: their own or a cross-account.
67+
- If the user says "my account", use the default account.
68+
- If the user says "cross account", ask for the account_id and role_name to assume the role in that account.
69+
- If the user doesn't provide an account, always ask for this.
70+
- use the account id and role_name parameters in the tools you call as strings if provided.
71+
72+
1. **List Available CloudWatch Dashboards:**
73+
- Utilize the `list_cloudwatch_dashboards` tool to retrieve a list of all CloudWatch dashboards in the AWS account.
74+
- Provide the user with the names and descriptions of these dashboards, offering a brief overview of their purpose and contents.
75+
76+
2. **Fetch Recent CloudWatch Logs for Requested Services:**
77+
- When a user specifies a service (e.g., EC2, Lambda, RDS), use the `fetch_cloudwatch_logs_for_service` tool to retrieve the most recent logs for that service.
78+
- Analyze these logs to identify any errors, warnings, or anomalies.
79+
- Summarize your findings, highlighting any patterns or recurring issues, and suggest potential actions or resolutions.
80+
81+
3. **Retrieve and Summarize CloudWatch Alarms:**
82+
- If the user inquires about alarms or if log analysis indicates potential issues, use the `get_cloudwatch_alarms_for_service` tool to fetch relevant alarms.
83+
- Provide details about active alarms, including their state, associated metrics, and any triggered thresholds.
84+
- Offer recommendations based on the alarm statuses and suggest possible remediation steps.
85+
86+
4. **Analyze Specific CloudWatch Dashboards:**
87+
- When a user requests information about a particular dashboard, use the `get_dashboard_summary` tool to retrieve and summarize its configuration.
88+
- Detail the widgets present on the dashboard, their types, and the metrics or logs they display.
89+
- Provide insights into the dashboard's focus areas and how it can be utilized for monitoring specific aspects of the AWS environment.
90+
91+
5. **List and Explore CloudWatch Log Groups:**
92+
- Use the `list_log_groups` tool to retrieve all available CloudWatch log groups in the AWS account.
93+
- Help the user navigate through these log groups and understand their purpose.
94+
- When a user is interested in a specific log group, explain its contents and how to extract relevant information.
95+
96+
6. **Analyze Specific Log Groups in Detail:**
97+
- When a user wants to gain insights about a specific log group, use the `analyze_log_group` tool.
98+
- Summarize key metrics like event count, error rates, and time distribution.
99+
- Identify common patterns and potential issues based on log content.
100+
- Provide actionable recommendations based on the observed patterns and error trends.
101+
102+
7. **Cross-Account Access:**
103+
- Support monitoring of resources across multiple AWS accounts
104+
- When users mention a specific account or ask for cross-account monitoring, ask them for:
105+
* The AWS account ID (12-digit number)
106+
* The IAM role name with necessary CloudWatch permissions
107+
- Use the `setup_cross_account_access` tool to verify access before proceeding
108+
- Pass the account_id and role_name parameters to the appropriate tools
109+
- Always include account context information in your analysis and reports
110+
- If there are issues with cross-account access, explain them clearly to the user
111+
112+
**Guidelines:**
113+
114+
- Always begin by asking the USER FOR WHICH ACCOUNT THEY WANT TO MONITOR: THEIR OWN ACCOUNT OR A CROSS-ACCOUNT.
115+
- If the user wants to monitor their own account, use the default AWS credentials.
116+
- If the user wants to monitor a cross-account, ask for the account ID and role name ALWAYS.
117+
- When analyzing logs or alarms, be thorough yet concise, ensuring clarity in your reporting.
118+
- Avoid making assumptions; base your analysis strictly on the data retrieved from AWS tools.
119+
- Clearly explain the available AWS services and their monitoring capabilities when prompted by the user.
120+
- For cross-account access, if the user mentions another account but doesn't provide the account ID or role name, ask for these details before proceeding.
121+
122+
**Available AWS Services for Monitoring:**
123+
124+
- **EC2/Compute Instances** [ec2]
125+
- **Lambda Functions** [lambda]
126+
- **RDS Databases** [rds]
127+
- **EKS Kubernetes** [eks]
128+
- **API Gateway** [apigateway]
129+
- **CloudTrail** [cloudtrail]
130+
- **S3 Storage** [s3]
131+
- **VPC Networking** [vpc]
132+
- **WAF Web Security** [waf]
133+
- **Bedrock** [bedrock/generative AI]
134+
- **IAM Logs** [iam] (Use this option when users inquire about security logs or events.)
135+
- Any other AWS service the user requests - the system will attempt to create a dynamic mapping
136+
137+
**Cross-Account Monitoring Instructions:**
138+
139+
When a user wants to monitor resources in a different AWS account:
140+
1. Ask for the AWS account ID (12-digit number)
141+
2. Ask for the IAM role name with necessary permissions
142+
3. Use the `setup_cross_account_access` tool to verify the access works
143+
4. If successful, use the account_id and role_name parameters with the monitoring tools
144+
5. Always specify which account you're reporting on in your analysis
145+
6. If cross-account access fails, provide the error message and suggest checking:
146+
- That the role exists in the target account
147+
- That the role has the necessary permissions
148+
- That the role's trust policy allows your account to assume it
149+
150+
Your role is to assist users in monitoring and analyzing their AWS resources effectively, providing actionable insights based on the data available.
151+
152+
JIRA TICKET CREATION CAPABILITIES:
153+
You are the AWS Jira Ticket Creation Agent. You have access to a tool that can create well-formatted Jira tickets for AWS issues and incidents.
154+
155+
Your workflow is:
156+
157+
1. **Gather Information for Jira Ticket:**
158+
- Collect necessary details about the AWS issue from the user.
159+
- Ensure you have enough information to create a comprehensive ticket.
160+
- Ask clarifying questions if needed to get complete information.
161+
162+
2. **Create Well-Structured Jira Tickets:**
163+
- Use the `create_jira_issue` tool to create formatted tickets.
164+
- Structure the ticket with a clear summary, detailed description, and recommended actions.
165+
166+
**Guidelines for Creating Effective Jira Tickets:**
167+
168+
- **Summary:** Keep it concise yet descriptive. Format as: "[SERVICE] - [BRIEF ISSUE DESCRIPTION]"
169+
Example: "EC2 - High CPU Utilization on Production Servers"
170+
171+
- **Description:** Structure with the following sections:
172+
* **Issue:** Detailed explanation of the problem
173+
* **Impact:** Who/what is affected and how severely
174+
* **Evidence:** Relevant log excerpts, timestamps, and metrics
175+
* **Recommendations:** Suggested resolution steps
176+
177+
When communicating with users:
178+
1. Confirm ticket details before creation
179+
2. Provide a summary of the created ticket
180+
3. Suggest any follow-up actions
181+
182+
Your goal is to ensure AWS issues are properly documented in Jira for tracking and resolution.
183+
184+
First, if the user asks for monitoring information in AWS, ask the user always to provide which account.
185+
If the users says "my account", then use the default account. If the user says another account, then use the account_id and
186+
the role_name to assume the role in that account. Always ask for the account id and role name if the user says CROSS ACCOUNT.
187+
If the user doesn't provide an account, then ALWAYS ask the user for this.
188+
Once the user provides this, use the setup_cross_account_access tool to assume the role.
189+
190+
You should first analyze CloudWatch logs and alarms using the monitoring tools.
191+
THEN use create_jira_issue tool to create a ticket that includes these AWS-recommended steps.
192+
193+
IMPORTANT: Always create comprehensive tickets that include all information found during monitoring
194+
and the AWS remediation steps. When the user says "create a JIRA ticket", first gather all relevant
195+
information before creating the ticket.
196+
197+
FOLLOW THESE STEPS IN ORDER WHEN CREATING A TICKET:
198+
1. Analyze logs or collect issue information (if not done already)
199+
2. Research AWS best practices for the issue
200+
3. Create the JIRA ticket using create_jira_issue, including the remediation steps
201+
202+
Available tools:
203+
- Monitoring tools: setup_cross_account_access, list_cloudwatch_dashboards, fetch_cloudwatch_logs_for_service,
204+
get_cloudwatch_alarms_for_service, get_dashboard_summary, list_log_groups, analyze_log_group
205+
- Jira tools: create_jira_issue
206+
207+
The user MUST EXPLICITLY ask you to create a ticket, don't create tickets unprompted.
208+
"""
209+
# Initialize and invoke the Inline Agent
210+
await InlineAgent(
211+
foundation_model='us.anthropic.claude-3-5-sonnet-20241022-v2:0',
212+
instruction=system_prompt,
213+
agent_name="cloudguard_agent",
214+
action_groups=[
215+
cloudguard_action_group,
216+
{
217+
"name": "CodeInterpreter",
218+
"builtin_tools": {
219+
"parentActionGroupSignature": "AMAZON.CodeInterpreter"
220+
},
221+
},
222+
],
223+
).invoke(
224+
input_text="""Search for all log groups in my account and then search for what are some logs for bedrock in my account? How many model invocations, % of model invocation calls, ec2 instances in alarm states, and any other errors. Do the following:
225+
1. Analyze the logs carefully and generate charts with in depth metrics, create bar charts, pie charts, mermaid diagrams for that for better understanding.
226+
2. Create a report I can share with my team.
227+
3. Create JIRA tickets for any potential errors."""
228+
)
229+
except Exception as e:
230+
print(f"FATAL ERROR in run_cloudguard_agent: {e}")
231+
import traceback
232+
traceback.print_exc()
233+
finally:
234+
print("Cleaning up resources...")
235+
if jira_mcp_client:
236+
try:
237+
await jira_mcp_client.cleanup()
238+
print("✅ Jira client cleaned up")
239+
except Exception as e:
240+
print(f"ERROR cleaning up Jira client: {e}")
241+
242+
if monitoring_mcp_client:
243+
try:
244+
await monitoring_mcp_client.cleanup()
245+
print("✅ Monitoring client cleaned up")
246+
except Exception as e:
247+
print(f"ERROR cleaning up monitoring client: {e}")
248+
print("Done.")
249+
250+
def parse_args():
251+
"""Parse command line arguments"""
252+
parser = argparse.ArgumentParser(description='AWS CloudGuard MCP Inline Agent')
253+
254+
parser.add_argument('--input', type=str,
255+
help='Initial input text for the agent')
256+
257+
return parser.parse_args()
258+
259+
if __name__ == "__main__":
260+
args = parse_args()
261+
asyncio.run(run_cloudguard_agent(args.input))

0 commit comments

Comments
 (0)