Skip to content

Commit 8be7a8e

Browse files
authored
feat: Add new SysQL Query tool
1 parent 4e9f051 commit 8be7a8e

File tree

5 files changed

+366
-262
lines changed

5 files changed

+366
-262
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ Get up and running with the Sysdig MCP Server quickly using our pre-built Docker
101101
| Tool Name | Description | Sample Prompt |
102102
|-----------|-------------|----------------|
103103
| `generate_and_run_sysql` | Generate and run a SysQL query using natural language | "List top 10 pods by memory usage in the last hour" |
104+
| `run_sysql` | Execute a pre-written SysQL query directly (use only when user provides explicit query) | "Run this query: MATCH CloudResource WHERE type = 'aws_s3_bucket' LIMIT 10" |
104105

105106
</details>
106107

@@ -184,7 +185,7 @@ To use the MCP server tools, your API token needs specific permissions in Sysdig
184185
|--------------|---------------------|---------------------------|
185186
| **CLI Scanner** | `secure.vm.cli-scanner.exec` | Vulnerability Management: "CLI Execution" (EXEC) |
186187
| **Threat Detection (Events Feed)** | `policy-events.read` | Threats: "Policy Events" (Read) |
187-
| **SysQL** | `sage.exec`, `risks.read` | Sage: "Use Sage chat" (EXEC) + Risks: "Access to risk feature" (Read) |
188+
| **SysQL** | `sage.exec`, `risks.read` | SysQL: "AI Query Generation" (EXEC) + Risks: "Access to risk feature" (Read) |
188189
189190
**Additional Permissions:**
190191

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "sysdig-mcp-server"
3-
version = "0.3.1"
3+
version = "0.4.0"
44
description = "Sysdig MCP Server"
55
readme = "README.md"
66
requires-python = ">=3.12"

tools/sysql/tool.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,54 @@ async def tool_generate_and_run_sysql(self, ctx: Context, question: str) -> dict
8181
except ToolError as e:
8282
self.log.error(f"Failed to execute SysQL query: {e}")
8383
raise e
84+
85+
86+
async def tool_run_sysql(self, ctx: Context, sysql_query: str) -> dict:
87+
"""
88+
Executes a pre-written SysQL query directly against the Sysdig API and returns the results.
89+
90+
Use this tool ONLY when the user provides an explicit SysQL query. Do not improvise or
91+
generate queries. For natural language questions, use generate_and_run_sysql instead.
92+
93+
Args:
94+
ctx (Context): A context object containing configuration information.
95+
sysql_query (str): A valid SysQL query string to execute directly.
96+
97+
Returns:
98+
dict: A dictionary containing the results of the SysQL query execution with metadata.
99+
100+
Raises:
101+
ToolError: If the SysQL query execution fails or if the query is invalid.
102+
103+
Examples:
104+
# tool_run_sysql(sysql_query="MATCH Vulnerability WHERE severity = 'Critical' LIMIT 10")
105+
# tool_run_sysql(sysql_query="MATCH KubeWorkload AS k AFFECTED_BY Vulnerability WHERE k.namespace = 'production'")
106+
# tool_run_sysql(sysql_query="MATCH CloudResource WHERE type = 'aws_s3_bucket' RETURN *")
107+
# tool_run_sysql(sysql_query="MATCH Vulnerability AS v WHERE v.name = 'CVE-2024-1234' RETURN v")
108+
"""
109+
# Start timer
110+
start_time = time.time()
111+
# Get API instance
112+
api_instances: dict = ctx.get_state("api_instances")
113+
legacy_api_client: LegacySysdigApi = api_instances.get("legacy_sysdig_api")
114+
if not legacy_api_client:
115+
self.log.error("LegacySysdigApi instance not found")
116+
raise ToolError("LegacySysdigApi instance not found")
117+
118+
if not sysql_query:
119+
raise ToolError("No SysQL query provided. Please provide a valid SysQL query string.")
120+
121+
try:
122+
self.log.debug(f"Executing SysQL query: {sysql_query}")
123+
results = legacy_api_client.execute_sysql_query(sysql_query)
124+
execution_time = (time.time() - start_time) * 1000
125+
self.log.debug(f"SysQL query executed in {execution_time} ms")
126+
response = create_standard_response(
127+
results=results, execution_time_ms=execution_time,
128+
metadata_kwargs={"sysql_query": sysql_query}
129+
)
130+
131+
return response
132+
except ToolError as e:
133+
self.log.error(f"Failed to execute SysQL query: {e}")
134+
raise e

utils/mcp_server.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,18 @@ def add_tools(self) -> None:
165165
),
166166
tags={"sysql", "sysdig_secure"},
167167
)
168+
self.mcp_instance.tool(
169+
name_or_fn=sysdig_sysql_tools.tool_run_sysql,
170+
name="run_sysql",
171+
description=(
172+
"""
173+
Execute a pre-written SysQL query directly against the Sysdig API.
174+
Use ONLY when the user provides an explicit SysQL query string.
175+
For natural language questions, use generate_and_run_sysql instead.
176+
"""
177+
),
178+
tags={"sysql", "sysdig_secure"},
179+
)
168180

169181
if self.app_config.transport() == "stdio":
170182
# Register the tools for STDIO transport

0 commit comments

Comments
 (0)