Dokumentasjon

Bygg på MCPEmails

Alt en MCP-klient gjør, kan et skript gjøre over vanlig HTTPS. Ett endepunkt, én API-nøkkel, JSON inn og JSON ut. Denne guiden dekker autentisering, de tre kallene du trenger, feil, nye forsøk, grenser og webhooks for ny e-post.

Endepunktet

Hver forespørsel er en JSON-RPC 2.0 POST til https://mcpemails.com/api/mcp. Dette er samme endepunkt som claude.ai, ChatGPT og andre MCP-klienter bruker, med de samme verktøyene og de samme tillatelsene, så et skript og en chatassistent ser ett og samme produkt.

  • Send Content-Type: application/json og Accept: application/json. Svaret er ett JSON-objekt.
  • Serveren holder ingen sesjon. Det er ingenting å åpne eller lukke, og hver forespørsel bærer sin egen Authorization-header.
  • Vellykkede verktøyresultater har et typet structuredContent-objekt, så du slipper å tolke prosa. De samme dataene ligger i content[0].text som en JSON-streng.

Autentisering

API-nøkler

  • Opprett en nøkkel i dashbordet under API-nøkler → Ny nøkkel. Gi den navn etter skriptet eller arbeidsflyten som skal bruke den.
  • En nøkkel er mcpe_ etterfulgt av 64 heksadesimale tegn. Den vises én gang, når du oppretter den, og bare en hash lagres. Kopier den da; en mistet nøkkel kan ikke gjenopprettes, bare erstattes.
  • Send den med hver forespørsel som Authorization: Bearer mcpe_.... Legg aldri en nøkkel i en URL eller en query-streng.
  • Alle planer kan opprette så mange nøkler de trenger. Bruk én nøkkel per skript eller arbeidsflyt, så kan du trekke tilbake én uten å røre de andre.
  • Å trekke tilbake en nøkkel på siden API-nøkler avslutter tilgangen umiddelbart.

Omfang

Hver nøkkel har bare de tillatelsene du huker av når du oppretter den. Du kan endre dem senere med Rediger tilgang, og endringen gjelder fra neste kall uten å koble til på nytt.

OmfangTillater
read:emailListe, lese og søke i meldinger, laste ned vedlegg, liste innbokser og mapper.
search:emailBeholdt for eldre nøkler. Søk dekkes av read:email.
send:emailSende, svare og videresende.
manage:draftsOpprette, oppdatere og slette utkast. Å sende et utkast krever også send:email.
manage:foldersFlytte, kopiere, flagge og arkivere meldinger; opprette, gi nytt navn til og slette mapper.
delete:emailSlette og masseslette meldinger.
manage:contactsSøke etter kontakter i nylig e-post.
schedule:emailPlanlegge sendinger og håndtere planlagte e-poster.
manage:automationsOpprette regler som kjører etter en tidsplan uten at noen følger med.

Start med read:email og legg til et skriveomfang bare når arbeidsflyten trenger det. Et kall utenfor nøkkelens omfang avvises før vi kontakter e-postserveren din. Lesere i arbeidsområdet kan bare ha leseomfang.

Innbokstilgang

En nøkkel når som standard alle innbokser i arbeidsområdet. For å låse den til noen av dem, åpne Rediger tilgang på nøkkelen og velg innboksene under Innbokstilgang. Begrensningen sjekkes på hvert kall, så en nøkkel låst til support-innboksen kan ikke lese økonomi-innboksen, uansett hva forespørselen sier.

OAuth for koblingsapper

Apper som folk kobler til selv, som claude.ai, ChatGPT og andre MCP-klienter, logger inn med OAuth i stedet for en nøkkel: dynamisk klientregistrering, autorisasjonskode med PKCE og en samtykkeskjerm der brukeren velger omfang og innbokser. Se OAuth-tilkobling. For dine egne skript, servere og arbeidsflyter er en API-nøkkel enklere.

