← All MCP servers
MCP server

koreanpulse

mcp:whdrnr2583-cmd/koreanpulse

Korean equities in English: DART filings, activist & foreign-holder classification, KRX news.

Verdict
Suspicious

Risky behavior the analysis could not rule out.

Analyzed Oct 26, 2026, 13:32 UTC at 078952a
2
findings
high
highest severity
1
threat classes
153
files scanned
1,665/1,665
checks satisfied
0
package advisories

Why this verdict

  • suspicious: finding mcp-server:.:daily-worker/src/index.ts:530:SUPPLY
  • suspicious: finding mcp-server:.:pyproject.toml:38:SUPPLY

Security findings 2

Supply chain

highContextual risklow confidence

The package depends on the unpinned `agentprod`, with a uv source pointing to a local path outside the repository (../agentprod). The code that is installed is therefore unverifiable.

"agentprod",
conceal:remotevector:metadata
Counter-argument considered

agentprod is an unpinned runtime dependency whose uv source is a local path outside the repo. A wheel install from an index would resolve whatever package carries that name, and nothing cited mitigates this.

Supply chain

mediumContextual risklow confidence

The daily worker's empty-state HTML page loads the Tailwind CSS script from a mutable third-party CDN URL with no pinning or integrity check, so the remote code can change without notice (low-impact, common practice).

<script src="https://cdn.tailwindcss.com"></script>
conceal:remotevector:code
Counter-argument considered

The page loads an unpinned third-party script with no integrity check. Impact is low and it is served to browsers rather than agents, but no cited carve-out or mitigation neutralizes it.

Open questions 2

What the analysis could not settle from the code alone.

Which tool or caller supplies the webhook URL and the alert body to send_alert, and does the body include anything beyond public DART filing data?
Data exfiltration
[file request src/koreanpulse/server.py] Where is send_alert called, who controls the webhook URL, and what data goes into the alert title and body?
Data exfiltration
Refuted findings 3

Candidates the review stage examined and rejected, kept for transparency.

Data exfiltration

criticalRefutedlow confidence

The cache worker sends the OpenAI API key and user-supplied text to a Cloudflare AI Gateway proxy URL instead of api.openai.com; the gateway is undeclared in the manifest but disclosed in a code comment as a region-block workaround.

"https://gateway.ai.cloudflare.com/v1/520ed8d88fdd95e30af7d0a0e81c1706/koreanpulse/openai/chat/completions",
Why it was refuted

The key is the operator's own env OPENAI_API_KEY for the wrapped OpenAI service. It goes to an operator-controlled Cloudflare AI Gateway route, a disclosed proxy for OpenAI, so this is the env-API-key carve-out and not exfiltration.

Data exfiltration

highRefutedlow confidence

send_alert posts title/body content to a caller-supplied Discord/Slack/Telegram webhook URL, which could send data off-host to an attacker-chosen channel if the URL or content is influenced by untrusted input; no caller is shown here, so the source and destination are not established.

return await client.post(url, json=payload)
Why it was refuted

The webhook sender is a declared alert feature. detect_channel only accepts Discord, Slack and Telegram URL patterns and rejects everything else as unsupported, so the destination is allow-listed. The payload is only title/body, and no tool in the shown server.py calls send_alert with untrusted or sensitive data, so there is no source-to-sink chain.

Tool poisoning

highRefutedlow confidence

The tool docstring, which is MCP tool metadata, directs the client LLM how to handle another tool (not to fall back to `track_korean_filings`) and to relay paywall text verbatim; this conditions agent tool use but appears to be a paywall UX instruction.

Do NOT silently retry with `track_korean_filings`
Why it was refuted

The docstring text is a paywall UX instruction. It tells the client to relay the license notice and not to fall back to a free tool that would return a misleadingly empty answer. It does not touch credentials, exfiltrate data, or hide behavior, and it is openly declared in the tool description, so it is benign.

Coverage gaps 3

Parts of the artifact the static analysis could not fully examine.

manifest_unparseable server configuration is not an object
landing/public/.well-known/mcp.json
request_unanswered request.0: behavior-chains.9/req-alert-callers: resolved_clean: citation not shown or quote not in it
invalid_refuter refuter results do not match requested findings