mail-report-mcp
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., "@mail-report-mcpGenerate an HTML email report from this markdown and send it to ops@example.com"
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.
mail-report-mcp
An MCP server that turns a Markdown report into a polished, email-safe HTML message and sends it over SMTP.
In | Markdown from the model, plus a zip of screenshots and files |
Out | HTML mail with every style inlined, delivered over SMTP with retries |
Clients | Claude Code, Codex, opencode, or a gateway such as LiteLLM |
It speaks streamable HTTP, so any MCP client can use it: an agent on your laptop, or a gateway that fans the tools out to every model behind it. It runs the same way either way.
Features
Markdown in, email-safe HTML out. Every style is inlined, so the message survives mail clients that strip
<style>blocks.Coloured pills.
Critical,High,Medium,LowandInfobecome pills in tables and###headings on their own.MAIL_REPORT_PILLSteaches the server words of your own, and[[shipped|green]]pills anything else on the spot.The model needs no prompting. The style guide ships as a tool, a resource and a prompt, so a fresh model writes the right format without you maintaining one.
Screenshots cost no tokens. Zip
report.mdwith its images, upload it once, and everyis embedded inline. File bytes never pass through the model's context.No long-lived secret in the agent. Uploads run on short-lived tickets, so the auth token stays on your side.
Delivery is queued, not hoped for. Retries with exponential backoff, a hard give-up window, an optional rate limit, and a
job_idthat tells you whether it actually went out.Size caps come from the relay. Attachment limits are derived from the ESMTP
SIZEyour relay advertises, rather than guessed.Recipients are governed. Three sources (the model, a per-key gateway header, a server default), one allowlist over all three, and a strict mode where each caller supplies its own address.
Branded per server. Accent colour and logo are env vars. The logo is rasterized from SVG, because mail clients will not render it.
Closed by default. Bearer-token auth, a separate unauthenticated health endpoint, a non-root container and a healthcheck.
Related MCP server: MCP Sendmail Server
Contents
Quick start
1. Make a directory
mkdir mail-report-mcp && cd mail-report-mcp
mkdir -p datadata/ holds the upload spool and the delivery queue. Without that mount both are ephemeral, so queued mail is lost on restart.
2. docker-compose.yml
services:
mail-report-mcp:
image: spaaleks/mail-report-mcp:latest
# or if you prefer quay.io:
# image: quay.io/spaaleks/mail-report-mcp:latest
restart: unless-stopped
env_file: .env
ports:
- "8000:8000"
volumes:
- ./data:/dataThat publishes the port, which is what you want when the client is an agent on the same host. If the client is another container, drop the ports: block, put both on a shared network and let them talk by service name.
3. .env
# Copy to .env. Never commit it.
# openssl rand -hex 32
MCP_AUTH_TOKEN=
SMTP_HOST=mail.example.com
SMTP_PORT=587
SMTP_SECURITY=starttls
SMTP_USER=reports@example.com
SMTP_PASS=
SMTP_FROM=reports@example.com
SMTP_FROM_NAME=Acme Reports
SMTP_TO=you@example.comSMTP_HOST and SMTP_FROM are the only required values. Omit SMTP_USER and SMTP_PASS for an unauthenticated relay. Everything else has a default, and the full list is in Environment variables.
Leave MCP_AUTH_TOKEN set. Anything that can reach the port can send mail as you, and the container logs a warning at startup if it is empty.
4. Start it
docker compose up -d
curl -s http://localhost:8000/healthz
# {"status":"ok","smtp_configured":true}smtp_configured: false means the SMTP block did not resolve, and docker compose logs carries the startup error saying which value is missing.
/healthz needs no token. Every other path returns 401 without one.
5. Point a client at it
The URL is the server plus /mcp, and the token goes in as a bearer header.
Claude Code
claude mcp add --transport http mail-report http://127.0.0.1:8000/mcp \
--header "Authorization: Bearer $MCP_AUTH_TOKEN"Codex
codex mcp add mail-report --url http://127.0.0.1:8000/mcp \
--bearer-token-env-var MCP_AUTH_TOKENOr in ~/.codex/config.toml:
[mcp_servers.mail_report]
url = "http://127.0.0.1:8000/mcp"
bearer_token_env_var = "MCP_AUTH_TOKEN"Codex reads the token from that environment variable at connection time, so it never lands in the config file.
opencode
In opencode.json, or ~/.config/opencode/opencode.json to have it everywhere:
{
"mcp": {
"mail-report": {
"type": "remote",
"url": "http://127.0.0.1:8000/mcp",
"enabled": true,
"headers": { "Authorization": "Bearer {env:MCP_AUTH_TOKEN}" }
}
}
}LiteLLM
A gateway reaches it the same way, and hands the tools to every model behind it. In your LiteLLM config.yaml:
mcp_servers:
mail_report:
url: "http://mail-report-mcp:8000/mcp" # compose service name + port
transport: "http"
description: "Render Markdown reports to email-safe HTML and send them over SMTP."
auth_type: "bearer_token"
auth_value: os.environ/MCP_AUTH_TOKEN # same value as the server's MCP_AUTH_TOKENThat URL is a compose service name, which resolves when both containers share a Docker network. It is the tidiest arrangement, and it lets you drop the ports: block from step 2, but any URL LiteLLM can reach works, including a published port or a public hostname. More on per-key recipient routing in Behind a gateway: LiteLLM.
6. Send the first report
Ask the agent for one in plain language:
Read the mail-report style guide, then send me a report on what you changed today.
The model calls report_guide, writes the Markdown, and calls send_report. It gets back a job_id, and report_status says whether the mail actually left. Nothing else has to be explained to it.
If you would rather check the rendering before anything is sent, ask for preview_report instead. It returns the HTML and sends nothing.
What the mail looks like
A pentest round, written by the model as plain Markdown in the subset the guide describes:
# Embedded API — Round v7
No Critical or High findings this round. The tenant boundary held under every probe that broke it in v5, and the two remaining issues are configuration drift rather than logic flaws.
| ID | Sev | Title |
|------------|--------|--------------------------------------|
| EMB-v7-001 | Medium | Stale CORS allowlist entry |
| EMB-v7-002 | Low | Verbose error body on malformed JWT |
| EMB-v7-003 | Info | Server header discloses build number |
---
## Findings
### EMB-v7-001 — Medium — Stale CORS allowlist entry
The allowlist still carries the old staging origin, decommissioned when staging moved in-house. Nothing serves that name today, but the record is registrable, so whoever claims it inherits credentialed cross-origin reads.
**Repro:**
```http
GET /v1/tenants/self HTTP/1.1
Host: api.example.com
Origin: https://staging.example.net
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://staging.example.net
Access-Control-Allow-Credentials: true
```
**Impact:** an attacker registering `staging.example.net` reads any authenticated response a victim's browser will make.
**Fix:** drop the entry from `config/cors.yaml`, and fail the deploy when an allowlist origin stops resolving. See the [CORS notes](https://example.com/docs/cors).That is the whole input. No HTML, no template, no styling decision from the model. Here is the mail it produces, as the recipient sees it:

Medium, Low and Info in that table became pills without being marked up. The full report this was cut from, severity legend and all, lives in tests/sample_report.py.
The calls behind it
send_report(
subject="Embedded API — Round v7",
title="Embedded API — Round v7",
subtitle="blind reassessment, 2026-09-01",
body="# Embedded API — Round v7\n\nNo Critical or High findings this round. …",
)The # Embedded API — Round v7 heading is dropped from the body because it repeats title, so passing both is safe. The call returns as soon as the mail is queued, not when it is sent:
{
"queued": true,
"job_id": "job_4f1c8a2b6d0e7391a5c2b8f4",
"to": ["you@example.com"],
"subject": "Embedded API — Round v7",
"recipient_source": "default",
"attachments": [],
"inline_images": [],
"attachment_bytes": 0,
"html_bytes": 18379,
"note": "Delivery runs in the background with retries. Call report_status with this job_id to confirm."
}recipient_source is argument, header or default, so the model can see which of the three recipient sources applied. Then:
report_status(job_id="job_4f1c8a2b6d0e7391a5c2b8f4"){
"job_id": "job_4f1c8a2b6d0e7391a5c2b8f4",
"state": "delivered",
"attempts": 1,
"queued_at": 1756901400.12,
"updated_at": 1756901401.86,
"delivered_at": 1756901401.86,
"result": {
"sent": true,
"to": ["you@example.com"],
"subject": "Embedded API — Round v7",
"attachments": [],
"attachment_bytes": 0,
"message_bytes": 27402,
"html_bytes": 18379,
"logo": "logo.svg",
"inline_images": []
}
}While it is still in the queue state is queued or active, and a report that keeps failing ends at failed with last_error naming the SMTP reason.
How it works
MCP client --> mail-report (port 8000) --> SMTP relay --> inbox
^ |
| +--> upload endpoint (files, bypassing the model)
+-- tools, resource, promptThe client is anything that speaks MCP: an agent such as Claude Code or opencode talking to it directly, or a gateway such as LiteLLM that exposes the tools to the models behind it.
The model reads
guide://report-styleand writes the report in MarkdownFor a report with images, it calls
request_upload_ticketand posts a zip straight to the upload endpointsend_reportrenders the Markdown, resolves attachments and queues the mailA background worker delivers it, retries on transient SMTP failures and deletes the files once sent
report_statusreports whether it actually went out
Tool | Purpose |
| Where mail will go, the upload URL, size limits and the recipient policy |
| The report style guide, same content as the |
| Render Markdown to HTML without sending |
| A short-lived ticket for posting files to the upload endpoint |
| Queue a report for delivery |
| State of a queued report: queued, active, delivered or failed |
Running it without compose
docker run --rm \
-p 8000:8000 \
-e MCP_AUTH_TOKEN=your-token \
-e SMTP_HOST=mail.example.com \
-e SMTP_FROM=reports@example.com \
-e SMTP_TO=you@example.com \
-v "$(pwd)/data:/data" \
spaaleks/mail-report-mcp:latestInstead of environment variables you can mount a dotenv file read-only at /config/.env.
Environment variables
key | default | notes |
|
| bind address |
|
| |
|
| upload endpoint |
| (unset) | absolute URL uploads are reachable at, advertised to callers when it differs from the MCP host |
| (unset) | when set, requires |
| (unset) | comma-separated |
|
| |
|
| whether the model may name a recipient |
|
| drop the |
| (unset) | allowlist applied to every recipient whatever its source. |
| 25 MiB, or the message budget if lower | largest single file |
| derived from the relay | largest combined payload per mail. Replaces the relay-derived budget, so a value above what the relay takes just moves the rejection to the relay |
|
| how long an unused upload survives the sweeper |
|
| delivery attempts before giving up, |
|
| hard stop for retries even when attempts are unlimited, |
|
| outbound messages per minute, |
|
| logo shown above the title. SVG, PNG, JPG, GIF or WEBP |
|
| display width in px |
|
| brand colour of section headings, links, the title rule and blockquotes. |
| (unset) | extra pill words beyond the severities. |
DNS-rebinding protection follows MCP_HOST and covers /mcp: a loopback bind validates the Host header automatically (a request claiming Host: evil.example.com gets 421), while binding 0.0.0.0, as the image does, leaves it off until you list hosts in MCP_ALLOWED_HOSTS. Behind a reverse proxy, list the public hostname there.
Mount /data. Uploads land in /data/attachments, the delivery queue in /data/state (mode 0700). Without the mount both are ephemeral and queued mail is lost on restart. send_report only accepts att_… ids, never paths, so a caller cannot name a file of its own choosing.
SMTP configuration
Resolution order: <project-root>/.env → /config/.env → ./.env, with process environment variables overriding whichever file was found.
key | required | notes |
| yes | |
| yes | From: address |
| no | display name shown before it, e.g. |
| no | default recipient (a |
| no | default |
| no | omit for an unauthenticated relay |
| no |
|
Attachments
Files go in through the upload endpoint and come back as att_… ids, so a remote caller never needs a file path.
The model calls request_upload_ticket first and posts with the short-lived ticket it gets back, which keeps any long-lived secret out of the agent's environment. With MCP_AUTH_TOKEN you can post directly:
curl -H "Authorization: Bearer $MCP_AUTH_TOKEN" -F file=@shot.png \
https://reports.example.com/attachments
# {"id":"att_64dbb3…","filename":"shot.png","bytes":18422,"expires_in_seconds":86400}send_report(subject=…, body=…, attachments=["att_64dbb3…"])--data-binary @shot.png -H "X-Filename: shot.png" works too, if that is easier to generate. Uploads are swept after MAIL_REPORT_ATTACH_TTL.
Bundles
A report with pictures goes in as a bundle. Zip report.md together with its images and any files, upload it once, and pass the returned bundle_id:
report.md referenced: 
login.png
console.png
findings.pdf not referenced, so it is attached normallycurl -H "X-Upload-Ticket: $TICKET" --data-binary @bundle.zip \
-H "X-Filename: bundle.zip" https://reports.example.com/attachments
# {"bundle_id":"bnd_…","report":true,"files":{...}}send_report(subject="…", bundle_id="bnd_…")report.md becomes the body, every  reference is embedded as an inline cid: part so the recipient sees it in place, and unreferenced files ride along as attachments. File bytes never travel through the model's context.
Exposing uploads without exposing MCP
/mcp and the upload endpoint are separate paths, so you can publish one and keep the other internal. Set MCP_UPLOAD_URL to the public URL uploads end up on. The server hands it to callers via smtp_status and names it in error messages, so set it whenever uploads are reachable somewhere other than the MCP host.
Publishing only uploads, with /mcp staying on the internal network. In a Caddyfile:
reports.example.com {
reverse_proxy /attachments mail-report-mcp:8000
}The same in an nginx server block:
server {
listen 443 ssl;
server_name reports.example.com;
ssl_certificate /etc/ssl/reports.example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/reports.example.com/privkey.pem;
location /attachments {
proxy_pass http://mail-report-mcp:8000;
proxy_set_header Host $host;
client_max_body_size 25m;
}
}nginx caps request bodies at 1 MB, so client_max_body_size has to be at least as large as MAIL_REPORT_MAX_ATTACHMENT_BYTES or uploads come back as 413 before they ever reach the server.
Then tell the server where uploads ended up, in the compose file's environment: block:
environment:
MCP_UPLOAD_URL: "https://reports.example.com/attachments"MCP_ATTACH_PATH is a separate knob that moves the path the server itself listens on, default /attachments. You only need it if that path collides with something else behind the same proxy.
/healthz is the only unauthenticated path. The upload endpoint accepts a short-lived X-Upload-Ticket, which is what the model uses so no long-lived secret ever reaches the agent's environment, or MCP_AUTH_TOKEN for your own curl.
Recipients
Three sources, tried in order, and the result says which one applied (recipient_source):
source | set by | |
1 | the | the model, when the user names an address |
2 | the | your gateway, per API key |
3 |
| the server's config |
The header is read straight off the request, so the model never sees or controls it. Any gateway that can set a per-key header can drive it. With LiteLLM, a caller sends x-mcp-mail_report-x-mail-report-to: team-a@example.com and the header is forwarded as x-mail-report-to, provided the name is listed in that server's extra_headers.
send_report sends mail on your behalf, so three settings are worth reviewing:
MAIL_REPORT_ALLOW_TO_ARG=falseturns off the first source, leaving routing to the gateway. Thetoparameter is then absent from the tool schema, so the model has no address to offer.MAIL_REPORT_REQUIRE_TO=trueturns off the third. See below.MAIL_REPORT_ALLOWED_RECIPIENTSbounds every source at once, for example*@example.com,boss@partner.example. Whichever source an address came from, it is checked against this list before the mail is queued, including an address the user just typed at the model's prompt. Without it, whoever can set the header or the argument can send your reports anywhere.
Addresses are validated for shape before any of that, so a newline cannot smuggle extra headers into the message.
Requiring an explicit recipient
SMTP_TO is a convenience: leave to off and the report lands in the office mailbox. That is the wrong default for a shared dev server, where each developer should get their own mail rather than everyone's drafts arriving at one address.
MAIL_REPORT_REQUIRE_TO=true removes source 3. The address then has to come from the caller, either way round:
Pinned per client. Set the
x-mail-report-toheader in the MCP client config, next to the auth token, and every report from that client goes to that developer. Nothing is asked, nothing changes in how the model works.claude mcp add --transport http mail-report http://127.0.0.1:8000/mcp \ --header "Authorization: Bearer $MCP_AUTH_TOKEN" \ --header "x-mail-report-to: dev@example.com"Or the same header in
opencode.json:{ "mcp": { "mail-report": { "type": "remote", "url": "http://127.0.0.1:8000/mcp", "enabled": true, "headers": { "Authorization": "Bearer {env:MCP_AUTH_TOKEN}", "x-mail-report-to": "dev@example.com" } } } }Asked per report. With no header set,
send_reportrefuses and answers{"queued": false, "needs": "recipient", ...}with an instruction to ask the user for an address and call again withto. The style guide's Recipients section switches to match, so the model asks before writing the report rather than after. Nothing is delivered in the meantime, and the model is told not to guess an address. The answer it comes back with is still an ordinarytoargument, soMAIL_REPORT_ALLOWED_RECIPIENTSapplies to it like any other.
SMTP_TO is ignored entirely in this mode, so it can stay in the container's environment. The server logs which mode it is in at startup, and smtp_status reports it as recipients.require_explicit. This is off by default: a plain SMTP_TO server keeps working exactly as before.
Report style
Write Markdown in a supported subset (headings, bold, inline/fenced code, pipe tables, bullet lists, blockquotes, rules, links). Ask the model to read guide://report-style, or call the report_guide tool, and it gets the full layout guide without you writing one.
Pills
Two ways to get one, and they cover different jobs.
Words the server knows. Critical, High, Medium, Low and Info become pills on their own, in ### headings and table body cells. Elsewhere they stay plain text, so a High in a sentence reads as a word rather than a badge. MAIL_REPORT_PILLS adds words of your own, as Word=#rrggbb pairs:
MAIL_REPORT_PILLS="Passed=#2f855a,Failed=#c53030,Flaky=#b7791f,In Progress=#5f6b7a"| Suite | Result | Notes |
|------------|--------|--------------|
| auth | Passed | |
| billing | Failed | 3 cases |
| migrations | Flaky | retry 2 of 3 |Same rules as the severities: tables and ### headings only, matched on the exact spelling you configured, and phrases with spaces are fine. Reusing a severity word re-themes it, so MAIL_REPORT_PILLS="High=#7b1020" changes the colour High renders in. The words in effect are listed by smtp_status and appended to the style guide the model reads, so it writes Passed in a result column without being told.
Anything else, marked inline. For a one-off label there is [[word|colour]], and it works anywhere: prose, list items, headings, table cells.
The `swordfish` account is [[unowned|red]] and the migration is [[shipped|green]].
### Provisioning flow [[Blocked|amber]]Colours are red, orange, amber, green, teal, blue, purple, pink, grey, black, accent (your MAIL_REPORT_ACCENT) or a #rrggbb value. Written without one, [[shipped]] comes out grey, unless the word is in the server's vocabulary, in which case it takes that colour. An unrecognised colour name falls back to grey rather than failing the send.
Inside a table cell the pipe has to be escaped, [[unowned\|red]], because an unescaped one starts a new column. Escaped pipes work in any cell now, so a shell pipe in a code span survives too.
Both forms render to an inlined style attribute on a <span>. There is no stylesheet involved, because a mail client that strips <style> would strip the pills with it.
Logo
The logo sits above the title. assets/logo.svg ships with the image and is used unless MAIL_REPORT_LOGO points somewhere else, so replacing it means mounting your own file and naming it:
services:
mail-report-mcp:
volumes:
- ./data:/data
- ./brand/acme.svg:/brand/acme.svg:ro
environment:
MAIL_REPORT_LOGO: "/brand/acme.svg"
MAIL_REPORT_LOGO_WIDTH: "140"SVG, PNG, JPG, GIF or WEBP, up to 2 MiB. An SVG is rasterized to PNG at twice the display width before it goes out, because mail clients do not render SVG and an <img> pointing at one shows a broken image in most of them. That conversion needs cairosvg, which the image already carries. Point the variable at a PNG if you would rather not depend on it.
MAIL_REPORT_LOGO_WIDTH is the display width in pixels, default 100, and it has to land between 16 and 1200. The file is read once and cached against its path, size and modification time, so dropping a new file in the same place is picked up on the next report without restarting the container.
In the mail the logo travels as an inline cid: part rather than a link, so it appears without the client fetching anything remote. preview_report inlines it as a data URI instead, which is why preview HTML comes out larger than the message that is actually sent.
smtp_status reports the path in use, whether it loaded and how large it is. If no logo loads at startup, send_report drops the include_logo argument from its schema rather than offering the model something that does nothing. When one does load, include_logo=false leaves it off a single report.
Accent colour
The accent colour is one env var. MAIL_REPORT_ACCENT=#2f6f4f turns section headings, links, the rule under the title and the blockquote bar green, and the blockquote's background tint is mixed from it. Severity pills keep their own colours by default, because Critical and High mean red whatever your brand is, though MAIL_REPORT_PILLS overrides any of them and [[shipped|accent]] opts a single pill into the accent. The value goes straight into a style attribute, so it must be #rgb or #rrggbb: colour names and rgb() are rejected. smtp_status reports the colour in effect, and preview_report returns it alongside the HTML.
Placeholders are not expanded
Everything passed to send_report is literal text. There is no shell and no template engine behind it, so a model that writes $(date +%F) into a subtitle is writing those nine characters into the email. send_report refuses to queue a report whose subject, title, subtitle or body still holds a $(…), ${…} or {{…}}, and names the offenders, so the model resolves the value and calls again instead of the recipient reading the placeholder. Inside a code span or fenced block the token is content, not a placeholder, and passes through untouched. preview_report reports the same finding as a warning rather than an error.
Behind a gateway: LiteLLM
LiteLLM is one MCP gateway among several. A gateway needs two things from this server: the bearer token, and a forwarded header if you want per-key recipient routing.
litellm-config.example.yaml holds this block. Merge it into your LiteLLM config.yaml:
mcp_servers:
mail_report:
url: "http://mail-report-mcp:8000/mcp" # compose service name + port
transport: "http"
description: "Render Markdown reports to email-safe HTML and send them over SMTP."
auth_type: "bearer_token"
auth_value: os.environ/MCP_AUTH_TOKEN # same value as the server's MCP_AUTH_TOKENauth_value has to resolve to the same token the server runs with, when the server sets one at all. The url above assumes the two containers share a Docker network, which is the common setup, but anything LiteLLM can reach is fine. It then offers the tools to any tool-calling model and re-exposes the server at http://<litellm>:4000/mail_report/mcp.
License
MIT
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
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 Connectors
Render markdown into email-safe HTML, lint drafts for deliverability problems, and preview emails.
Analyze, audit, fix and diff HTML, MJML, Maizzle and React Email across 21 email clients.
Send transactional email over a verified domain — templates, attachments, custom headers.
Render HTML/.eml emails in real Gmail, Outlook & Yahoo web clients and screenshot them
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables sending emails via SMTP with template management, supporting multiple SMTP configurations, template creation with variable substitution, and bulk email sending with rate limiting.623419MIT
- FlicenseNot gradedqualityDmaintenanceEnables sending emails via SMTP with support for HTML content, attachments, bulk sending, and template-based emails. Features session management and full MCP Streamable HTTP transport compliance.-
- FlicenseAqualityDmaintenanceEnables sending emails through SMTP with support for multiple recipients, attachments, CC/BCC, and both plain text and HTML formats. Includes preset configurations for common email providers like Gmail, QQ, Outlook, and 163.5-
- AlicenseAqualityBmaintenanceA multi-service email platform for MCP-compatible clients that supports standard email providers, transactional APIs, and local testing environments. It enables users to send and receive emails, monitor service health, and integrate with messaging webhooks like Slack and Discord through natural language commands.102MIT
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/spaaleks/mail-report-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server