Skip to content

Commit 2e60d20

Browse files
committed
Sysdig MCP closed availability
0 parents  commit 2e60d20

31 files changed

+2706
-0
lines changed

.dockerignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
examples/
3+
.venv/
4+
.github/
5+
.idea/
6+
.vscode/
7+
.env
8+
.gitignore
9+
CONTRIBUTING.md
10+
flake8.ini
11+
flake.nix
12+
LICENSE.*
13+
README.md
14+
__pycache__/*
15+
lib/
16+
.python-version
17+
*.yaml

.gitignore

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
!build/sysdig_client-1.0.0.tar.gz
14+
develop-eggs/
15+
dist/
16+
downloads/
17+
eggs/
18+
.eggs/
19+
lib/
20+
lib64/
21+
parts/
22+
sdist/
23+
var/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
.env
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*,cover
48+
.hypothesis/
49+
venv/
50+
.venv/
51+
.python-version
52+
.pytest_cache
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
61+
# Sphinx documentation
62+
docs/_build/
63+
64+
# PyBuilder
65+
target/
66+
67+
#Ipython Notebook
68+
.ipynb_checkpoints
69+
70+
# VSCode
71+
.vscode/

AUTHORS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
If you are running a pair programming or mob programming session, add a
2+
line to the end of your commit message to honor, credit and thank your
3+
partners correctly in GitHub.
4+
5+
Use this file to speedup the procedure, copying and pasting directly the adresses:
6+
7+
Co-authored-by: Alejandro Magallón Soler <alejandro.magallon@sysdig.com>
8+
Co-authored-by: Sebastian Zumbado Herrera <sebastian.zumbado@sysdig.com>

Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
2+
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
3+
4+
# Disable Python downloads, because we want to use the system interpreter
5+
# across both images. If using a managed Python version, it needs to be
6+
# copied from the build image into the final image; see `standalone.Dockerfile`
7+
# for an example.
8+
9+
WORKDIR /app
10+
COPY . /app
11+
RUN --mount=type=cache,target=/root/.cache/uv \
12+
--mount=type=bind,source=uv.lock,target=uv.lock \
13+
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
14+
uv sync --locked --no-install-project --no-editable
15+
RUN --mount=type=cache,target=/root/.cache/uv \
16+
uv sync --locked --no-editable
17+
18+
# Dinal image without uv
19+
FROM python:3.12-slim
20+
# It is important to use the image that matches the builder, as the path to the
21+
# Python executable must be the same
22+
23+
# Copy the application from the builder
24+
COPY --from=builder --chown=app:app /app /app
25+
26+
WORKDIR /app
27+
28+
# Place executables in the environment at the front of the path
29+
ENV PATH="/app/.venv/bin:$PATH"
30+
31+
ENTRYPOINT ["/bin/sh", "entrypoint.sh"]

LICENSE.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Copyright (c) 2025, Sysdig. All Rights Reserved.

README.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# MCP Server
2+
3+
## Description
4+
5+
This is an implementation of an [MCP (Model Context Protocol) Server](https://modelcontextprotocol.io/quickstart/server) to allow different LLMs to query information from Sysdig Secure platform. **It is still in early development and not yet ready for production use.** New endpoints and functionalities will be added over time. The goal is to provide a simple and easy-to-use interface for querying information from Sysdig Secure platform using LLMs.
6+
7+
## Available Tools
8+
9+
<details>
10+
<summary><strong>Events Feed</strong></summary>
11+
12+
| Tool Name | Description | Sample Prompt |
13+
|-----------|-------------|----------------|
14+
| `get_event_info` | Retrieve detailed information for a specific security event by its ID | "Get full details for event ID 123abc" |
15+
| `list_runtime_events` | List runtime security events with optional filters | "Show me high severity events from the last 2 hours in cluster1" |
16+
| `get_event_process_tree` | Retrieve the process tree for a specific event (if available) | "Get the process tree for event ID abc123" |
17+
18+
</details>
19+
20+
<details>
21+
<summary><strong>Inventory</strong></summary>
22+
23+
| Tool Name | Description | Sample Prompt |
24+
|-----------|-------------|----------------|
25+
| `list_resources` | List inventory resources using filters (e.g., platform or category) | "List all exposed IAM resources in AWS" |
26+
| `get_resource` | Get detailed information about an inventory resource by its hash | "Get inventory details for hash abc123" |
27+
28+
</details>
29+
30+
<details>
31+
<summary><strong>Vulnerability Management</strong></summary>
32+
33+
| Tool Name | Description | Sample Prompt |
34+
|-----------|-------------|----------------|
35+
| `list_runtime_vulnerabilities` | List runtime vulnerability scan results with filtering | "List running vulnerabilities in cluster1 sorted by severity" |
36+
| `list_accepted_risks` | List all accepted vulnerability risks | "Show me all accepted risks related to nginx containers" |
37+
| `get_accepted_risk` | Retrieve a specific accepted risk by ID | "Get details for accepted risk id abc123" |
38+
| `list_registry_scan_results` | List scan results for container registries | "List failed scans from harbor registry" |
39+
| `get_vulnerability_policy_by_id` | Get a specific vulnerability policy by ID | "Show policy ID 42" |
40+
| `list_vulnerability_policies` | List all vulnerability policies | "List all vulnerability policies for pipeline stage" |
41+
| `list_pipeline_scan_results` | List CI pipeline scan results | "Show me pipeline scans that failed for ubuntu images" |
42+
| `get_scan_result` | Retrieve detailed scan results by scan ID | "Get results for scan ID 456def" |
43+
44+
</details>
45+
46+
<details>
47+
<summary><strong>Sysdig Sage</strong></summary>
48+
49+
| Tool Name | Description | Sample Prompt |
50+
|-----------|-------------|----------------|
51+
| `sysdig_sysql_sage_query` | Generate and run a SysQL query using natural language | "List top 10 pods by memory usage in the last hour" |
52+
53+
</details>
54+
55+
## Requirements
56+
57+
### UV Setup
58+
59+
You can use [uv](https://github.com/astral-sh/uv) as a drop-in replacement for pip to create the virtual environment and install dependencies.
60+
61+
If you don't have `uv` installed, you can install it via (Linux and MacOS users):
62+
63+
```bash
64+
curl -Ls https://astral.sh/uv/install.sh | sh
65+
```
66+
67+
To set up the environment:
68+
69+
```bash
70+
uv venv
71+
source .venv/bin/activate
72+
```
73+
74+
This will create a virtual environment using `uv` and install the required dependencies.
75+
76+
### Sysdig SDK
77+
78+
You will need the Sysdig-SDK. You can find it in the `build` directory as a `.tar.gz` file that will be used by UV to install the package.
79+
80+
## Configuration
81+
82+
The application can be configured via the `app_config.yaml` file and environment variables.
83+
84+
### `app_config.yaml`
85+
86+
This file contains the main configuration for the application, including:
87+
88+
- **app**: Host, port, and log level for the MCP server.
89+
- **sysdig**: The Sysdig Secure host to connect to.
90+
- **mcp**: Transport protocol (stdio, sse, streamable-http), URL, host, and port for the MCP server.
91+
92+
### Environment Variables
93+
94+
The following environment variables are required for configuring the Sysdig SDK:
95+
96+
- `SYSDIG_HOST`: The URL of your Sysdig Secure instance (e.g., `https://secure.sysdig.com`).
97+
- `SYSDIG_SECURE_API_TOKEN`: Your Sysdig Secure API token.
98+
99+
You can find your API token in the Sysdig Secure UI under **Settings > Sysdig Secure API**. Make sure to copy the token as it will not be shown again.
100+
101+
![API_TOKEN_CONFIG](./docs/assets/settings-config-token.png)
102+
![API_TOKEN_SETTINGS](./docs/assets/api-token-copy.png)
103+
104+
You can set these variables in your shell or in a `.env` file.
105+
106+
You can also use `MCP_TRANSPORT` to override the transport protocol set in `app_config.yaml`.
107+
108+
## Running the Server
109+
110+
You can run the MCP server using either Docker or `uv`.
111+
112+
### Docker
113+
114+
To run the server using Docker, you first need to build the image:
115+
116+
```bash
117+
docker build -t sysdig-mcp-server .
118+
```
119+
120+
Then, you can run the container, making sure to pass the required environment variables:
121+
122+
```bash
123+
docker run -e SYSDIG_HOST=<your_sysdig_host> -e SYSDIG_SECURE_API_TOKEN=<your_sysdig_secure_api_token> -p 8080:8080 sysdig-mcp-server
124+
```
125+
126+
By default, the server will run using the `stdio` transport. To use the `streamable-http` or `sse` transports, set the `MCP_TRANSPORT` environment variable to `streamable-http` or `sse`:
127+
128+
```bash
129+
docker run -e MCP_TRANSPORT=streamable-http -e SYSDIG_HOST=<your_sysdig_host> -e SYSDIG_SECURE_API_TOKEN=<your_sysdig_secure_api_token> -p 8080:8080 sysdig-mcp-server
130+
```
131+
132+
### UV
133+
134+
To run the server using `uv`, first set up the environment as described in the [UV Setup](#uv-setup) section. Then, run the `main.py` script:
135+
136+
```bash
137+
uv run main.py
138+
```
139+
140+
By default, the server will run using the `stdio` transport. To use the `streamable-http` or `sse` transports, set the `MCP_TRANSPORT` environment variable to `streamable-http` or `sse`:
141+
142+
```bash
143+
MCP_TRANSPORT=streamable-http uv run main.py
144+
```
145+
146+
## Client Configuration
147+
148+
To use the MCP server with a client like Claude or Cursor, you need to provide the server's URL and authentication details.
149+
150+
### Authentication
151+
152+
When using the `sse` or `streamable-http` transport, the server requires a Bearer token for authentication. The token is passed in the `Authorization` header of the HTTP request.
153+
154+
Additionally, you can specify the Sysdig Secure host by providing the `X-Sysdig-Host` header. If this header is not present, the server will use the value from `app_config.yaml`.
155+
156+
Example headers:
157+
158+
```
159+
Authorization: Bearer <your_sysdig_secure_api_token>
160+
X-Sysdig-Host: <your_sysdig_host>
161+
```
162+
163+
### URL
164+
165+
If you are running the server with the `sse` or `streamable-http` transport, the URL will be `http://<host>:<port>/sysdig-mcp-server/mcp`, where `<host>` and `<port>` are the values configured in `app_config.yaml` or the Docker run command.
166+
167+
For example, if you are running the server locally on port 8080, the URL will be `http://localhost:8080/sysdig-mcp-server/mcp`.
168+
169+
### Claude Desktop App
170+
171+
For the Claude Desktop app, you can manually configure the MCP server by editing the `claude_desktop_config.json` file. This is useful for running the server locally with the `stdio` transport.
172+
173+
1. **Open the configuration file**:
174+
- Go to **Settings > Developer** in the Claude Desktop app.
175+
- Click on **Edit Config** to open the `claude_desktop_config.json` file.
176+
177+
2. **Add the MCP server configuration**:
178+
- Add the following JSON object to the `mcpServers` section of the file.
179+
180+
```json
181+
{
182+
"mcpServers": {
183+
"sysdig-mcp-server": {
184+
"command": "uv",
185+
"args": [
186+
"--directory",
187+
"<path_to_your_sysdig_mcp_server_directory>",
188+
"run",
189+
"main.py"
190+
],
191+
"env": {
192+
"SYSDIG_HOST": "<your_sysdig_host>",
193+
"SYSDIG_SECURE_API_TOKEN": "<your_sysdig_secure_api_token>",
194+
"MCP_TRANSPORT": "stdio"
195+
}
196+
}
197+
}
198+
}
199+
```
200+
201+
3. **Replace the placeholders**:
202+
- Replace `<your_sysdig_host>` with your Sysdig Secure host URL.
203+
- Replace `<your_sysdig_secure_api_token>` with your Sysdig Secure API token.
204+
- Replace `<path_to_your_sysdig_mcp_server_directory>` with the absolute path to the `sysdig-mcp-server` directory.
205+
206+
4. **Save the file** and restart the Claude Desktop app for the changes to take effect.

app_config.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
app:
3+
host: "localhost"
4+
port: 8080
5+
log_level: "ERROR"
6+
language: "en"
7+
8+
sysdig:
9+
host: "https://secure.sysdig.com"
10+
11+
mcp:
12+
transport: stdio
13+
url: "http://localhost:8080/sysdig-mcp-server/mcp"
14+
host: "localhost"
15+
port: 8080

docs/assets/api-token-copy.png

200 KB
Loading

docs/assets/settings-config-token.png

519 KB
Loading

entrypoint.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
3+
python3 main.py

image.png

485 KB
Loading

main.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'''
2+
Main entry point for the MCP server application.
3+
'''
4+
import os, asyncio
5+
from dotenv import load_dotenv
6+
# Application config loader
7+
from utils.app_config import get_app_config
8+
# Register all tools so they attach to the MCP server
9+
from utils.mcp_server import run_stdio, run_http
10+
11+
# Load environment variables from .env
12+
load_dotenv()
13+
14+
app_config = get_app_config()
15+
16+
if __name__ == "__main__":
17+
# Choose transport: "stdio" or "sse" (HTTP/SSE)
18+
transport = os.environ.get("MCP_TRANSPORT", app_config["mcp"]["transport"]).lower()
19+
20+
if transport == "stdio":
21+
# Run MCP server over STDIO (local)
22+
asyncio.run(run_stdio())
23+
else:
24+
# Run MCP server over streamable HTTP by default
25+
run_http()

0 commit comments

Comments
 (0)