LLM Security Warnings
5 min read
When an LLM (Claude Desktop, Cursor, Windsurf, etc.) runs an MCP server programmatically, the human user never sees the terminal. The --trust flag skips the interactive confirmation prompt, but there is no other channel to communicate security risks to the user.
smcp solves this by injecting security warnings directly into the MCP protocol, so the LLM reads the warning and communicates it to the user on your behalf.
The Problem
Consider this typical MCP client configuration:
{
"mcpServers": {
"data-tool": {
"command": "smcp",
"args": ["run", "--trust", "acme/data-tool@latest"]
}
}
}
The --trust flag is necessary because the LLM launches smcp as a subprocess — there is no interactive terminal to display the confirmation prompt. But if acme/data-tool has a low security score, the user has no way to know.
How It Works
When smcp run --trust detects a package with a security score below the warning threshold (default 80), it activates a lightweight STDIO proxy that intercepts the MCP initialization handshake and injects two complementary warnings:
1. Instructions Warning (Primary)
The MCP protocol includes an instructions field in the initialize response. This field is designed for the LLM to read as context about the server. All major MCP clients (Claude Desktop, Cursor, Windsurf) pass this field to the LLM.
smcp prepends a structured security warning to this field:
[SECURITY WARNING - MCP Hub Certification]
The MCP server "acme/data-tool" has been analyzed by MCP Hub's automated security
certification pipeline and received a security score of 35/100 (Critical Risk).
Certification Level: 0 (Integrity Verified).
Findings: 5 total (2 critical, 1 high, 1 medium, 1 low).
IMPORTANT: You MUST inform the user about this security assessment before
proceeding with any operations from this MCP server. Tell the user:
- The server name and its security score
- That it has potential security vulnerabilities
- That they should exercise caution with sensitive operations
This assessment was performed by MCP Hub (https://mcp-hub.info).
[END SECURITY WARNING]
The LLM reads this as part of the server context and is instructed to inform the user before proceeding with any operations.
2. Notification Warning (Secondary)
After the handshake, smcp sends a notifications/message notification with severity level warning:
{
"jsonrpc": "2.0",
"method": "notifications/message",
"params": {
"level": "warning",
"logger": "mcp-hub-security",
"data": "Security Warning: acme/data-tool scored 35/100 (Critical Risk). 2 critical, 1 high findings. Exercise caution."
}
}
Some MCP clients display notifications as banners or toasts in their UI, giving direct visibility to the human user even without the LLM acting as intermediary.
Architecture
The proxy intercepts only the initialization handshake (3-4 JSON-RPC messages), then switches to raw byte-level passthrough with zero overhead:
Normal mode (no warning needed):
LLM Client → os.Stdin → MCP Server stdin
MCP Server stdout → os.Stdout → LLM Client
Proxy mode (score below threshold):
LLM Client → smcp proxy → MCP Server stdin
MCP Server stdout → smcp proxy → LLM Client
(after init handshake: switches to raw io.Copy)
The proxy only activates when ALL of these conditions are true:
--trustflag is set- The package has security metadata (hub-format manifest)
- The security score is below the warning threshold
In all other cases, smcp uses direct stdin/stdout passthrough with no performance impact.
Configuration
Warning Threshold
The default threshold is 80. Packages scoring below this value trigger the warning injection. You can customize it with the --warning-threshold flag or in the config file.
CLI flag:
# Warn only for packages scoring below 60
smcp run --trust --warning-threshold 60 acme/data-tool@latest
# Warn for all packages (threshold 100 = always warn)
smcp run --trust --warning-threshold 100 acme/data-tool@latest
# Disable warnings (threshold 0 = never warn)
smcp run --trust --warning-threshold 0 acme/data-tool@latest
Config file (~/.smcp/config.yaml):
policy:
warning_threshold: 80 # Score below which LLM warnings are injected
The CLI flag overrides the config file value.
Score Bands
The warning message includes a risk label based on the score:
| Score Range | Label | Description |
|---|---|---|
| 0-39 | Critical Risk | Serious vulnerabilities detected. The LLM is strongly urged to inform the user. |
| 40-59 | High Risk | Significant security concerns. The LLM should caution the user. |
| 60-79 | Moderate Risk | Some issues found. The LLM recommends awareness. |
| 80-100 | Low Risk | No warning injected (above default threshold). |
Usage Examples
Claude Desktop Configuration
{
"mcpServers": {
"data-tool": {
"command": "smcp",
"args": ["run", "--trust", "acme/data-tool@latest"]
}
}
}
If acme/data-tool has a score of 45, Claude will see the security warning in the server’s instructions and tell the user something like:
“I should let you know that the data-tool MCP server has a security score of 45/100 (High Risk) according to MCP Hub’s analysis. There are some potential security vulnerabilities. You may want to exercise caution with sensitive operations.”
Cursor / Windsurf Configuration
The same approach works with any MCP client that reads the instructions field:
{
"mcpServers": {
"db-query": {
"command": "smcp",
"args": ["run", "--trust", "--warning-threshold", "70", "acme/[email protected]"]
}
}
}
CI/CD with Custom Threshold
For automated environments where you want stricter warnings:
smcp run --trust --warning-threshold 90 acme/tool@latest
This injects warnings for any package scoring below 90, ensuring the LLM flags all but the highest-rated servers.
Behavior Details
Fail-Open
Consistent with smcp’s fail-open philosophy, if the proxy encounters any error during the handshake interception (malformed JSON, unexpected message order, timeout), it falls back to raw passthrough mode. The MCP server runs normally — the only difference is that the security warning is not injected.
Existing Instructions
If the MCP server already has its own instructions field in the initialize response, the security warning is prepended to the existing text. The server’s original instructions are preserved and appear after the warning.
Handshake Timeout
The proxy enforces a 30-second timeout on the initialization handshake. If the MCP server does not complete the handshake within this time, the proxy switches to raw passthrough mode and the server continues running normally.
No Warning Without --trust
When --trust is NOT set, smcp shows an interactive confirmation prompt in the terminal for low-score packages. The protocol injection is unnecessary because the human can see the terminal directly. The warning proxy is only activated when --trust bypasses the interactive prompt.
Next Steps
- Running MCP Servers – General guide to running MCPs with
smcp. - Security Policies – Configure minimum certification levels and score requirements.
- Security Scores – How MCP Hub computes security scores.
- Configuration – Full configuration file reference.