Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions server/secops-soar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ To use this MCP server with Claude Desktop:
],
"env": {
"SOAR_URL": "${SOAR_URL}",
"SOAR_APP_KEY": "${SOAR_APP_KEY}"
"SOAR_APP_KEY": "${SOAR_APP_KEY}",
"SOAR_PROXY": "${SOAR_PROXY}"
},
"disabled": false,
"autoApprove": []
Expand All @@ -92,7 +93,8 @@ To have the MCP server provide tools for specific marketplace integrations, use
],
"env": {
"SOAR_URL": "${SOAR_URL}",
"SOAR_APP_KEY": "${SOAR_APP_KEY}"
"SOAR_APP_KEY": "${SOAR_APP_KEY}",
"SOAR_PROXY": "${SOAR_PROXY}"
},
"disabled": false,
"autoApprove": []
Expand All @@ -109,13 +111,15 @@ Set up these environment variables in your system:
```bash
export SOAR_URL="your-soar-url"
export SOAR_APP_KEY="your-soar-app-key"
export SOAR_PROXY="http://proxy:8080"
export SOAR_INTEGRATIONS="ServiceNow,CSV,Siemplify"
```

**For Windows PowerShell:**
```powershell
$Env:SOAR_URL = "your-soar-url"
$Env:SOAR_APP_KEY = "your-soar-app-key"
$Env:SOAR_PROXY = "http://proxy:8080"
$Env:SOAR_INTEGRATIONS = "ServiceNow,CSV,Siemplify"
```

Expand Down
5 changes: 4 additions & 1 deletion server/secops-soar/secops_soar_mcp/bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import dotenv
from logger_utils import get_logger

from secops_soar_mcp.http_client import HttpClient
from secops_soar_mcp.utils import consts

Expand All @@ -42,7 +43,9 @@ async def bind():
"""Binds global variables."""
global http_client, valid_scopes
http_client = HttpClient(
os.getenv(consts.ENV_SOAR_URL), os.getenv(consts.ENV_SOAR_APP_KEY)
os.getenv(consts.ENV_SOAR_URL),
os.getenv(consts.ENV_SOAR_APP_KEY),
os.getenv(consts.ENV_SOAR_PROXY),
)
valid_scopes = await _get_valid_scopes()

Expand Down
56 changes: 45 additions & 11 deletions server/secops-soar/secops_soar_mcp/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""HTTP client for making requests to the SecOps SOAR API."""

import json
from typing import Any, Dict
from typing import Any, Dict, Optional

import aiohttp
from logger_utils import get_logger
Expand All @@ -25,9 +25,10 @@
class HttpClient:
"""HTTP client for making requests to the SecOps SOAR API."""

def __init__(self, base_url: str, app_key: str):
def __init__(self, base_url: str, app_key: str, proxy: Optional[str] = None):
self.base_url = base_url
self.app_key = app_key
self.proxy = proxy
self._session = None

def _get_session(self) -> aiohttp.ClientSession:
Expand Down Expand Up @@ -56,16 +57,21 @@ async def get(
The response as a JSON object, or None if an error occurred.
"""
headers = await self._get_headers()
request_kwargs = {"params": params, "headers": headers}
if self.proxy:
request_kwargs["proxy"] = self.proxy
try:
async with self._get_session().get(
self.base_url + endpoint, params=params, headers=headers
self.base_url + endpoint, **request_kwargs
) as response:
response.raise_for_status() # Raise an exception for 4xx/5xx responses
return await response.json()
except aiohttp.ClientResponseError as e:
logger.debug("HTTP error occurred: %s", e)
logger.error("HTTP error occurred for endpoint %s: %s", endpoint, e)
return {"error": f"HTTP error: {e}"}
except Exception as e:
logger.debug("An error occurred: %s", e)
logger.error("An error occurred for endpoint %s: %s", endpoint, e)
return {"error": f"Unexpected error: {e}"}
return None

async def post(
Expand All @@ -85,18 +91,41 @@ async def post(
The response as a JSON object, or None if an error occurred.
"""
headers = await self._get_headers()
request_kwargs = {"json": req, "params": params, "headers": headers}
if self.proxy:
request_kwargs["proxy"] = self.proxy
try:
async with self._get_session().post(
self.base_url + endpoint, json=req, params=params, headers=headers
self.base_url + endpoint, **request_kwargs
) as response:
if response.status == 500:
try:
error_data = await response.json()
logger.error(
"Server error (500) for endpoint %s: %s",
endpoint,
error_data,
)
return {"error": f"Server error (500): {error_data}"}
except Exception:
error_text = await response.text()
logger.error(
"Server error (500) for endpoint %s: %s",
endpoint,
error_text,
)
return {"error": f"Server error (500): {error_text}"}

response.raise_for_status()
data = await response.content.read()
decoded_data = data.decode("utf-8")
return json.loads(decoded_data)
except aiohttp.ClientResponseError as e:
logger.debug("HTTP error occurred: %s", e)
logger.error("HTTP error occurred for endpoint %s: %s", endpoint, e)
return {"error": f"HTTP error: {e}"}
except Exception as e:
logger.debug("An error occurred: %s", e)
logger.error("An error occurred for endpoint %s: %s", endpoint, e)
return {"error": f"Unexpected error: {e}"}
return None

async def patch(
Expand All @@ -116,16 +145,21 @@ async def patch(
The response as a JSON object, or None if an error occurred.
"""
headers = await self._get_headers()
request_kwargs = {"json": req, "params": params, "headers": headers}
if self.proxy:
request_kwargs["proxy"] = self.proxy
try:
async with self._get_session().patch(
self.base_url + endpoint, json=req, params=params, headers=headers
self.base_url + endpoint, **request_kwargs
) as response:
response.raise_for_status()
return await response.json()
except aiohttp.ClientResponseError as e:
logger.debug("HTTP error occurred: %s", e)
logger.error("HTTP error occurred for endpoint %s: %s", endpoint, e)
return {"error": f"HTTP error: {e}"}
except Exception as e:
logger.debug("An error occurred: %s", e)
logger.error("An error occurred for endpoint %s: %s", endpoint, e)
return {"error": f"Unexpected error: {e}"}
return None

async def close(self):
Expand Down
1 change: 1 addition & 0 deletions server/secops-soar/secops_soar_mcp/utils/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

ENV_SOAR_URL = "SOAR_URL"
ENV_SOAR_APP_KEY = "SOAR_APP_KEY"
ENV_SOAR_PROXY = "SOAR_PROXY"


class Endpoints:
Expand Down