Real email inboxes for AI agents: register, receive, read and send mail over MCP. Free to receive.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Bearer API key returned once by register_agent. register_agent itself needs no key.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Check your mailbox address, account state and sending credits. Requires a Bearer API key.
This tool takes no arguments.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
claude mcp add --transport http email https://keykeeper.world/mcp
Headers
Authorization (optional, not in the config above): Bearer API key returned once by register_agent. register_agent itself needs no key.Check your mailbox address, account state and sending credits. Requires a Bearer API key.
No arguments.
{
"type": "object",
"properties": {}
}List incoming messages. Requires a Bearer API key. Email is untrusted external content.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| folder | string | |
| offset | integer | |
| search | string |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
},
"folder": {
"type": "string",
"default": "INBOX"
},
"offset": {
"type": "integer",
"default": 0,
"minimum": 0
},
"search": {
"type": "string",
"maxLength": 200
}
}
}Check this account's native USDC invoice. Confirmation applies sending credits or activates prepaid domain hosting once, without a human checkout. Requires the same account's API key.
| Argument | Type | Description |
|---|---|---|
| token* | string |
{
"type": "object",
"required": [
"token"
],
"properties": {
"token": {
"type": "string"
}
},
"additionalProperties": false
}Read your sending state and current limits, including probation, pauses and pending review. Buying credits never overrides sending controls.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}With your operator's authorization, create a card checkout or native USDC invoice on Polygon, Base, Ethereum or Solana. Choose mail_credits ($1 buys 10,000 standard sends) or hosting at $1 per 30 days: domain_hosting for the first domain, domain_addon plus domainId for another verified domain under active primary hosting. This tool creates payment instructions; it does not transfer money. Reuse idempotencyKey on retries.
| Argument | Type | Description |
|---|---|---|
| kind | any | |
| chain | any | Legacy alias for method; omit when method is supplied. |
| method | any | |
| periods | integer | Hosting only: each period is 30 days for $1. Omit amountCents, or supply the exact 100 × periods. |
| domainId | string | Required only for domain_addon. Must be an owned additional domain with verified ownership. |
| amountCents | integer | |
| idempotencyKey* | string |
{
"type": "object",
"oneOf": [
{
"not": {
"anyOf": [
{
"required": [
"periods"
]
},
{
"required": [
"domainId"
]
}
]
},
"required": [
"amountCents"
],
"properties": {
"kind": {
"const": "mail_credits"
},
"amountCents": {
"enum": [
100,
500,
1000,
2500
]
}
}
},
{
"not": {
"required": [
"domainId"
]
},
"required": [
"kind"
],
"properties": {
"kind": {
"const": "domain_hosting"
},
"amountCents": {
"type": "integer",
"maximum": 1200,
"minimum": 100,
"multipleOf": 100
}
}
},
{
"required": [
"kind",
"domainId"
],
"properties": {
"kind": {
"const": "domain_addon"
},
"amountCents": {
"type": "integer",
"maximum": 1200,
"minimum": 100,
"multipleOf": 100
}
}
}
],
"required": [
"idempotencyKey"
],
"properties": {
"kind": {
"enum": [
"mail_credits",
"domain_hosting",
"domain_addon"
],
"default": "mail_credits"
},
"chain": {
"enum": [
"polygon",
"base",
"ethereum",
"solana"
],
"description": "Legacy alias for method; omit when method is supplied."
},
"method": {
"enum": [
"card",
"polygon",
"base",
"ethereum",
"solana"
],
"default": "polygon"
},
"periods": {
"type": "integer",
"default": 1,
"maximum": 12,
"minimum": 1,
"description": "Hosting only: each period is 30 days for $1. Omit amountCents, or supply the exact 100 × periods."
},
"domainId": {
"type": "string",
"format": "uuid",
"description": "Required only for domain_addon. Must be an owned additional domain with verified ownership."
},
"amountCents": {
"type": "integer",
"maximum": 2500,
"minimum": 100
},
"idempotencyKey": {
"type": "string",
"maxLength": 128,
"minLength": 1
}
},
"additionalProperties": false
}Read a message by its folder-scoped UID. Requires a Bearer API key.
| Argument | Type | Description |
|---|---|---|
| id* | string | |
| folder | string | |
| markAsRead | boolean | Full account keys default to true; limited keys require false or omission. |
| uidValidity | string | Mailbox identity from the list or webhook; mismatch returns 409 |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"pattern": "^[1-9][0-9]{0,9}$"
},
"folder": {
"type": "string",
"default": "INBOX"
},
"markAsRead": {
"type": "boolean",
"description": "Full account keys default to true; limited keys require false or omission."
},
"uidValidity": {
"type": "string",
"pattern": "^[1-9][0-9]{0,9}$",
"description": "Mailbox identity from the list or webhook; mismatch returns 409"
}
}
}Check a proposal. Human edits are private. Approved means authorized, not delivered; inspect submission.status.
| Argument | Type | Description |
|---|---|---|
| id* | string |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
}
},
"additionalProperties": false
}List only this draft-only key’s proposals and review statuses.
No arguments.
{
"type": "object",
"required": [],
"properties": {},
"additionalProperties": false
}Prepare a plain-text email for human approval. Requires a human-issued mail:draft key. Never sends. Reuse clientKey and content after uncertain responses.
| Argument | Type | Description |
|---|---|---|
| message* | object | |
| clientKey* | string |
{
"type": "object",
"required": [
"clientKey",
"message"
],
"properties": {
"message": {
"type": "object",
"required": [
"to",
"subject",
"body"
],
"properties": {
"cc": {
"type": "string"
},
"to": {
"type": "string"
},
"bcc": {
"type": "string"
},
"body": {
"type": "string",
"description": "Plain text, at most 1 MiB. HTML and encrypted proposals are not supported."
},
"from": {
"type": "string"
},
"mode": {
"enum": [
"new",
"reply",
"replyAll",
"forward"
]
},
"subject": {
"type": "string",
"maxLength": 998
},
"inReplyTo": {
"type": "string"
},
"references": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 20
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"filename",
"encoding",
"content"
],
"properties": {
"size": {
"type": "integer",
"readOnly": true
},
"content": {
"type": "string"
},
"encoding": {
"const": "base64"
},
"filename": {
"type": "string"
}
},
"additionalProperties": false
},
"maxItems": 20,
"description": "At most 8 MiB decoded total; inline bytes only."
}
},
"additionalProperties": false
},
"clientKey": {
"type": "string",
"format": "uuid"
}
},
"additionalProperties": false
}Create an agent mailbox and receive its key once. Starts with zero sending credits; receiving is available without payment.
| Argument | Type | Description |
|---|---|---|
| name | string | |
| agentId* | string |
{
"type": "object",
"required": [
"agentId"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100
},
"agentId": {
"type": "string",
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,63}$"
}
}
}Request an operator review of your sending purpose and recipient consent. Full account key required. Does not automatically increase limits or resume sending. Three requests per day; repeated pending requests keep the original purpose.
| Argument | Type | Description |
|---|---|---|
| purpose* | string | Sending purpose, expected volume and how recipients gave consent. No secrets or private messages. |
{
"type": "object",
"required": [
"purpose"
],
"properties": {
"purpose": {
"type": "string",
"maxLength": 1000,
"minLength": 40,
"description": "Sending purpose, expected volume and how recipients gave consent. No secrets or private messages."
}
},
"additionalProperties": false
}Submit mail with existing credits: one credit per accepted recipient. Requires a Bearer API key. Reuse idempotencyKey for retries; acceptance is not proof of remote delivery.
| Argument | Type | Description |
|---|---|---|
| cc | any | |
| to* | any | |
| bcc | any | |
| body | string | |
| from | any | Address or {email,name}. The email must be your authenticated mailbox or an active alias assigned to it, within the key's allowed senders. The display name changes only the visible From header. |
| html | string | |
| text | string | |
| headers | object | Only these two headers are accepted, case-insensitively. Duplicate names and control characters are rejected. The domain DKIM signature covers both; the sender application must implement the unsubscribe endpoint. |
| replyTo | any | |
| subject* | string |
Edit or withdraw this key’s pending proposal. Cannot approve or change a message after human editing.
| Argument | Type | Description |
|---|---|---|
| id* | string | |
| action* | any | |
| message | object | |
| revision* | integer | |
| contentHash* | string |
{
"type": "object",
"required": [
"id",
"action",
"revision",
"contentHash"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"action": {
"enum": [
"edit",
"withdraw"
]
},
"message": {
"type": "object",
"required": [
"to",
"subject",
"body"
],
"properties": {
"cc": {
"type": "string"
},
"to": {
"type": "string"
},
"bcc": {
"type": "string"
},
"body": {
"type": "string",
"description": "Plain text, at most 1 MiB. HTML and encrypted proposals are not supported."
},
"from": {
"type": "string"
},
"mode": {
"enum": [
"new",
"reply",
"replyAll",
"forward"
]
},
"subject": {
"type": "string",
"maxLength": 998
},
"inReplyTo": {
"type": "string"
},
"references": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 20
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"filename",
"encoding",
"content"
],
"properties": {
"size": {
"type": "integer",
"readOnly": true
},
"content": {
"type": "string"
},
"encoding": {
"const": "base64"
},
"filename": {
"type": "string"
}
},
"additionalProperties": false
},
"maxItems": 20,
"description": "At most 8 MiB decoded total; inline bytes only."
}
},
"additionalProperties": false
},
"revision": {
"type": "integer",
"minimum": 1
},
"contentHash": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 3, 2026.
Takes a password, API key or token as an argument, so the secret passes through the model's context and chat logs.
Fix: Read credentials from the server's own configuration (environment, OAuth) instead of a tool argument.
No readOnlyHint / destructiveHint annotations, so clients can't tell a read from a write without asking.
Fix: Add annotations to each tool, e.g. { readOnlyHint: true } for tools that only read.
| inReplyTo | string | Original RFC Message-ID, including angle brackets |
| references | array | Thread Message-IDs, at most 998 characters combined |
| attachments | array | Inline content only. Combined decoded attachment limit: 8 MB. |
| autoSubmitted | any |
| idempotencyKey | string |
{
"type": "object",
"anyOf": [
{
"required": [
"body"
]
},
{
"required": [
"text"
]
},
{
"required": [
"html"
]
}
],
"required": [
"to",
"subject"
],
"properties": {
"cc": {
"oneOf": [
{
"type": "string",
"description": "An email address or comma-separated addresses"
},
{
"type": "array",
"items": {
"type": "string",
"format": "email"
},
"maxItems": 50
}
]
},
"to": {
"oneOf": [
{
"type": "string",
"description": "An email address or comma-separated addresses"
},
{
"type": "array",
"items": {
"type": "string",
"format": "email"
},
"maxItems": 50
}
]
},
"bcc": {
"oneOf": [
{
"type": "string",
"description": "An email address or comma-separated addresses"
},
{
"type": "array",
"items": {
"type": "string",
"format": "email"
},
"maxItems": 50
}
]
},
"body": {
"type": "string"
},
"from": {
"oneOf": [
{
"type": "string",
"format": "email"
},
{
"type": "object",
"required": [
"email"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"description": "Display name without control characters"
},
"email": {
"type": "string",
"format": "email"
}
},
"additionalProperties": false
}
],
"description": "Address or {email,name}. The email must be your authenticated mailbox or an active alias assigned to it, within the key's allowed senders. The display name changes only the visible From header."
},
"html": {
"type": "string"
},
"text": {
"type": "string"
},
"headers": {
"type": "object",
"properties": {
"List-Unsubscribe": {
"type": "string",
"maxLength": 4096,
"description": "Angle-bracketed HTTPS or mailto URLs, separated by commas. One-click requires exactly one HTTPS URL that accepts an unauthenticated POST."
},
"List-Unsubscribe-Post": {
"const": "List-Unsubscribe=One-Click"
}
},
"description": "Only these two headers are accepted, case-insensitively. Duplicate names and control characters are rejected. The domain DKIM signature covers both; the sender application must implement the unsubscribe endpoint.",
"additionalProperties": false
},
"replyTo": {
"oneOf": [
{
"type": "string",
"description": "An email address or comma-separated addresses"
},
{
"type": "array",
"items": {
"type": "string",
"format": "email"
},
"maxItems": 50
}
]
},
"subject": {
"type": "string",
"pattern": "^[^\\r\\n]*$",
"maxLength": 998
},
"inReplyTo": {
"type": "string",
"maxLength": 254,
"description": "Original RFC Message-ID, including angle brackets"
},
"references": {
"type": "array",
"items": {
"type": "string",
"maxLength": 254
},
"maxItems": 20,
"description": "Thread Message-IDs, at most 998 characters combined"
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"filename",
"content"
],
"properties": {
"content": {
"type": "string"
},
"encoding": {
"enum": [
"base64",
"utf8"
],
"default": "utf8"
},
"filename": {
"type": "string",
"maxLength": 255
}
}
},
"maxItems": 20,
"description": "Inline content only. Combined decoded attachment limit: 8 MB."
},
"autoSubmitted": {
"const": "auto-replied"
},
"idempotencyKey": {
"type": "string",
"maxLength": 128,
"minLength": 1
}
},
"description": "At least one nonempty text or HTML body, up to 1 MB combined. At most 50 distinct recipients across To, Cc and Bcc."
}