De tre kallene

1. initialize (valgfritt)

MCP-klienter starter med initialize. Et skript kan hoppe over det, siden serveren ikke holder noen sesjon, men det er en billig måte å sjekke at nøkkelen virker og lese serverens instruksjoner.

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "clientInfo": { "name": "my-agent", "version": "1.0" },
      "capabilities": {}
    }
  }'

2. tools/list

tools/list returnerer alle verktøyene denne nøkkelen kan kalle, med beskrivelse, inndataskjema og utdataskjema. Les den ved oppstart i stedet for å hardkode verktøynavn eller argumenter: listen filtreres etter nøkkelens omfang, og verktøy får nye argumenter over tid.

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'

3. tools/call

Kall et verktøy ved navn med argumentene. De fleste verktøy tar en action som bestemmer hva de gjør, som list, read eller search på email_read. Oppgi postboksen med inbox (adressen) eller inbox_id; inbox_list returnerer begge.

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "email_read",
      "arguments": { "action": "list", "inbox": "you@example.com", "unread": true, "limit": 20 }
    }
  }'

Et vellykket resultat:

JSON
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [{ "type": "text", "text": "{\"messages\":[...],\"total\":42, ...}" }],
    "structuredContent": {
      "messages": [{ "id": "...", "subject": "...", "from": { "name": "...", "email": "..." } }],
      "total": 42,
      "total_is_estimate": false,
      "has_more": true,
      "next_offset": 20
    }
  }
}

Verktøyreferansen beskriver hvert verktøy, og curl-guiden har flere eksempler.

Feil

Det finnes to typer. En forespørsel som ikke kunne kjøre i det hele tatt kommer tilbake som en JSON-RPC error med en HTTP-status. En forespørsel som nådde et verktøy og ble avvist av det kommer tilbake som et vanlig result med isError: true, slik at en AI-modell kan lese årsaken. Forgren på data.error_code eller _meta-koden, ikke på meldingsteksten.

SvarNårHva du gjør
HTTP 401, -32001Manglende, feilformet, tilbakekalt eller utløpt nøkkel.Rett Authorization-headeren eller opprett en ny nøkkel. Nye forsøk hjelper ikke.
HTTP 403, -32004, insufficient_scopeNøkkelen mangler et omfang denne verktøyhandlingen krever. data.required_scopes lister hva som ville tillatt den.Legg til omfanget med Rediger tilgang, eller bruk en annen nøkkel.
HTTP 429, -32003, rate_limit_exceededFor mange forespørsler. data.window sier hvilket vindu som ble fullt.Vent Retry-After sekunder (også i data.retry_after), og send så samme forespørsel på nytt.
-32602Ukjent verktøynavn. data.available_tools lister navnene denne nøkkelen kan kalle.Bruk et navn fra tools/list.
isError: true, invalid_argumentsArgumentene besto ikke verktøyets skjema. Ingenting kjørte. Teksten navngir hvert ugyldige argument, og når et argumentnavn var gjettet, navngir den det som finnes.Rett argumentene. De samme argumentene avvises på samme måte.
isError: true, usage_limit_reachedEt Gratis-arbeidsområde har brukt opp månedens e-posthandlinger.Vent til tilbakestillingsdatoen i _meta, eller oppgrader. Betalte planer har ingen månedlig grense.
isError: true, annetVerktøyet kjørte og feilet: melding ikke funnet, leverandøren avviste, ugyldig mottaker og så videre.Les content[0].text. Den sier hva som skjedde og om noe ble sendt.
HTTP
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope", ...

{
  "jsonrpc": "2.0",
  "id": 4,
  "error": {
    "code": -32004,
    "message": "Insufficient scope: the 'send:email' scope is required to call email_compose.",
    "data": { "error_code": "insufficient_scope", "required_scopes": ["send:email"], ... }
  }
}
HTTP
HTTP/1.1 429 Too Many Requests
Retry-After: 12

