Skip to main content
Glama
loicfontaine-max

qorami-mcp

Qorami SDK

Official clients, tool schemas and an MCP server for Qorami — a control point between your AI agents and actually sending email. Before each send, the agent asks Qorami, which replies send, request_human_confirmation, or do_not_send.

Get an API key in the dashboard. Full API reference: https://qorami.fr/docs.

Path

What

js/

Zero-dependency JavaScript / TypeScript client (fetch, Node 18+ or browser).

python/

Zero-dependency Python client (stdlib only) + LangChain, CrewAI, LlamaIndex & OpenAI-Agents tools.

tools/

Drop-in OpenAI function-calling & Anthropic tool-use schemas for qorami_check_email.

mcp/

Stdio MCP server (qorami_health, verify_email, check_action_status) for Claude Desktop, Cursor, any MCP client.

n8n-nodes-qorami/

n8n community node (Settings → Community Nodes → n8n-nodes-qorami) — guard an email, usable as an AI-Agent tool.

n8n/

No-code recipe: guard a workflow's email with a plain HTTP Request node (no install).

examples/

Runnable Node & Python quickstarts.

JavaScript / TypeScript

import { QoramiClient } from './js/qorami.mjs'

const qorami = new QoramiClient({ apiKey: process.env.QORAMI_API_KEY })

await qorami.guard(
  { recipient: 'client@example.com', subject: 'Our offer', body, policyProfile: 'sales' },
  {
    send: () => mailer.send(),                            // allowed
    requestHumanConfirmation: (r) => queue(r.action.id), // a human was notified
    doNotSend: (r) => log('blocked', r.decision),        // do not send
  },
)

Or step by step with qorami.verify(...) and, after a review, poll qorami.status(actionId) until nextAction.type === 'send'.

Related MCP server: Agent Prompt Injection Firewall MCP

Python

from qorami import QoramiClient
qorami = QoramiClient(api_key=os.environ["QORAMI_API_KEY"])

result = qorami.verify(recipient="client@example.com", subject="Our offer",
                       body=email_body, policy_profile="sales")
if result.next_action_type == "send":
    send_email()
elif result.next_action_type == "request_human_confirmation":
    queue_for_review(result.action_id)   # a human was notified by email
# else: do_not_send

Agent framework tools

pip install qorami[<framework>] ships a drop-in qorami_check_email wrapper — each returns ALLOWED / NEEDS HUMAN APPROVAL / BLOCKED and reuses the client:

Framework

Install

Import

LangChain

pip install qorami[langchain]

from qorami_langchain import build_qorami_tool

CrewAI

pip install qorami[crewai]

from qorami_crewai import QoramiEmailGuard

LlamaIndex

pip install qorami[llamaindex]

from qorami_llamaindex import build_qorami_tool

OpenAI Agents SDK

pip install qorami[openai-agents]

from qorami_openai_agents import qorami_check_email

from qorami_langchain import build_qorami_tool
tool = build_qorami_tool()        # reads QORAMI_API_KEY

No-code workflows (n8n) use a plain HTTP Request node — see n8n/.

MCP server

Register Qorami as a native tool in Claude Desktop / Cursor / any MCP client — see mcp/. It exposes qorami_health, verify_email and check_action_status over stdio.

The contract

Every client returns the same decision the agent must obey via nextAction.type: send, request_human_confirmation (a human approves first — poll the action), or do_not_send. See https://qorami.fr/docs.

Cleaned version (auto-remediation)

When an email is risky only because of mechanically-removable content (a leaked secret, a suspicious link, an IBAN/card/SSN), the verify result carries a cleaned, sendable copy — send remediation.safeBody instead of blocking outright:

const r = await qorami.verify({ recipient, subject, body, policyProfile: 'general' })
if (r.nextAction.type === 'do_not_send' && r.remediation?.safeToSend) {
  mailer.send({ ...email, body: r.remediation.safeBody })   // safe, redacted copy
}
r = qorami.verify(recipient=..., subject=..., body=email_body)
if r.next_action_type == "do_not_send" and (r.remediation or {}).get("safeToSend"):
    send_email(body=r.remediation["safeBody"])   # safe, redacted copy

remediation.removed lists what was stripped (e.g. ["secret", "link"]). The MCP server surfaces the same field.

License

MIT — see LICENSE.

Available Tools

2 tools
check_action_statusA

After request_human_confirmation, poll this with the actionId until nextAction.type becomes "send" (approved) or "do_not_send" (blocked).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionIdYesThe action id returned by verify_email

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Describes polling behavior and termination conditions without annotations; no side effects noted but read-only implied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence front-loaded with usage context, every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a simple polling tool with one parameter and no output schema; clearly explains termination condition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already defines actionId well; description only references it ('poll this with the actionId'), adding no extra semantic depth.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description specifies polling an actionId until a terminal state ('send' or 'do_not_send') is reached, clearly distinguishing from sibling tool verify_email.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states 'After request_human_confirmation, poll this' and outlines expected outcomes, though lacks explicit when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_emailA

Before sending ANY email, call this to get permission from Qorami. Returns a decision the agent MUST obey: send (allowed), request_human_confirmation (a human must approve first — then poll check_action_status), or do_not_send (blocked). When not allowed, "suggestions" says what to fix.

ParametersJSON Schema
NameRequiredDescriptionDefault
recipientYesRecipient email address
subjectYesEmail subject
bodyYesFull email body
policyProfileNoRisk profile (default general)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It details the decision outcomes and the 'suggestions' field for fixes. However, it does not disclose whether the tool has side effects (e.g., logging) or authorization requirements, leaving some behavior opaque.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise at two sentences, front-loaded with the most critical usage instruction. Every part is necessary and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the absence of an output schema, the description explains the key return values and their meanings. A decision tool with multiple outcomes is adequately covered, though it could mention the format of 'suggestions' or any error conditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the parameters are well-documented in the schema. The description does not add any extra semantics beyond what the schema provides. The baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: to get permission before sending emails. It specifies the three possible return values (send, request_human_confirmation, do_not_send) and how the agent must obey. This distinguishes it from the sibling tool check_action_status, which is referenced for polling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to call this tool 'before sending ANY email', providing clear usage guidance. It also tells the agent what to do based on the response: obey the decision, and if not allowed, use suggestions to fix. It references the sibling tool for following up on human confirmation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.0.0
    • First observedcheck_action_status
    • First observedverify_email

TDQS

A4.4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: verify_email handles the initial permission check, and check_action_status polls the result of a human confirmation request. There is no overlap.

Naming Consistency5/5

Both tool names follow the verb_noun pattern (verify_email, check_action_status) and use snake_case consistently.

Tool Count3/5

With only 2 tools, the set is on the thin side for a standalone MCP server, but it covers the core email verification workflow without unnecessary additions.

Completeness5/5

The tools cover the entire permission lifecycle: initial decision via verify_email and subsequent polling for human confirmation via check_action_status. No obvious gaps for the intended domain.

Maintenance

ActivityStale
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    A pre-action risk gate for AI agents. Your agent calls the forecast tool before any irreversible action — send email, run SQL, make a payment, delete a file — and gets a risk score (0–100) and a GO / CONFIRM / STOP verdict in a few seconds.
    1
    111 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Human-in-the-loop approval inbox for AI agents: an agent proposes an action (send email, post comment, run a command), a human approves, rejects, or edits it from a web, mobile, or Slack/Discord/Telegram inbox, and the agent only runs on approval. Full audit trail, self-hostable (MIT).
    8
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to send and receive email with enforced security policies, scoped mailboxes, and human approval for external sending.
    1
    MIT