[ ⌘K ]
← BACK TO SEARCH

geelen/workers-mcp-server

high

Talk to a Cloudflare Worker from Claude Desktop!

This MCP server allows Claude Desktop to interact with Cloudflare Workers by exposing worker methods as tools. It enables taking screenshots of URLs v...

purpose: This MCP server allows Claude Desktop to interact threat: network exposed
TypeScript64May 20, 2026May 20, 2026GITHUB
5/20/2026
high1 finding
src/index.ts
31async takeScreenshot(url: string) {
32    const browser = await puppeteer.launch(this.env.MYBROWSER)
33    const page = await browser.newPage()
34    await page.setViewport({ width: 768, height: 1024 })
35    await page.goto(url)
36
37    const img = await page.screenshot()
38    await browser.close()
39
40    return new Response(img, { headers: { 'Content-Type': 'image/png' } })
41  }
src/index.ts:31

// Exploitable by any user with access to the MCP server (network-exposed).

The takeScreenshot method accepts a URL directly from the user without any validation or sanitization. It passes this URL to page.goto(), which can be used to make requests to internal network resources (e.g., 169.254.169.254 for cloud metadata, internal services, or localhost). This is a classic Server-Side Request Forgery (SSRF) vulnerability.

ImpactAn attacker could use this tool to probe internal network services, access cloud metadata endpoints (e.g., AWS/GCP/Cloudflare metadata), or perform port scanning of internal infrastructure. Since the MCP is network-exposed, this could lead to information disclosure or further compromise.

FixValidate the URL against an allowlist of permitted domains or URL patterns. Reject URLs pointing to private IP ranges (RFC 1918), loopback addresses, or metadata endpoints. Consider using a URL parser to check the hostname and block internal addresses.

high2 findings
src/index.ts
53async sendEmail(recipient: string, subject: string, contentType: string, body: string) {
54    try {
55      const msg = createMimeMessage()
56      const from = this.env.EMAIL_FROM
57
58      msg.setSender({ name: 'Claude Desktop', addr: from })
59      msg.setRecipient(recipient)
60      msg.setSubject(subject)
61      msg.addMessage({
62        contentType: contentType,
63        data: body,
64      })
65
66      await this.env.EMAIL.send(new EmailMessage(from, recipient, msg.asRaw()))
67      return 'Email sent successfully!'
68    } catch (error) {
69      console.error(error)
70      throw error
71    }
72  }
browser.automationnetwork.httpenv.exposure
65
LLM-based
high findings+50
medium findings+15