{
  "jsonrpc": "2.0",
  "id": 5,
  "error": {
    "code": -32003,
    "message": "Rate limit exceeded",
    "data": { "error_code": "rate_limit_exceeded", "window": "per_minute", "retry_after": 12, ... }
  }
}
JSON
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "isError": true,
    "content": [{ "type": "text", "text": "Invalid arguments for email_read. The call was rejected before it ran, ..." }],
    "_meta": {
      "com.mcpemails/invalid_arguments": {
        "error_code": "invalid_arguments",
        "retryable": false,
        "errors": [{ "path": "arguments.since", "message": "..." }]
      }
    }
  }
}

Paginering

Hvert liste- og søkeresultat slutter med de samme fire feltene:

  • has_more: true når det finnes en side til. Bare has_more: false betyr at du har sett alt.
  • next_offset: send den tilbake som offset, med alle andre argumenter uendret, for å få neste side. Den er null når has_more er false.
  • total: antall treff, eller null når leverandøren ikke kan telle dem. Den motsier aldri siden du holder.
  • total_is_estimate: true når total er et estimat eller et minimum og ikke et nøyaktig antall.

Lange meldingstekster deles opp på samme måte: når body_truncated er true, les igjen med body_next_offset som body_offset.

Nye forsøk og idempotensnøkler

En tilkobling som brytes etter en sending lar deg ikke vite om e-posten gikk ut. Send med en idempotency_key og prøv igjen med samme nøkkel: arbeidet kjører én gang.

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 7,
    "method": "tools/call",
    "params": {
      "name": "email_compose",
      "arguments": {
        "action": "send",
        "inbox": "you@example.com",
        "to": ["customer@example.com"],
        "subject": "Your order has shipped",
        "body": "Hi, your order is on its way.",
        "idempotency_key": "order-1042-shipped"
      }
    }
  }'
  • Godtas på sendinger, svar, videresendinger, planlagte sendinger, utkastskriving og postboksendringer som flytting, flagging og sletting. tools/list viser idempotency_key i inndataskjemaet til hvert verktøy som tar den.
  • Opptil 200 tegn. Bruk noe fra ditt eget system, som et ordrenummer og et hendelsesnavn.
  • Nøklene er knyttet til API-nøkkelen som sendte dem, og huskes i 24 timer.
  • Et nytt forsøk med samme nøkkel og samme argumenter kjører ikke igjen. Det returnerer idempotent_replay: true, den opprinnelige status og det opprinnelige utfallet i result, inkludert message_id du kan ha mistet.
  • Samme nøkkel med andre argumenter avvises med idempotency_key_conflict. Bruk en ny nøkkel for en ny operasjon.
  • Et nytt forsøk mens det første kallet fortsatt kjører returnerer status: "processing". Prøv igjen om kort tid.
  • Når e-postleverandøren avviste en sending før den ble godtatt, ble ingenting sendt og nøkkelen frigis, så det identiske nye forsøket sender faktisk.
  • Når utfallet er usikkert, sier gjentakelsen status: "unknown". Sjekk Sendt før du sender igjen under en ny nøkkel.
JSON
{
  "idempotency_key": "order-1042-shipped",
  "idempotent_replay": true,
  "status": "succeeded",
  "result": { "message_id": "...", "inbox_id": "...", "status": "sent" },
  "message": "This logical request was already processed. ..."
}

Godkjenning av sending

Enhver innboks kan holde tilbake alle sendinger til en person godkjenner dem. En sending fra skriptet ditt returnerer da en approval_id med status: "pending_approval" i stedet for å gå ut, og den går ut når noen godkjenner den i dashbordet. Dette fungerer på alle planer og er et godt utgangspunkt mens en ny automatisering beviser seg. Et nytt forsøk med samme idempotency_key rapporterer godkjenningen i stedet for å opprette en ny.

