Back to Directory/Developer Tools

io.github.loicfontaine-max/qorami

Check an email before an AI agent sends it: send / ask a human / block. Detects prompt injection.

Developer ToolsPythonv1.0.0

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.

PathWhat
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'.

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:

FrameworkInstallImport
LangChainpip install qorami[langchain]from qorami_langchain import build_qorami_tool
CrewAIpip install qorami[crewai]from qorami_crewai import QoramiEmailGuard
LlamaIndexpip install qorami[llamaindex]from qorami_llamaindex import build_qorami_tool
OpenAI Agents SDKpip 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.

Installation

Source-derived launch command. Check the maintainer’s required arguments and credentials before running:

bash
npx -y qorami-mcp

Set up in your AI client

Merge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.

json
{
  "mcpServers": {
    "io-github-loicfontaine-max-qorami": {
      "command": "npx",
      "args": [
        "-y",
        "qorami-mcp"
      ]
    }
  }
}

Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.

Claude Desktop setup reference

Package

qorami-mcpnpm

Compatible MCP Clients

io.github.loicfontaine-max/qorami works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.
  • Cursor~/.cursor/mcp.jsonRestart Cursor for changes to take effect.
  • VS Code.vscode/mcp.jsonReload VS Code window for changes to take effect.
  • Windsurf~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect.
  • Claude Code.mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.

Learn More