Opensearch Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Opensearch Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A Model Context Protocol (MCP) server built with FastMCP for retrieving error stack traces by transaction ID (TID) from OpenSearch logs.
git clone <repository-url>
cd opensearch-mcppip install -r requirements.txtOr using uv:
uv pip install -r requirements.txtcp .env.example .env
# Edit .env with your OpenSearch connection settingsPrerequisites: You need your own OpenSearch instance running and accessible. Configure the connection details in the .env file.
cp .env.example .env
# Edit .env and set OPENSEARCH_HOST and OPENSEARCH_PORT to your OpenSearch instancedocker-compose upThis will start:
http://localhost:48081/mcp)The MCP server will connect to your OpenSearch instance using the configuration from .env.
To run in detached mode:
docker-compose up -dcp .env.example .env
# Edit .env and configure OPENSEARCH_HOST and OPENSEARCH_PORT to your OpenSearch instancepython server.pyThe server will start on http://localhost:48081/mcp.
docker build -t opensearch-mcp .docker run --rm -p 48081:48081 \
-e OPENSEARCH_HOST=your-opensearch-host \
-e OPENSEARCH_PORT=9200 \
opensearch-mcpOr use an env file:
docker run --rm -p 48081:48081 --env-file .env opensearch-mcpThe MCP server will be available at http://localhost:48081/mcp.
Note:
your-opensearch-host with your actual OpenSearch hostname or IPhost.docker.internal (macOS/Windows) or your host IP (Linux) if OpenSearch is running on the host machineThe MCP server reads connection settings from environment variables:
| Variable | Default | Description |
|---|---|---|
OPENSEARCH_HOST | localhost | OpenSearch host |
OPENSEARCH_PORT | 9200 | OpenSearch port |
OPENSEARCH_USE_SSL | false | Enable SSL/TLS |
OPENSEARCH_VERIFY_CERTS | false | Verify SSL certificates |
OPENSEARCH_USERNAME | - | Username for authentication (optional) |
OPENSEARCH_PASSWORD | - | Password for authentication (optional) |
When using Docker Compose, these variables are automatically available from the container environment.
stack_trace_tidRetrieve full error stack trace by transaction ID (TID).
Parameters:
tid (string, required): Transaction ID to search forindex_pattern (string, optional): Index pattern to search (default: servicelogs-*)repo_name (string, optional): Filter by repository/application name (maps to application_name field)Example:
{
"tid": "e1020584c0a74074a930c4e90e953912.139.17702793574644017",
"repo_name": "xxx"
}Returns: Formatted text with one log entry per line. Each line follows the format:
timestamp - level - message - application_name - projectIf a separate stack_trace field exists in the log document, the format is:
timestamp - level - message - stack_trace - application_name - projectNote: Log entries are sorted chronologically by @timestamp in ascending order. Newlines in messages and stack traces are normalized to | (pipe characters) for single-line format.
Example Output:
2026-02-05T08:15:57.566Z - INFO - channel GOPAY got phone A0:1ec614bbcb328b7c66436a318d7b77e0 from token - xxx - xxx
2026-02-05T08:15:57.570Z - INFO - register user for A0:44b351780fec875b97ad01d9bb946f3e , system : SYSTEM_TYPE_ATOME, channel: GOPAY - user-service-provider - pintar-user
2026-02-05T08:15:58.263Z - ERROR - POST http://:8080/user/info -d [{"module":"RESIDENTIAL_INFO","module":"RESIDENTIAL_INFO",...}] ***RESPONSE*** 400 {"timestamp":1770279358262,"status":400,"error":"Bad Request","path":"/user/info"} - xxx - xxx
2026-02-05T08:15:58.264Z - ERROR - [Gopay Linking] Failed to save user info for userId : [400 ] during [POST] to [http://:8080/user/info] [PintarUserInfoFeignClient#saveUserInfo(List)]: [{"timestamp":1770279358262,"status":400,"error":"Bad Request","path":"/user/info"}] - feign.FeignException$BadRequest: [400 ] during [POST] to [http://:8080/user/info] [PintarUserInfoFeignClient#saveUserInfo(List)]: [{"timestamp":1770279358262,"status":400,"error":"Bad Request","path":"/user/info"}] | at feign.FeignException.clientErrorStatus(FeignException.java:243) | at feign.FeignException.errorStatus(FeignException.java:223) | at feign.FeignException.errorStatus(FeignException.java:213) | ... - xxx - xxx
2026-02-05T08:15:58.267Z - INFO - [GopayServiceImpl] linking account failed for userId: , error: INVALID_KYC - xxx - xxxNote: Log entries are sorted by timestamp in ascending order. Stack traces (when present) are included as part of the message field, with stack frames separated by | (pipe characters).
The MCP server uses streamableHttp transport on port 48081. This enables HTTP-based communication instead of stdio, making it easier to deploy and scale.
Important: Ensure your OpenSearch instance is running and accessible before starting the MCP server.
#### Option 1: Using Docker Compose (Recommended)
.env:cp .env.example .env
# Edit .env with your OpenSearch host and portdocker-compose upThe MCP server will be available at http://localhost:48081/mcp.
#### Option 2: Running Locally
cp .env.example .env
# Edit .env with your OpenSearch host and portpython server.pyThe server will start on http://localhost:48081/mcp.
#### Option 3: Using Docker Run
Build the image:
docker build -t opensearch-mcp .Run the container with your OpenSearch connection:
docker run --rm -p 48081:48081 \
-e OPENSEARCH_HOST=your-opensearch-host \
-e OPENSEARCH_PORT=9200 \
opensearch-mcpOr use an env file:
docker run --rm -p 48081:48081 --env-file .env opensearch-mcp#### Cursor IDE
Add to your Cursor MCP settings (mcp.json):
{
"mcpServers": {
"opensearch": {
"url": "http://localhost:48081/mcp"
}
}
}#### Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"opensearch": {
"url": "http://localhost:48081/mcp"
}
}
}#### Remote Access
If the MCP server is running on a remote machine, use the remote URL:
{
"mcpServers": {
"opensearch": {
"url": "http://your-server-ip:48081/mcp"
}
}
}The MCP server port and host can be configured via environment variables:
MCP_PORT: Port for the HTTP server (default: 48081)MCP_HOST: Host to bind to (default: 0.0.0.0)Example:
MCP_PORT=8080 MCP_HOST=127.0.0.1 python server.pyhttp://localhost:48081/mcpnetwork_mode: host to allow the container to access VPN resources through your host's networkNote: With network_mode: host, the container uses your host's network directly, so:
opensearch-mcp/
├── src/
│ └── opensearch_mcp/
│ ├── __init__.py
│ ├── server.py # FastMCP server with tool definitions
│ └── opensearch_client.py # OpenSearch client wrapper
├── docker-compose.yml # Docker Compose setup (OpenSearch + MCP server)
├── Dockerfile # MCP server Docker image
├── .dockerignore # Docker ignore file
├── .env.example # Example environment variables
├── mcp.json.example # Example MCP client configuration
├── requirements.txt # Python dependencies
├── pyproject.toml # Python project configuration
└── README.md # This file# Ensure your OpenSearch instance is running and accessible
# Start MCP server with Docker Compose
docker-compose up
# Or run MCP server locally
python server.pyThe docker-compose.yml includes only the MCP server service:
.env file for configuration)The MCP server service:
.env file.env/mcp pathNote: You need to provide your own OpenSearch instance. Configure the connection details in the .env file.
The MCP server expects log documents with the following structure:
{
"@timestamp": "2024-01-01T10:00:00Z",
"level": "ERROR",
"msg": "Error occurred...",
"application_name": "xxx",
"project": "xxx",
"stack_trace": "feign.FeignException$BadRequest: [...] | at ...",
"TID": "e1020584c0a74074a930c4e90e953912.139.17702793574644017"
}Key fields:
@timestamp: Log timestamp (ISO 8601 format)level: Log level (INFO, WARN, ERROR, etc.)msg: Log message contentapplication_name: Application/service name (used for filtering via repo_name parameter)project: Project/repository namestack_trace: Stack trace content (optional, formatted as pipe-separated lines)TID: Transaction ID field (searched using phrase matching across all fields)If you see connection errors:
curl http://your-opensearch-host:9200/_cluster/health.env are set correctly (OPENSEARCH_HOST and OPENSEARCH_PORT)servicelogs-*)repo_name filter, verify that application_name field exists and matches the filter valueIf using SSL:
OPENSEARCH_USE_SSL=trueOPENSEARCH_VERIFY_CERTS appropriatelyMIT
Contributions are welcome! Please feel free to submit a Pull Request.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.