Hastighetsgrenser

Hver plan har et tak per minutt for hele arbeidsområdet. En enkelt nøkkel kan bruke hele planens grense per minutt; flere nøkler deler den.

PlanForespørsler per minuttWebhooks
Free60Nei
Personal120Nei
Pro300Ja
Business1 000Ja
  • tools/call-svar har RateLimit-Limit, RateLimit-Remaining og RateLimit-Reset (i sekunder) for det vinduet som er nærmest fullt, så en klient kan regulere tempoet før den treffer grensen.
  • Hver nøkkel har også time- og døgnvinduer. En 429 navngir vinduet som ble fullt i data.window.
  • En 429 har Retry-After i sekunder. Vent så lenge, og send så samme forespørsel på nytt.
  • Gratis inkluderer en månedlig kvote med e-posthandlinger. Betalte planer har ingen månedlig grense og ingen kostnad per kall.

Webhooks for ny e-post

På Pro og Business kan MCPEmails sende en POST til din URL når e-post kommer inn i en innboks, så en arbeidsflyt starter på ny e-post i stedet for å polle. Opprett et endepunkt i dashbordet, velg innboksene og kopier signeringsnøkkelen, som vises én gang. URL-en må være HTTPS, på port 443 eller 8443. Bruk testknappen til å sende en signert ping-hendelse.

Hendelsen

HTTP
POST /your/webhook HTTP/1.1
Content-Type: application/json
MCPEmails-Event-Id: evt_...
MCPEmails-Event-Type: message.received
MCPEmails-Signature: t=1792843200,v1=5f2b...

{
  "id": "evt_...",
  "type": "message.received",
  "created_at": "2026-10-24T09:20:00.000Z",
  "workspace_id": "...",
  "inbox_id": "...",
  "folder": "INBOX",
  "count": 1,
  "message_ids": ["..."]
}
  • type er message.received. message_ids lister de nye meldingene i innboksens INBOX-mappe, opptil 10 per hendelse; count er hvor mange som kom, og kan være flere.
  • Som standard inneholder nyttelasten bare id-er, ikke innhold. Et endepunkt satt til å inkludere headere får også en messages-liste med id, from og subject for hver melding.
  • Hent meldingen med email_read (action: "read", inbox_id og en message_id) med en API-nøkkel. Nøkkelens omfang og innbokstilgang gjelder som vanlig.
  • Levering skjer vanligvis innen rundt to minutter etter at meldingen kom. Innbokser sjekkes etter en tidsplan, så dette er ikke umiddelbart.

Verifiser signaturen

Hver levering har MCPEmails-Signature: t=<unix-sekunder>,v1=<hex>, der v1 er HMAC-SHA256 av tidsstempelet, et punktum og den rå forespørselskroppen, med endepunktets hemmelighet som nøkkel. Nøkkelen er hele hemmeligheten slik den vises, whsec_-prefikset inkludert. Beregn signaturen på nytt over den rå kroppen, sammenlign i konstant tid, og avvis et tidsstempel som er mer enn fem minutter gammelt.

JavaScript
import crypto from 'node:crypto';

