bunnycdn-mcp
This server lets an AI assistant manage a Bunny.net account—CDN, DNS, Edge Storage, Stream/video, edge scripts, Shield/WAF, and Magic Containers—through MCP, with read-only mode and credential redaction by default.
Read account details, billing summary, CDN statistics, and search across all Bunny resources.
Manage pull zones: create, update, delete, purge cache/URLs, add/remove hostnames, and configure edge rules.
Manage DNS zones and records, including create/update/delete and DNS statistics.
Manage storage zones and storage files (list, download, delete) when a storage key is configured.
Manage video libraries and Stream videos/collections: CRUD, view statistics, heatmaps, and re-encoding.
Manage edge scripts: list/get scripts, view/upload source code, publish releases, and manage variables/secrets.
Manage Shield/WAF: list shield zones, view WAF rules, manage custom rules and rate limits, read bot detection settings, and get security metrics.
Manage Magic Containers: list/get/create/update/delete apps, deploy/undeploy/restart, list registries/regions, and retrieve app statistics.
Retrieve origin error logs for debugging pull zone failures.
Security defaults: write tools are withheld unless BUNNY_READONLY=0, responses are allow-listed to keep credentials out of model context, and edge-script source is gated behind BUNNY_ALLOW_SOURCE.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bunnycdn-mcppurge the cache for all my pull zones"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bunny-mcp
MCP server for Bunny.net — pull zones, DNS, storage, video streaming, edge scripting, Shield/WAF and Magic Containers, from an AI assistant.
A hardened fork of anvme/bunnycdn-mcp (MIT). Two things differ, and both exist because pointing the upstream at a real Bunny account publishes credentials.
Part of the Aura Design Engine
These are the skills behind Aura — one AI web-agency lifecycle you can run standalone or orchestrate across a whole client fleet from a single dashboard.
Stage | Skill | Role |
🎨 Build | Design & build sites inside Elementor — the recipes, and the MCP engine under them | |
🔎 Audit + Content | REST content ops, SEO & site audits | |
🖥 Host | Provision & operate the infrastructure | |
🚀 Deliver | CDN, storage & edge delivery | |
🛡 Govern | Drive the control plane — approvals, snapshots, rollbacks — over MCP |
→ Orchestrate all of it across your client fleet with Aura — governed agent ops with approvals and a full audit trail on top of these skills.
Related MCP server: Cloudflare Control
What the fork changes
1. Responses are projected through an allow-list
Bunny returns credentials inline with ordinary metadata:
Endpoint | Credential in the response |
|
|
|
|
|
|
|
|
|
|
Handing those to a model puts them in its context, its logs and its transcript. So no tool ever sees them: every response passes through lib/project.js at the HTTP layer, keyed by request path, and only the fields named there survive.
It is an allow-list, not a deny-list. Stripping known secret names fails the moment Bunny adds a field — the new one ships in the clear and nothing tells you. Naming what may pass fails the other way: a new field is invisible until someone decides it is safe.
It fails closed. A path with no declared shape returns no data and an error naming the path, rather than the raw payload.
It applies inside a value, not only to it. A URL keeps scheme, host, port and path; userinfo, query and fragment go. The first version of that scrubber removed user:password@ and kept the rest — a deny-list wearing a scrubber's coat, which closed the one place a credential was known to sit and let ?token=… walk through. And a free-form bag is a bag whether it arrives as an object or a string: CustomHTML is dropped for the same reason metaTags is.
It does not vet structure by naming its parent. A bare field name may only carry a scalar, or an array of them; an object survives only where a nested shape is declared for it. Every leak found while reviewing this fork lived one level below a name someone had already vetted — Hostnames looked safe and held the TLS private key; EdgeRules was given a shape and ExtraActions inside it still carried the very parameter that shape existed to drop.
2. Write tools are withheld unless you ask for them
BUNNY_READONLY defaults to on. In that mode the write-capable tools are never registered — absent from tools/list, not merely annotated as risky. An agent cannot call a tool it cannot see, and the MCP destructiveHint is advice to a client, not a control.
The gate fails closed: a tool is registered in read-only mode only if it declares readOnlyHint: true. A new tool whose author forgot its annotations counts as a writer and is withheld.
BUNNY_READONLY=0 # register the write tools too — 0/false/no/off, nothing elseErrors are projected too
A non-2xx response never reaches the response interceptor — axios routes it to the rejection handler — so error bodies get their own boundary. Bunny quotes submitted values back in validation messages, and what these tools submit includes edge-script secrets, so the rule keys on the request: a request that carried no body cannot have its own payload echoed at it and keeps its message; a request that carried one has the message withheld, with the status and ErrorKey still saying what went wrong.
Diagnostics keep the sentence and lose the target
An origin error log and a transcoding failure both quote the request that failed, and that request is the one an operator signs. Those fields are kept — a diagnostic that will not say what failed is not worth returning — but the target inside them is withheld whole, not edited:
failed fetching https://svc:pw@origin/x?token=secret after 10s
↓
failed fetching (withheld: URL) after 10sA whitespace-delimited token is withheld when it carries an @, or a ?/# with anything attached to it — either side. That is what separates a query or fragment from ordinary punctuation: why? because has a space after the mark, while callback?token=secret and a bare #access_token=x do not. Nothing is parsed, so there is no interior for a new URL shape to hide in — nine review findings were spent teaching an earlier reducer the shapes prose can take, and each one found the shape the last had not met.
A fragment goes even when it looks like a section number. #3 reads as a reference and #123456 reads as a PIN, but they are the same string with different digits, so no rule can tell them apart; both are withheld rather than guessed at.
A token with none of those marks is returned exactly as written, so https://origin.example/ok, origin.example/file and 3.5 are untouched: a plain target carries nothing, and which host failed is most of a diagnostic's value.
The structured target fields — a log's Url and Path — are reduced rather than withheld, because a field that IS a URL can be cut precisely.
What this does not catch, said plainly: a secret embedded in a path segment, as in /download/sk_live_x/file. Nothing short of understanding the operator's own URL scheme would.
Edge-script source is withheld by default
/compute/script/<id>/code returns the script's source, and source carries hard-coded keys about as readily as any other operator-authored text — CustomHTML is dropped for exactly that reason. So the body is withheld and the response says how to release it:
BUNNY_ALLOW_SOURCE=1 # return edge-script source — 1/true/yes/on, nothing elseMore generally, a non-JSON body on the management API no longer gets a free pass. It passes only where a route declares it may; anything else raises, naming the path. The blanket "non-JSON means it's a file download" exemption was the hole this closed.
Credential scoping
Use a permission-scoped key from Account → API → Manage Keys, never the account master key. The redaction above keeps secrets out of the transcript; it does nothing about what the key itself is allowed to do.
Features
Tool | Description | Data Source | Mode |
| Get account details and balance | bunny.net API | read |
| Get billing summary with charges | bunny.net API | read |
| Get CDN statistics (bandwidth, requests, cache hit rate) | bunny.net API | read |
| Search across all resources | bunny.net API | read |
| Purge a URL from CDN cache | bunny.net API | write |
| List CDN edge regions | bunny.net API | read |
| List countries for geo-blocking | bunny.net API | read |
| List pull zones with search and pagination | bunny.net API | read |
| Get pull zone details | bunny.net API | read |
| Create a pull zone | bunny.net API | write |
| Update pull zone settings | bunny.net API | write |
| Delete a pull zone | bunny.net API | write |
| Purge entire pull zone cache | bunny.net API | write |
| Add or remove custom hostnames | bunny.net API | write |
| Add, update, delete, or toggle edge rules | bunny.net API | write |
| List DNS zones | bunny.net API | read |
| Get DNS zone with all records | bunny.net API | read |
| Create a DNS zone | bunny.net API | write |
| Update DNS zone settings | bunny.net API | write |
| Delete a DNS zone | bunny.net API | write |
| Add, update, or delete DNS records | bunny.net API | write |
| Get DNS query statistics | bunny.net API | read |
| List storage zones | bunny.net API | read |
| Get storage zone details | bunny.net API | read |
| Create a storage zone | bunny.net API | write |
| Get storage zone usage statistics | bunny.net API | read |
| List files and directories | Storage API | read |
| Download file content | Storage API | read |
| Delete a file or directory | Storage API | write |
| List video libraries | bunny.net API | read |
| Get library details | bunny.net API | read |
| Create a video library | bunny.net API | write |
| Update library settings | bunny.net API | write |
| List videos with search and pagination | Stream API | read |
| Get video details | Stream API | read |
| Create video object, optionally fetch from URL | Stream API | write |
| Update video metadata | Stream API | write |
| Delete a video | Stream API | write |
| Get view statistics | Stream API | read |
| Get attention heatmap data | Stream API | read |
| Re-encode a video | Stream API | write |
| List video collections | Stream API | read |
| Get collection details | Stream API | read |
| Create, update, or delete collections | Stream API | write |
| List edge scripts | bunny.net API | read |
| Get script details | bunny.net API | read |
| Get script source code | bunny.net API | read |
| Upload script code (saved as draft) | bunny.net API | write |
| Create, update, or delete scripts | bunny.net API | write |
| Publish a release to edge servers | bunny.net API | write |
| List a script's environment variable names | bunny.net API | read |
| Manage environment variables and secrets | bunny.net API | write |
| List shield security zones | bunny.net API | read |
| Get zone by shield zone ID or pull zone ID | bunny.net API | read |
| Get WAF rules and profiles | bunny.net API | read |
| Create, update, or delete custom WAF rules | bunny.net API | write |
| List rate limiting rules | bunny.net API | read |
| Create, update, or delete rate limit rules | bunny.net API | write |
| Get security metrics overview | bunny.net API | read |
| Read bot detection settings | bunny.net API | read |
| Get or update bot detection settings | bunny.net API | write |
| List Magic Container applications | bunny.net API | read |
| Get application details | bunny.net API | read |
| Get app overview with real-time metrics | bunny.net API | read |
| Create, update, or delete applications | bunny.net API | write |
| Deploy, undeploy, or restart applications | bunny.net API | write |
| List container registries | bunny.net API | read |
| List deployment regions | bunny.net API | read |
| Get application statistics | bunny.net API | read |
| Get origin error logs for a pull zone | bunny.net API | read |
Data sources: Tools marked Storage API require BUNNY_STORAGE_KEY. Tools marked Stream API require BUNNY_STREAM_KEY. All other tools use BUNNY_API_KEY.
Prerequisites
Node.js >= 18
A bunny.net account with an API key
Optional: Stream library API key (for video tools)
Optional: Storage zone password (for file tools)
Setup
No installation needed — just configure your MCP client:
Add to .vscode/mcp.json:
{
"servers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}Add to .cursor/mcp.json:
{
"mcpServers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}Add to claude_desktop_config.json:
{
"mcpServers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}claude mcp add --transport stdio bunny -- npx -y github:Digitizers/bunny-mcpOr add to .mcp.json (shared with team):
{
"mcpServers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}Add to settings.json:
{
"context_servers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}Open Settings → Tools → AI Assistant → MCP, click +, and paste:
{
"mcpServers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}gemini mcp add bunny -- npx -y github:Digitizers/bunny-mcpOr add to ~/.gemini/settings.json:
{
"mcpServers": {
"bunny": {
"command": "npx",
"args": ["-y", "github:Digitizers/bunny-mcp"],
"env": {
"BUNNY_API_KEY": "your-api-key"
}
}
}
}Any MCP client that supports stdio transport can use this server. The command is:
npx -y github:Digitizers/bunny-mcpSee the full list of MCP clients.
Optional environment variables
Variable | Description |
| Video library API key — enables Stream video and collection tools |
| Storage zone password — enables Storage file tools |
| Storage region code (default: empty for Falkenstein) |
| Default storage zone name |
Add these to the env block in your MCP client configuration above.
Local development
git clone https://github.com/Digitizers/bunny-mcp.git
cd bunny-mcp
npm install
npm test
node index.jsHow It Works
This MCP server connects to the bunny.net API using your API key. The catalog above holds 70 tools, split by which API keys are provided:
Core tools (56 tools) — always available with
BUNNY_API_KEYStream tools (11 tools) — registered when
BUNNY_STREAM_KEYis setStorage file tools (3 tools) — registered when
BUNNY_STORAGE_KEYis set
Those are the totals with the write gate open. By default BUNNY_READONLY is on and 41 of the 70 register — the 29 write-capable ones are withheld, per section 2. The Mode column in the catalog says which is which.
All read operations are cached in-memory with a short TTL for performance. Every tool includes MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) so clients can make informed decisions about tool approval.
License
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to manage Cloudflare resources through natural language, including DNS records, zone management, Workers KV storage, cache purging, and analytics. Supports comprehensive Cloudflare operations with secure API token authentication.132MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Cloudflare infrastructure including DNS records, cache purging, SSL settings, Workers, and analytics through the Cloudflare API. Eliminates dashboard context-switching by allowing natural language control of domain management and infrastructure operations.
- FlicenseBqualityDmaintenanceEnables interaction with Bunny.net APIs for Stream/Video, Storage, CDN Pull Zones, and DNS services. Provides 35 tools for managing video libraries, files, CDN configurations, and DNS records through Claude.37
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Cloudways infrastructure, including servers, applications, monitoring, and security via the Cloudways API.
Related MCP Connectors
Manage your Vidalytics videos and analytics from your AI assistant.
AI-powered design and management for Webflow Sites
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Digitizers/bunny-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server