VictoriaLogs MCP Server
The implementation of Model Context Protocol (MCP) server for VictoriaLogs.
This provides access to your VictoriaLogs instance and seamless integration with VictoriaLogs APIs and documentation. It can give you a comprehensive interface for logs, observability, and debugging tasks related to your VictoriaLogs instances, enable advanced automation and interaction capabilities for engineers and tools.
Features
This MCP server allows you to use almost all read-only APIs of VictoriaLogs, i.e. all functions available in Web UI:
- Querying logs and exploring logs data
- Showing parameters of your VictoriaLogs instance
- Listing available streams, fields, field values
- Query statistics for the logs as metrics
In addition, the MCP server contains embedded up-to-date documentation and is able to search it without online access.
More details about the exact available tools and prompts can be found in the Usage section.
You can combine functionality of tools, docs search in your prompts and invent great usage scenarios for your VictoriaLogs instance. And please note the fact that the quality of the MCP Server and its responses depends very much on the capabilities of your client and the quality of the model you are using.
You can also combine the MCP server with other observability or doc search related MCP Servers and get even more powerful results.
Try without installation
There is a publicly available instance of the VictoriaMetrics MCP Server that you can use to test the features without installing it:
https://play-vmlogs-mcp.victoriametrics.com/mcp
Attention! This URL is not supposed to be opened in a browser, it is intended to be used in MCP clients.
It's available in Streamable HTTP Mode mode and configured to work with Public VictoriaLogs Playground.
Here is example of configuration for Claude Desktop:
Requirements
- VictoriaLogs instance: (single-node or cluster)
- Go 1.24 or higher (if you want to build from source)
Installation
Go
go install github.com/VictoriaMetrics-Community/mcp-victorialogs/cmd/mcp-victorialogs@latest
Binaries
Just download the latest release from Releases page and put it to your PATH.
Example for Linux x86_64 (note that other architectures and platforms are also available):
latest=$(curl -s https://api.github.com/repos/VictoriaMetrics-Community/mcp-victorialogs/releases/latest | grep 'tag_name' | cut -d\" -f4)
wget https://github.com/VictoriaMetrics-Community/mcp-victorialogs/releases/download/$latest/mcp-victorialogs_Linux_x86_64.tar.gz
tar axvf mcp-victorialogs_Linux_x86_64.tar.gz
Docker
You can run VictoriaLogs MCP Server using Docker.
This is the easiest way to get started without needing to install Go or build from source.
docker run -d --name mcp-victorialogs \
-e VL_INSTANCE_ENTRYPOINT=https://play-vmlogs.victoriametrics.com \
-e MCP_SERVER_MODE=http \
-e MCP_LISTEN_ADDR=:8081 \
-p 8081:8081 \
ghcr.io/victoriametrics-community/mcp-victorialogs
You should replace environment variables with your own parameters.
Note that the MCP_SERVER_MODE=http flag is used to enable Streamable HTTP mode.
More details about server modes can be found in the Configuration section.
See available docker images in github registry.
Also see Using Docker instead of binary section for more details about using Docker with MCP server with clients in stdio mode.
Source Code
For building binary from source code you can use the following approach:
- Clone repo:
bash
git clone https://github.com/VictoriaMetrics-Community/mcp-victorialogs.git
cd mcp-victorialogs
- Build binary from cloned source code:
bash
make build
# after that you can find binary mcp-victorialogs and copy this file to your PATH or run inplace
- Build image from cloned source code:
bash
docker build -t mcp-victorialogs .
# after that you can use docker image mcp-victorialogs for running or pushing
Smithery
To install VictoriaLogs MCP Server for your client automatically via Smithery, yo can use the following commands:
# Get the list of supported MCP clients
npx -y @smithery/cli list clients
#Available clients:
# claude
# cline
# windsurf
# roocode
# witsy
# enconvo
# cursor
# vscode
# vscode-insiders
# boltai
# amazon-bedrock
# Install VictoriaLogs MCP server for your client
npx -y @smithery/cli install @VictoriaMetrics-Community/mcp-victorialogs --client <YOUR-CLIENT-NAME>
# and follow the instructions
Configuration
MCP Server for VictoriaLogs is configured via environment variables:
| Variable | Description | Required | Default | Allowed values |
|---|---|---|---|---|
VL_INSTANCE_ENTRYPOINT |
URL to VictoriaLogs instance | Yes | - | - |
VL_INSTANCE_BEARER_TOKEN |
Authentication token for VictoriaLogs API | No | - | - |
VL_INSTANCE_HEADERS |
Custom HTTP headers to send with requests (comma-separated key=value pairs) | No | - | - |
VL_DEFAULT_TENANT_ID |
Default tenant ID used when tenant is not specified in requests (format: AccountID:ProjectID or AccountID) |
No | 0:0 |
- |
MCP_SERVER_MODE |
Server operation mode. See Modes for details. | No | stdio |
stdio, sse, http |
MCP_LISTEN_ADDR |
Address for SSE or HTTP server to listen on | No | localhost:8081 |
- |
MCP_DISABLED_TOOLS |
Comma-separated list of tools to disable | No | - | - |
MCP_HEARTBEAT_INTERVAL |
Defines the heartbeat interval for the streamable-http protocol. It means the MCP server will send a heartbeat to the client through the GET connection, to keep the connection alive from being closed by the network infrastructure (e.g. gateways) |
No | 30s |
- |
MCP_LOG_FORMAT |
Log output format | No | text |
text, json |
MCP_LOG_LEVEL |
Minimum log level | No | info |
debug, info, warn, error |
Modes
MCP Server supports the following modes of operation (transports):
stdio- Standard input/output mode, where the server reads commands from standard input and writes responses to standard output. This is the default mode and is suitable for local servers.sse- Server-Sent Events. Server will expose the/sseand/messageendpoints for SSE connections.http- Streamable HTTP. Server will expose the/mcpendpoint for HTTP connections.
More info about traqnsports you can find in MCP docs:
Сonfiguration examples
# For a public playground
export VL_INSTANCE_ENTRYPOINT="https://play-vmlogs.victoriametrics.com"
# Custom headers for authentication (e.g., behind a reverse proxy)
# Expected syntax is key=value separated by commas
export VL_INSTANCE_HEADERS="<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
# Server mode
export MCP_SERVER_MODE="sse"
export MCP_SSE_ADDR="0.0.0.0:8081"
export MCP_DISABLED_TOOLS="hits,facets"
Endpoints
In SSE and HTTP modes the MCP server provides the following endpoints:
| Endpoint | Description |
|---|---|
/sse + /message |
Endpoints for messages in SSE mode (for MCP clients that support SSE) |
/mcp |
HTTP endpoint for streaming messages in HTTP mode (for MCP clients that support Streamable HTTP) |
/metrics |
Metrics in Prometheus format for monitoring the MCP server |
/health/liveness |
Liveness check endpoint to ensure the server is running |
/health/readiness |
Readiness check endpoint to ensure the server is ready to accept requests |
Setup in clients
Cursor
Go to: Settings -> Cursor Settings -> MCP -> Add new global MCP server and paste the following configuration into your Cursor ~/.cursor/mcp.json file:
{
"mcpServers": {
"victorialogs": {
"command": "/path/to/mcp-victorialogs",
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
}
}
}
See Cursor MCP docs for more info.
Claude Desktop
Add this to your Claude Desktop claude_desktop_config.json file (you can find it if open Settings -> Developer -> Edit config):
{
"mcpServers": {
"victorialogs": {
"command": "/path/to/mcp-victorialogs",
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
}
}
}
See Claude Desktop MCP docs for more info.
Claude Code
Run the command:
claude mcp add victorialogs -- /path/to/mcp-victorialogs \
-e VL_INSTANCE_ENTRYPOINT=<YOUR_VL_INSTANCE> \
-e VL_INSTANCE_BEARER_TOKEN=<YOUR_VL_BEARER_TOKEN> \
-e VL_INSTANCE_HEADERS="<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
See Claude Code MCP docs for more info.
Visual Studio Code
Add this to your VS Code MCP config file:
{
"servers": {
"victorialogs": {
"type": "stdio",
"command": "/path/to/mcp-victorialogs",
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
}
}
}
See VS Code MCP docs for more info.
Zed
Add the following to your Zed config file:
"context_servers": {
"victorialogs": {
"command": {
"path": "/path/to/mcp-victorialogs",
"args": [],
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
},
"settings": {}
}
}
}
See Zed MCP docs for more info.
JetBrains IDEs
- Open
Settings->Tools->AI Assistant->Model Context Protocol (MCP). - Click
Add (+) - Select
As JSON - Put the following to the input field:
{
"mcpServers": {
"victorialogs": {
"command": "/path/to/mcp-victorialogs",
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
}
}
}
Windsurf
Add the following to your Windsurf MCP config file.
{
"mcpServers": {
"victorialogs": {
"command": "/path/to/mcp-victorialogs",
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
}
}
}
See Windsurf MCP docs for more info.
Using Docker instead of binary
You can run VictoriaLogs MCP Server using Docker instead of local binary.
You should replace run command in configuration examples above in the following way:
{
"mcpServers": {
"victorialogs": {
"command": "docker",
"args": [
"run",
"-i", "--rm",
"-e", "VL_INSTANCE_ENTRYPOINT",
"-e", "VL_INSTANCE_BEARER_TOKEN",
"-e", "VL_INSTANCE_HEADERS",
"ghcr.io/victoriametrics-community/mcp-victorialogs",
],
"env": {
"VL_INSTANCE_ENTRYPOINT": "<YOUR_VL_INSTANCE>",
"VL_INSTANCE_BEARER_TOKEN": "<YOUR_VL_BEARER_TOKEN>",
"VL_INSTANCE_HEADERS": "<HEADER>=<HEADER_VALUE>,<HEADER>=<HEADER_VALUE>"
}
}
}
}
Usage
After installing and configuring the MCP server, you can start using it with your favorite MCP client.
You can start dialog with AI assistant from the phrase:
Use MCP VictoriaLogs in the following answers
But it's not required, you can just start asking questions and the assistant will automatically use the tools and documentation to provide you with the best answers.
Toolset
MCP VictoriaLogs provides numerous tools for interacting with your VictoriaLogs instance.
Here's a list of available tools:
| Tool | Description |
|---|---|
documentation |
Search in embedded VictoriaLogs documentation |
facets |
Most frequent values per each log field |
field_names |
List of field names for the query |
field_values |
List of field values for the query |
flags |
View non-default flags of the VictoriaLogs instance |
hits |
The number of matching log entries grouped by buckets |
query |
Execute LogsQL queries |
stats_query |
Querying log stats for the given time |
stats_query_range |
Querying log stats on the given time range |
stream_field_names |
List of stream fields for the query |
stream_field_values |
List of stream field values for the query |
stream_ids |
List of stream IDs for the query |
streams |
List of streams for the query |
Prompts
The server includes pre-defined prompts for common tasks.
These are just examples at the moment, the prompt library will be added to in the future:
| Prompt | Description |
|---|---|
documentation |
Search VictoriaLogs documentation for specific topics |
Roadmap
- [ ] Support "Explain query" tool
- [ ] Support optional integration with VictoriaMetrics Cloud
- [ ] Add some extra knowledge to server in addition to current documentation tool:
- [x] VictoriaMetrics blog posts
- [ ] Github issues
- [ ] Public slack chat history
- [ ] CRD schemas
- [ ] Implement multitenant version of MCP (that will support several deployments)
- [ ] Add flags/configs validation tool
- [x] Enabling/disabling tools via configuration
Disclaimer
AI services and agents along with MCP servers like this cannot guarantee the accuracy, completeness and reliability of results. You should double check the results obtained with AI.
The quality of the MCP Server and its responses depends very much on the capabilities of your client and the quality of the model you are using.
Contributing
Contributions to the MCP VictoriaLogs project are welcome!
Please feel free to submit issues, feature requests, or pull requests.
Parameters
limit
Maximum number of results to return
query
Query for search (for example, list of keywords)
required
Parameters
end
End timestamp in RFC3339 format. For example, 2023-10-01T00:00:00Z
required
keep_const_fields
By default the facets tool doesn’t return log fields, which contain the same constant value across all the logs matching the given query. Add keep_const_fields=true arg if you need such log fields
limit
The number of values per each log field can be controlled via limit arg.
max_value_len
The facets tool ignores log fields, which contain too long values. The limit on the per-field value length can be controlled via max_value_len arg.
max_values_per_field
The facets tool ignores log fields, which contain too big number of unique values, since they can consume a lot of RAM to track. The limit on the number of unique values per each log field can be controlled via max_values_per_field arg.
query
LogsQL expression for the query of the logs data
required
start
Start timestamp in RFC3339 format. For example, 2023-10-01T00:00:00Z
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
query
LogsQL expression for the query of the logs streams
required
start
Start timestamp in RFC3339
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
field
Field name of for getting field values.
required
limit
The maximum number of returned values.
query
LogsQL expression for the query of the logs streams
required
start
Start timestamp in RFC3339
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339 format. For example, 2023-10-01T00:00:00Z
field
Additionally, any number of field=<field_name> args can be passed to /select/logsql/hits for grouping hits buckets by the mentioned <field_name> fields. The grouped fields are put inside 'fields' object of response.
fields_limit
Optional fields_limit=N query arg can be passed for limiting the number of unique 'fields' groups to return to N. If more than N unique 'fields' groups is found, then top N 'fields' groups with the maximum number of 'total' hits are returned. The remaining hits are returned in 'fields': {} group.
query
LogsQL expression for the query of the logs data
required
start
Start timestamp in RFC3339 format. For example, 2023-10-01T00:00:00Z
required
step
The step is used to group the log entries by time. For example, 60s means that the log entries counts will be grouped by 1 minute bucket. Default is 1d.
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339 format. For example, 2023-10-01T00:00:00Z
limit
The maximum number of log entries, which can be returned in the response
query
LogsQL expression for the query of the logs data
required
start
Start timestamp in RFC3339 format. For example, 2023-10-01T00:00:00Z
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
timeout
Optional query timeout. For example, timeout=5s. Query is canceled when the timeout is reached.
Parameters
query
LogsQL expression that must contain stats pipe. The calculated stats is converted into metrics with labels from by(...) clause of the | stats by(...) pipe.
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
time
Time in RFC3339. If it's missing, then it equals to the current time.
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
query
LogsQL expression that must contain stats pipe. The calculated stats is converted into metrics with labels from by(...) clause of the | stats by(...) pipe.
required
start
Start timestamp in RFC3339
required
step
Step interval for returning the stats.
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
query
LogsQL expression for the query of the logs streams
required
start
Start timestamp in RFC3339
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
field
Field name of log stream for getting field values.
required
query
LogsQL expression for the query of the logs streams
required
start
Start timestamp in RFC3339
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
query
LogsQL expression for the query of the logs streams
required
start
Start timestamp in RFC3339
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
Parameters
end
End timestamp in RFC3339. If <end> is missing, then it equals to the maximum timestamp across logs stored in VictoriaLogs.
query
LogsQL expression for the query of the logs streams
required
start
Start timestamp in RFC3339
required
tenant
Name of the tenant for which the data will be displayed (format AccountID:ProjectID)
out of 100
Security Review
Integration: VictoriaLogs
Repository: https://github.com/VictoriaMetrics-Community/mcp-victorialogs
Commit: latest
Scan Date: 2026-03-14 12:16 UTC
Security Score
80 / 100
Tier Classification
Silver
OWASP Alignment
OWASP Rubric
- Standard: OWASP Top 10 (2021) aligned review
- Core methodology: architecture context, trust boundaries, data-flow tracing, threat modeling, control verification, and evidence-backed validation
- Key characteristics considered: exploitability, impact, likelihood, attacker preconditions, and business context
OWASP Security Category Mapping
- A01 Broken Access Control: none
- A02 Cryptographic Failures: none
- A03 Injection: none
- A04 Insecure Design: none
- A05 Security Misconfiguration: none
- A06 Vulnerable and Outdated Components: none
- A07 Identification and Authentication Failures: none
- A08 Software and Data Integrity Failures: none
- A09 Security Logging and Monitoring Failures: none
- A10 Server-Side Request Forgery: none
Static Analysis Findings (Bandit)
High Severity
None
Medium Severity
None
Low Severity
None
Build Status
SKIPPED
Build step was skipped to avoid running untrusted build commands by default.
Tests
Not detected
Documentation
README: Present
Dependency file: Present
AI Security Review
OWASP Review of VictoriaLogs (mcp-victorialogs) — Security Code Review
1) OWASP Review Methodology Applied
- Architecture & Context: Reviewed main entrypoint (cmd/mcp-victorialogs/main.go), configuration loader (config/config.go), HTTP server setup, logging/middleware, hooks, resource indexing, and all tool handlers under cmd/mcp-victorialogs/tools and support utilities. Also inspected vendor MCP server and tenant parsing used by tools.
- Trust boundaries & Entry Points: Identified external entry points: MCP server (tools/prompts/resources API exposed over HTTP or SSE), HTTP endpoints (/mcp, /metrics, /health/), and environment configuration (VL_INSTANCE_ENTRYPOINT, VL_INSTANCE_BEARER_TOKEN, VL_INSTANCE_HEADERS, VL_DEFAULT_TENANT_ID, MCP_ env vars).
- Data flows: Traced user-supplied parameters (CallToolRequest arguments) into HTTP requests constructed by CreateSelectRequest/CreateAdminRequest (tools/utils.go) and into bleve search/indexing for embedded docs.
- Threat modeling: Focused on SSRF, credential exposure, insecure logging, missing request timeouts/resource exhaustion, and dependency exposure.
- Controls verification: Checked handlers for input validation, use of contextual cancellation, logging behavior, and how secrets/headers are applied to outbound requests.
- Evidence based validation: All findings include concrete file references and code excerpts. No speculative issues were reported.
2) OWASP Top 10 Category Mapping (2021)
- A01 Broken Access Control: no direct findings allowing privilege bypass in code paths examined.
- A02 Cryptographic Failures: related to secrets handling and logging (sensitive data leakage) — partial mapping.
- A03 Injection: low risk (user inputs are passed to query params but URL-encoded; no direct SQL/OS calls found).
- A04 Insecure Design: lack of admin-side hardening (no host allowlist for entrypoint, default open endpoints) -> A04.
- A05 Security Misconfiguration: open /metrics and /health endpoints, default listen address, no explicit HTTP client timeouts -> A05.
- A06 Vulnerable and Outdated Components: third-party dependencies present (go.mod) require scanning -> A06.
- A07 Identification and Authentication Failures: bearer token usage is basic; potential override via custom headers -> A07.
- A08 Software and Data Integrity Failures: vendor code included (normal for Go vendoring) — note to monitor supply-chain -> A08.
- A09 Security Logging and Monitoring Failures: logging hooks may record sensitive request and result data (including user query text and tenant ids) -> A09.
- A10 Server-Side Request Forgery (SSRF): potential design issue where the configured entrypoint could point to internal endpoints causing SSRF-like behavior if misconfigured -> A10.
3) Critical Vulnerabilities (RCE / Unsafe deserialization / Auth bypass)
- No critical RCE, unsafe deserialization, or authentication bypass vulnerabilities were found in the code paths reviewed. The project uses standard libraries and MCP server vendor code; CallToolRequest parsing is handled by vendor code which performs JSON unmarshalling but no unsafe reflection-based deserialization that leads to code execution was observed.
4) High Severity Issues
Finding 1 — Outbound requests made with no client-side timeout (Resource exhaustion / DoS risk)
- File: cmd/mcp-victorialogs/tools/utils.go
- Function: GetTextBodyForRequest (http calls originate in this function)
- Relevant lines (approx): GetTextBodyForRequest definition (tools/utils.go around lines 66-96)
- Issue: Uses http.DefaultClient.Do(req) without enforcing an explicit client timeout or connection/transport-level timeouts. Although the request carries a context, the server does not set request-level deadlines inside these handlers and the MCP request context may be long-lived. This can allow slow upstream responses to consume goroutines and file descriptors and degrade service (DoS).
- OWASP mapping: A05 Security Misconfiguration (resource management), A04 Insecure Design (no client-side safeguards).
- Severity: High
- Exploitability: Medium — requires attacker (or malfunctioning upstream) to trigger many slow calls; feasible if attacker can invoke the tool (LLM/client or remote user of MCP).
- Remediation: Use a custom http.Client with reasonable timeouts (Timeout, Transport with IdleConnTimeout, TLSHandshakeTimeout, DialContext timeouts) and/or enforce a per-request context timeout. Example: create a package-level http.Client with Timeout set or wrap request context with a maximum timeout before calling http.DefaultClient.Do. (Fix at cmd/mcp-victorialogs/tools/utils.go: replace http.DefaultClient.Do with a configured client or enforce ctx timeout before Do.)
Finding 2 — Potential SSRF / unsafe upstream endpoint configuration
- File: cmd/mcp-victorialogs/config/config.go and cmd/mcp-victorialogs/tools/utils.go
- Lines: config.InitConfig sets result.entryPointURL via url.Parse (config.go ~ line 129); getSelectURL/getRootURL (tools/utils.go ~ lines 79-86) use that URL and JoinPath to form outbound URLs.
- Issue: The entrypoint is fully admin-configurable via VL_INSTANCE_ENTRYPOINT and is used to construct outbound requests. There is no validation of allowed schemes (http/https enforced?), no host allowlist or protection preventing use of internal IPs/metadata endpoints. If the entrypoint is misconfigured to an internal resource, tool calls (invoked by clients) could be used to query internal services (SSRF). While entrypoint must be set by operator (not by untrusted client), a misconfiguration or compromised environment variable can cause SSRF.
- OWASP mapping: A10 Server-Side Request Forgery, A04 Insecure Design
- Severity: High (depending on deployment and operator control)
- Exploitability: Low–Medium (requires misconfiguration or attacker-supplied entrypoint in environment; impact high if internal endpoints are reachable)
- Remediation: Validate entrypoint URL: require https scheme and restrict hostname/IP ranges via allowlist or denylist and verify it’s not pointing at private IP ranges or cloud metadata endpoints. E.g., in config.InitConfig, after url.Parse, check u.Scheme == "https" (or allow http only for local admin-approved use) and optionally verify IP resolved does not belong to reserved ranges.
Finding 3 — Authorization header override via VL_INSTANCE_HEADERS (credential confusion)
- File: cmd/mcp-victorialogs/tools/utils.go
- Lines: CreateSelectRequest sets Authorization using cfg.BearerToken() and then iterates cfg.CustomHeaders() setting headers (tools/utils.go ~ lines 18-36 and 44-53)
- Issue: If an operator sets VL_INSTANCE_HEADERS including the Authorization header, the later loop will overwrite Authorization set from VL_INSTANCE_BEARER_TOKEN. This could be used intentionally, but may cause credential confusion or accidental leaks and unintended authentication. Additionally, custom headers are not validated.
- OWASP mapping: A07 Identification and Authentication Failures, A05 Security Misconfiguration
- Severity: High/Medium depending on deployment (High if unexpected Authorization override can cause credential misuse)
- Exploitability: Low (requires operator action to set env), Impact: Medium
- Remediation: Explicitly disallow overriding Authorization via VL_INSTANCE_HEADERS or at least document precedence. Prefer explicit configuration: if VL_INSTANCE_BEARER_TOKEN != "", either ignore an Authorization key in VL_INSTANCE_HEADERS or log a warning and prevent override. (Change in cmd/mcp-victorialogs/tools/utils.go: ensure Authorization header is set last and/or drop Authorization from custom headers.)
5) Medium Severity Issues
Finding 4 — Sensitive data may be logged (secrets and user query parameters)
- Files: cmd/mcp-victorialogs/hooks/hooks.go (NewLoggerHooks), cmd/mcp-victorialogs/logging/middleware.go
- Lines:
- hooks.go: hooks.AddBeforeAny logs toJSON(message) and hooks.AddOnSuccess logs toJSON(result). The helper toJSON calls json.Marshal on the message/result (hooks.go ~ lines 40-90)
- middleware.go logs remote request parameters (remote_addr, path) (middleware.go ~ lines 20-70)
- Issue: toJSON(message) may include user-supplied content or structured results that include sensitive data (tenant IDs, queries, possibly returned admin data). The logger does not redact secrets (e.g., queries, tenant ids). Also, logs may include entire result objects from tools, which may contain sensitive information. This can leak credentials or PII to logs or structured log sinks.
- OWASP mapping: A09 Security Logging and Monitoring Failures, A02 Cryptographic Failures (if logs are persisted without protections)
- Severity: Medium
- Exploitability: High (an attacker who calls tools with sensitive inputs can cause them to be logged) Impact: Medium
- Remediation: Implement structured logging with redaction policies for known sensitive fields (Authorization, AccountID/ProjectID, tenant, tokens, etc.). Avoid logging full request/response objects. At minimum, mask Authorization and other secret headers, or exclude request/result bodies from default logging.
Finding 5 — Metrics and health endpoints exposed without access control
- File: cmd/mcp-victorialogs/main.go
- Lines: mux.HandleFunc("/metrics", ...), /health/* handlers (main.go ~ lines 39-90)
- Issue: Exposes metrics and health endpoints unauthenticated. These endpoints may reveal internal metrics and health states useful for reconnaissance.
- OWASP mapping: A05 Security Misconfiguration
- Severity: Medium
- Exploitability: Medium
- Remediation: Consider restricting access to metrics/health endpoints via bind address (loopback-only), simple bearer token, or environment-configured allowlist. Document the exposure and recommend secure placement behind network controls.
Finding 6 — No server-side validation/enforcement of input patterns at runtime
- Files: tools/* (many; e.g., tools/query.go, tools/hits.go), vendor mcp definitions
- Lines: tool definitions rely on mcp's schema generation but handlers do a simple type assertion via GetToolReqParam; pattern validation is not enforced server-side here (GetToolReqParam returns type only). The MCP library may provide client-side schema, but server must validate at runtime.
- Issue: Some pattern constraints on parameters are declared in the tool schemas (via mcp.WithString(..., mcp.Pattern(...))) but these are not enforced by the handler code; type conversion is performed but pattern checks are not applied at runtime. This could lead to malformed inputs reaching upstream services.
- OWASP mapping: A03 Injection (input validation), A04 Insecure Design
- Severity: Medium
- Remediation: Enforce schema/pattern checks in the server before using parameters (e.g., validate RFC3339 timestamps, tenant format, numeric ranges). Use tcr.BindArguments when appropriate for structured input, or explicitly check strings against regexes prior to building requests. Add unit tests for validation.
6) Low Severity Issues / Best-Practice Gaps
Finding 7 — Defer Close after ReadAll: minor resource handling order
- File: cmd/mcp-victorialogs/tools/utils.go
- Lines: GetTextBodyForRequest reads body, then defers resp.Body.Close() after ReadAll. It’s preferable to defer Close immediately after checking err from Do to ensure body is closed on all code paths (even if ReadAll panics). Not a security vulnerability per se.
- Severity: Low
- Remediation: Move defer resp.Body.Close() directly after checking err from Do, before reading.
Finding 8 — Default listen address & mode
- File: cmd/mcp-victorialogs/config/config.go
- Lines: default listenAddr fallback to "localhost:8081" and default serverMode to "stdio". Good for safe defaults but document exposure when switched to http/sse.
- Severity: Low
- Remediation: Document in README and recommend explicit binding/port configuration for production.
Finding 9 — Custom headers parsed from VL_INSTANCE_HEADERS have no validation
- File: cmd/mcp-victorialogs/config/config.go and tools/utils.go
- Issue: Keys and values are not normalized; unusual header keys could lead to unexpected behavior. Low severity since env is operator controlled.
- Severity: Low
- Remediation: Validate header names (token characters) and prevent control characters; strip newlines.
7) Key Risk Characteristics (per finding summary)
- Find.1 (no HTTP client timeout): Exploitability medium; requires repeated tool calls; impact high (DoS); precondition: attacker can invoke tools (common for MCP clients). Likelihood medium.
- Find.2 (SSRF via entrypoint): Exploitability low–medium (requires misconfiguration or operator mistake); impact high (internal data exposure); precondition: operator sets entrypoint to internal/metadata address or an attacker can modify ENV; likelihood low but impact high.
- Find.3 (Authorization override): Exploitability low (requires operator action); impact medium; precondition: environment misconfiguration; likelihood low.
- Find.4 (sensitive logging): Exploitability high (any authenticated or unauthenticated client that triggers tools may cause logging); impact medium (information leakage); precondition: attacker can call tools with sensitive inputs; likelihood medium–high depending on auth model.
8) Positive Security Practices Observed
- Use of context-aware request creation: http.NewRequestWithContext(ctx, ...) is used, allowing cancellation propagation.
- Good separation of concerns: configuration parsing in config.go, request creation in utils.go, and distinct tool handlers.
- Use of patterns in tool input schemas (mcp.WithString Pattern(...)) — helps clients validate inputs.
- Recovery middleware used for tools (server.WithRecovery()) to prevent panics from crashing the server (main.go).
- Embedding docs as read-only, indexed via bleve and using mem-only index reduces disk/privilege surface for resources.
9) Recommendations (file:line where applicable)
- Enforce HTTP client timeouts (High priority)
- File: cmd/mcp-victorialogs/tools/utils.go (GetTextBodyForRequest)
- Change: Replace http.DefaultClient.Do(req) with a configured http.Client having timeouts, or enforce a per-request context deadline before Do(). Example: create package-level var httpClient = &http.Client{Timeout: 15 * time.Second, Transport: &http.Transport{DialContext: ..., TLSHandshakeTimeout: 5time.Second, IdleConnTimeout: 30time.Second}}. Use httpClient.Do(req).
- OWASP: A05 / A04
- Validate and restrict entrypoint URLs (High priority)
- File: cmd/mcp-victorialogs/config/config.go (after url.Parse result.entryPointURL assignment ~line 129)
- Change: Validate scheme (require https unless explicitly allowed), optionally resolve host and check against allowlist or block private IP ranges (169.254.169.254 etc.). Log an explicit error and refuse startup if entrypoint is unsafe.
-
OWASP: A10 / A04
-
Prevent custom header override of Authorization or explicitly define precedence (High/Medium priority)
- File: cmd/mcp-victorialogs/tools/utils.go (CreateSelectRequest/CreateAdminRequest where headers are set)
- Change: Either set custom headers first and then Authorization last, or explicitly remove Authorization from cfg.CustomHeaders before applying; better: treat Authorization specially (doc and warn if both set).
-
OWASP: A07
-
Redact sensitive fields from logs (Medium priority)
- File: cmd/mcp-victorialogs/hooks/hooks.go (NewLoggerHooks), cmd/mcp-victorialogs/logging/middleware.go
- Change: Avoid logging full message/result objects. Introduce a sanitizer that removes or redacts fields like Authorization, AccountID, ProjectID, tenant, tokens, and long texts. Do not log complete tool result contents by default.
-
OWASP: A09
-
Restrict access to /metrics and /health or bind them to loopback (Medium priority)
- File: cmd/mcp-victorialogs/main.go (mux.HandleFunc "/metrics", "/health/*")
- Change: Either bind the HTTP server to localhost only in production or add optional authentication token or network-level restriction. Document intended exposure.
-
OWASP: A05
-
Enforce server-side parameter validation (Medium priority)
- Files: cmd/mcp-victorialogs/tools/*.go
- Change: Validate patterns (timestamps, tenant format) and numeric ranges server-side before constructing upstream requests. If an input violates pattern, return an error. Consider using tcr.BindArguments to strongly type inputs or add explicit regex checks mirroring the schema.
-
OWASP: A03 / A04
-
Move defer resp.Body.Close() immediately after Do error check (Low priority)
- File: cmd/mcp-victorialogs/tools/utils.go (GetTextBodyForRequest)
-
Change: after resp,err := client.Do(req); if err != nil {...}; defer resp.Body.Close(); body, err := io.ReadAll(resp.Body)...
-
Validate custom header keys/values when parsing VL_INSTANCE_HEADERS (Low priority)
- File: cmd/mcp-victorialogs/config/config.go (VL_INSTANCE_HEADERS parsing)
-
Change: Reject headers with control characters or forbidden header names, trim values, and disallow overriding Authorization unless intended.
-
Dependency & supply chain scanning (Medium priority)
- File: go.mod
- Change: Run SCA (Software Composition Analysis) / vulnerability scanning on dependencies (bleve, mcp-go, VictoriaMetrics libs, etc.) and update vulnerable versions promptly.
- OWASP: A06 / A08
10) Next Tier Upgrade Plan (Bronze/Silver/Gold/Reject)
- Likely current tier: Bronze
- Rationale: Good separation of components and reasonable defaults, but several medium/high findings (timeouts, logging secrets, potential SSRF/config issues) need remediation for production-grade integration.
- Target next tier: Silver
-
Prioritized actions to reach Silver (ordered):
- Enforce HTTP client timeouts and robust transport settings (fix GetTextBodyForRequest) — reduces DoS risk. (tools/utils.go)
- Add entrypoint URL validation and hostname/IP allowlist/denylist checks during config initialization. (config/config.go)
- Prevent or clearly control Authorization header overrides from VL_INSTANCE_HEADERS and document header precedence. (tools/utils.go & config/config.go)
- Implement safe logging with redaction of sensitive fields and remove logging of full request/result bodies by default. (hooks/hooks.go, logging/middleware.go)
- Add server-side parameter validation for critical inputs (timestamps, tenant formats). (tools/* handlers)
- Configure metrics and health endpoint access (bind to loopback or add auth). (main.go)
- Run dependency vulnerability scanning and set an update policy. (go.mod)
-
Steps toward Gold (after Silver):
- Implement allowlists for upstream hosts and TLS-only enforcement with certificate pinning or operator-configurable CA verification.
- Add telemetry and alerting on anomalous outbound request rates / tool-call rates and integrate rate-limiting per-session.
- Harden runtime: use a dedicated HTTP transport per external endpoint, circuit-breakers, bulkheads, and per-tool concurrency limits.
- Tighten logging controls: centralized structured logging with role-based access and retention policies, secrets scrubbing at source.
Appendix: Concrete code references (sample locations)
- cmd/mcp-victorialogs/main.go
- /metrics handler: mux.HandleFunc("/metrics", ...) (main.go near server start)
- /health handlers: mux.HandleFunc("/health/liveness" and "/health/readiness")
- cmd/mcp-victorialogs/config/config.go
- Parsing VL_INSTANCE_ENTRYPOINT and url.Parse -> result.entryPointURL (InitConfig)
- Parsing VL_INSTANCE_HEADERS -> custom headers map
- cmd/mcp-victorialogs/tools/utils.go
- CreateSelectRequest / CreateAdminRequest: header setting and custom header overwrite behavior
- getSelectURL / getRootURL: building outbound URL from entrypoint
- GetTextBodyForRequest: uses http.DefaultClient.Do(req) and io.ReadAll(resp.Body)
- cmd/mcp-victorialogs/hooks/hooks.go
- NewLoggerHooks -> AddBeforeAny/AddOnSuccess logging of messages/results using toJSON
- cmd/mcp-victorialogs/logging/middleware.go
- Logs request start/completion including remote_addr, path, and size
Final notes:
- The codebase overall follows good modular design and sensible defaults; most data flows are explicit and handled through the MCP tool handlers. The most pressing items for production hardening are enforcing outbound request timeouts and improving handling of secrets (avoid Authorization override by custom headers and prevent logging of potentially sensitive request and result bodies). Addressing the high-priority items should move this integration from Bronze to Silver.
If you want, I can produce concrete patch snippets for the most critical fixes (http.Client with timeouts, entrypoint validation, Authorization override prevention, and logging redaction).
Summary
Security Score: 80/100 (Silver)
Static analysis found 0 high, 0 medium, and 0 low severity issues.
Build step skipped for safety.
No automated tests detected.
Sign in to leave a review
No reviews yet — be the first!
Configuration
VL_INSTANCE_BEARER_TOKEN
required
🔒 password
Configure the connection to VictoriaLogs MCP Server
VL_INSTANCE_ENTRYPOINT
required
string
URL of VictoriaLogs instance (it should be root URL of vlsingle or vlselect)
VL_INSTANCE_HEADERS
string
Optional custom headers to include in requests to VictoriaLogs instance, formatted as 'header1=value1,header2=value2'
MCP_SERVER_MODE
string
Mode in which the MCP server operates (possible values: stdio, http, sse)
MCP_LISTEN_ADDR
string
Address and port on which the MCP server listens for incoming connections (e.g., ':8081')
MCP_DISABLED_TOOLS
string
Comma-separated list of tools to disable (possible values: export, metric_statistics, test_rules)
MCP_HEARTBEAT_INTERVAL
string
Defines the heartbeat interval for the streamable-http protocol. It means the MCP server will send a heartbeat to the client through the GET connection, to keep the connection alive from being closed by the network infrastructure (e.g. gateways)
Docker Image
Docker HubPublished by github.com/VictoriaMetrics-Community