// rawBody: the request body exactly as received, before JSON.parse.
export function verifyMcpemailsSignature(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    String(header ?? '').split(',').map((part) => part.trim().split('=')),
  );
  const timestamp = Number(parts.t);
  if (!Number.isFinite(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest();
  const received = Buffer.from(parts.v1 ?? '', 'hex');
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}

Nye forsøk

  • Svar med en hvilken som helst 2xx-status innen 10 sekunder. Alt annet regnes som en feil, inkludert en omdirigering, som ikke følges.
  • En mislykket levering prøves igjen etter 1 minutt, 5 minutter, 30 minutter, 2 timer, 6 timer og 24 timer. Hvert nytt forsøk signeres på nytt med et ferskt tidsstempel.
  • Et endepunkt som har feilet i 24 timer, eller 50 ganger på rad, deaktiveres, og eieren av arbeidsområdet får beskjed på e-post. Du kan slå det på igjen fra dashbordet.
  • Bruk MCPEmails-Event-Id til å ignorere en levering du allerede har behandlet. Et nytt forsøk har samme hendelses-id.

Oppskrifter

n8n: kjør en arbeidsflyt på ny e-post

  • Legg til en Webhook-triggernode med HTTP-metode POST, og registrer produksjons-URL-en som et webhook-endepunkt i MCPEmails-dashbordet.
  • Legg til en HTTP Request-node: metode POST, URL https://mcpemails.com/api/mcp, autentisering Generic Credential Type → Header Auth med navn Authorization og verdi Bearer mcpe_....
  • Slå på Send Body, velg JSON, og bruk kroppen nedenfor til å lese den nye meldingen. De neste nodene får meldingen i result.structuredContent.
  • For å sjekke signaturen i n8n, aktiver Raw Body på Webhook-noden og kjør verifiseringen over i en Code-node. På selvdriftet n8n, tillat crypto-modulen med NODE_FUNCTION_ALLOW_BUILTIN=crypto.
JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "email_read",
    "arguments": {
      "action": "read",
      "inbox_id": "{{ $json.body.inbox_id }}",
      "message_id": "{{ $json.body.message_ids[0] }}"
    }
  }
}

For en AI Agent-node som leser og sender e-post selv, se n8n-guiden.

Claude Code

Legg til serveren med en nøkkel i en header. Det passer for hodeløse maskiner og CI, der det ikke finnes noen nettleser for OAuth-innloggingen:

bash
claude mcp add --transport http mcpemails https://mcpemails.com/api/mcp \
  --header "Authorization: Bearer $MCPEMAILS_KEY"

Claude Code-guiden dekker OAuth-innloggingen og valget av omfang.

Et kort Node-skript

Lister alle uleste meldinger i én innboks, side for side, og venter ut en 429:

JavaScript
// node agent.mjs  (Node 18 or later, MCPEMAILS_KEY in the environment)
const ENDPOINT = 'https://mcpemails.com/api/mcp';
let nextId = 1;

async function callTool(name, args) {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.MCPEMAILS_KEY}`,
      'Content-Type': 'application/json',
      Accept: 'application/json',
    },
    body: JSON.stringify({ jsonrpc: '2.0', id: nextId++, method: 'tools/call', params: { name, arguments: args } }),
  });
  if (res.status === 429) {
    const wait = Number(res.headers.get('Retry-After') ?? 1);
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
    return callTool(name, args);
  }
  const reply = await res.json();
  if (reply.error) throw new Error(`${reply.error.code}: ${reply.error.message}`);
  if (reply.result.isError) throw new Error(reply.result.content[0].text);
  return reply.result.structuredContent;
}

const inbox = 'you@example.com';
let offset = 0;
do {
  const page = await callTool('email_read', { action: 'list', inbox, unread: true, limit: 50, offset });
  for (const m of page.messages) console.log(m.id, m.from?.email, m.subject);
  offset = page.has_more ? page.next_offset : null;
} while (offset !== null);

OpenClaw

OpenClaw logger inn med OAuth som standard; OpenClaw-guiden går gjennom det. For å bruke en avgrenset nøkkel i stedet, legg den i serveroppføringens headers-map og la auth stå tom, fordi OpenClaw ignorerer en statisk Authorization-header på en oppføring satt til OAuth.

JSON
{
  "mcp": {
    "servers": {
      "mcpemails": {
        "url": "https://mcpemails.com/api/mcp",
        "transport": "streamable-http",
        "headers": { "Authorization": "Bearer mcpe_YOUR_KEY_HERE" }
      }
    }
  }
}

Start med én innboks, gratis

Opprett en nøkkel, kall tools/list, og se din egen e-post komme tilbake som JSON.