Back to the catalog

io.github.loicfontaine-max/qorami

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

Open source Open in the app JSON README (API)

About

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

Details

Kind
MCP servers
Topic
Communication
Publisher
loicfontaine-max
Origin
official
Category
ferramentas
Transport
local
Version
1.0.0
Stars
2
Last push
2026-07-03T09:40:52Z
Repository state
ativo
Language
Python
License
MIT
Added
2026-08-29 04:00:24
Updated
2026-08-29 04:00:24
Origin id
io.github.loicfontaine-max/qorami

README

# Qorami SDK

Official clients, tool schemas and an MCP server for [Qorami](https://qorami.fr) —
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](https://qorami.fr/dashboard/).
Full API reference: <https://qorami.fr/docs>.

| Path | What |
|---|---|
| [`js/`](js) | Zero-dependency JavaScript / TypeScript client (`fetch`, Node 18+ or browser). |
| [`python/`](python) | Zero-dependency Python client (stdlib only) + LangChain, CrewAI, LlamaIndex & OpenAI-Agents tools. |
| [`tools/`](tools) | Drop-in OpenAI function-calling & Anthropic tool-use schemas for `qorami_check_email`. |
| [`mcp/`](mcp) | Stdio MCP server (`qorami_health`, `verify_email`, `check_action_status`) for Claude Desktop, Cursor, any MCP client. |
| [`n8n-nodes-qorami/`](n8n-nodes-qorami) | **n8n community node** (`Settings → Community Nodes → n8n-nodes-qorami`) — guard an email, usable as an AI-Agent tool. |
| [`n8n/`](n8n) | No-code recipe: guard a workflow's email with a plain HTTP Request node (no install). |
| [`examples/`](examples) | Runnable Node & Python quickstarts. |

## JavaScript / TypeScript

```js
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

```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` |

```python
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/`](n8n).

## MCP server

Register Qorami as a native tool in Claude Desktop / Cursor / any MCP client —
see [`mcp/`](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:

```js
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
}
```

```python
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](LICENSE).

More