
Security News
arXiv Is Rate Limiting Authors Following a Flood of AI Slop Submissions
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.
replylayer-mcp
Advanced tools
The MCP server for ReplyLayer — safe email for AI agents. It exposes ReplyLayer's email surface (send, reply, read, monitor, release) as MCP tools so an MCP client (Claude Desktop, Cursor, …) can drive transactional and operational email with built-in security scanning. Not a bulk or marketing tool.
Server identity: replylayer v0.15.1. 44 tools. The hosted server
(POST /v1/mcp on api.replylayer.ai) reports the same identity and injects the
same server-level workflow primer as this binary — both read the version from this
package, so neither can drift from it. The hosted sign-in endpoint
(POST /v1/mcp/oauth) lists all of them except the four in
AGENT_UNAVAILABLE_TOOL_NAMES: a sign-in connection is an agent key, which can never
use those four, and its primer describes the connection instead of an API key. Its
tools also carry OAuth linking metadata (securitySchemes, top-level and in _meta, and
_meta["mcp/www_authenticate"] on a tool error caused by a revoked or expired token).
Published to npm as replylayer-mcp. Most MCP clients launch it via npx (no
global install needed) — see Client config. To run or
install it directly:
npx -y replylayer-mcp # or: npm install -g replylayer-mcp
Auth is a single ReplyLayer API key. The server resolves it from the
REPLYLAYER_API_KEY environment variable first, then from the stored credentials file
at ~/.replylayer/credentials. Production (https://api.replylayer.ai) is the default
endpoint; REPLYLAYER_API_URL is a testing-only override.
Set up the stored credential interactively (writes ~/.replylayer/credentials,
mode 0600):
replylayer-mcp init # or, without a global install: npx -y replylayer-mcp init
For CI / automation, skip init and pass REPLYLAYER_API_KEY in the environment.
A key only works once a human has finished the account's one-time signup verification:
confirming the account's email address and then its mobile number (a 6-digit SMS code, texted once the email is verified).
Web signup at https://app.replylayer.ai/signup walks through both before any key is
created. A key returned by rly signup stays inert until rly auth verify and
rly auth verify-phone succeed; until then calls fail with EMAIL_NOT_VERIFIED or
PHONE_NOT_VERIFIED. The server runs with a key a human has already provisioned and
verified.
Claude Desktop (claude_desktop_config.json) or Cursor (mcpServers) — launch via
npx so there's no global install or absolute path to manage:
{
"mcpServers": {
"replylayer": {
"command": "npx",
"args": ["-y", "replylayer-mcp"],
"env": {
"REPLYLAYER_API_KEY": "rly_live_k3m9p2qx7vn4hjd0.uZ8Qb1vK3mN0pR7sT2wX9yA4cF6gH8jL1nP3rT5vW7z"
}
}
}
}
If you ran replylayer-mcp init to store the key, the env block is optional. With a
global install (npm i -g replylayer-mcp), use "command": "replylayer-mcp" and drop
the args.
Every message is security-scanned, and scanning is directional:
The send tools (send_email, reply_to_message, send_draft) return an outcome —
branch on the outcome, not on success/failure. The discriminator is
email_effect.effect_status: sent | held_for_review | held_infrastructure | blocked
(the Governed Email Effect contract). Treat an
effect_status you do not recognize as held, never as sent. Where email_effect is
absent, fall back to the top-level status: sent | quarantined | pending_review | blocked. sent means ReplyLayer accepted the message for sending — it is not proof
the recipient received it.
Those send responses also carry the why inline: scan (the scanner
verdict — inspect scan.verdict, scan.findings, and scan.findings[].agent_instructions)
and hold_context (the hold reason plus agent_instructions on held sends — a typed
policy cause, a policy change to the scanner's decision, or a genuine scan-explained
hold; null on sent/terminal outcomes and normally on infrastructure holds). A held
send's hold_context.review_url is the dashboard page where the account owner approves
or releases it (omitted when the server has no public dashboard URL); a held result
leads with a HELD FOR REVIEW — not sent / HELD — not sent line telling the agent to
tell the account owner (the person the agent acts for) where it waits — and by when, from
hold_context.review_expires_at — and not to send it again. An infrastructure hold gets
neither the link nor that line (retry later instead). Call
read_message for full detail. A finding with
failure_class: "inference_error" is an infrastructure error, not a content judgment —
retry later, do not rewrite.
Recovery: inbound quarantined → release_quarantined_message; firewall_blocked →
release_firewall_blocked_message; pending_review needs the account owner's approval
in the dashboard (agent keys cannot approve — tell the account owner where, do not resend). RATE_LIMITED → if details.reason is
failed_authentication, the API key is wrong or revoked: stop and ask a human to fix the
key, do not retry; if details.reset_at is present it is the daily send quota (back off
until then); otherwise it is a short-window limit — wait for details.retry_after (or
the time in the error message), then retry. UNAUTHORIZED / API_KEY_REVOKED → the key
is wrong or revoked: stop and ask a human, do not retry.
RECIPIENT_SUPPRESSED / BILLING_* / EMAIL_NOT_VERIFIED → escalate, do not retry.
This server does no implicit retry (neither on 5xx nor on a 429 Retry-After):
every tool call fails fast and returns the structured error, so the agent owns retry
timing and a tool call is never held open by a silent server-side wait.
send_email and reply_to_message take an optional idempotency_key. Pick one stable
key per send or reply intent and reuse that exact key for every retry of that intent: a
replay returns the original outcome instead of sending a second message. The record is
permanent. On IDEMPOTENT_REQUEST_IN_FLIGHT, retry the same key after the indicated
delay. On IDEMPOTENT_REQUEST_NOT_PROVEN_SENT, stop and report it for investigation —
the message was not re-sent, and minting a new key could duplicate it.
create_draft's idempotency_key is a different thing: it is valid only alongside
send_at (scheduled sends) and replays for 24 h, not permanently.
By default every inbound read carries the standing untrusted-content contract:
agent_safety_context.untrusted_content: true plus a guidance string telling the
agent not to follow instructions embedded in the message body. Relaxing that on a given
read is entirely server-side and operator-configured — this server has no client-side
opt-in or env var for it. The server relaxes a read only when the customer has (a) put
the mailbox into instruction_trust_mode: 'enabled', (b) enabled this API key's
instruction-trust capability, and (c) designated that exact sender address (address-grain
only — no domain-wide trust) as a trusted instruction source, and the message itself
is verified_aligned (Mailgun-verified domain authenticity), clean-scanning, and
available from that sender. When all of that lines up, guidance is replaced with
trusted-instruction guidance (the agent may act on
that verified sender's own explicit requests in this message) and a thin
instruction_trust basis object is attached — untrusted_content stays true. This is
read-relaxation only: it never changes how an outbound send is gated.
Default is off end to end: no operator configuration → no relaxation → byte-identical legacy reads. There is currently no MCP tool to grant, list, or revoke trusted sources — see the note at the end of Tool surface.
Reads (no side effects): list_messages (search + filters + paging), read_message,
get_thread, list_threads, wait_for_message,
list_mailboxes, list_recipients, list_suppressions, list_allowlist,
list_allowlist_blocked_attempts, list_drafts, get_draft, list_inbound_blocklist,
list_inbound_allowlist, list_inbound_firewall_blocked_attempts, get_account_usage,
get_agent_quota, get_attachment_preview, get_link_scanning_status.
get_link_scanning_status reports whether malicious link scanning (URL reputation, backed by
Google Web Risk) is active for the account. Turning it on is an admin action (it enables an
account-wide sub-processor data flow), so the MCP surface is read-only here — enable it from the
dashboard, the SDK, or rly account link-scanning enable.
Sends (dispatch outbound mail): send_email, reply_to_message, send_draft.
Structured results. Every tool except remove_suppression (which always returns an
error) declares an outputSchema and returns structuredContent — a typed object you can
consume without re-parsing the text blob — alongside the text block, on every transport.
The text block is the same JSON. Each schema follows the API route's response schema and
describes the result after the fields the tool leaves out (see
Tool notes): objects accept fields the API adds later, enum-like values are
plain strings, and only the top-level fields the route always returns are required. A
tool error (isError: true) carries no structuredContent, except a blocked or
infrastructure-held send, which keeps its send result.
Drafts: create_draft, update_draft, delete_draft (plus send_draft above).
Inbound triage: release_quarantined_message, block_quarantined_message,
report_and_block (block + blocklist the sender, inbound-only),
release_firewall_blocked_message. Human-in-the-loop (admin-only; agent keys 403):
approve_review, deny_review.
Delete: delete_message — soft-deletes a message (any direction) and purges its
raw MIME; agent keys require the account delete policy to be enabled (else 403).
Policy / contacts: add_recipient, add_suppression, add_inbound_blocklist,
add_inbound_allowlist_entry, mark_message_read, mark_thread_read.
Star / unstar: star_message (toggle a message's starred flag),
star_thread (toggle a thread's starred flag).
Bulk policy mutations: add_inbound_allowlist_bulk (up to 1000 sender addresses for a
mailbox's inbound allowlist in one call), add_suppressions_bulk (up to 1000 addresses to
the account-wide do-not-contact list), add_inbound_blocklist_bulk (up to 1000 addresses
to the account-wide inbound blocklist).
Policy stub (intentionally unavailable): remove_suppression — always returns an
isError result explaining that suppression removal is a per-human admin decision; use
rly suppressions remove, an SDK admin key, or the dashboard instead.
Not yet a tool: trusted-instruction-source management (grant / list / revoke, plus the mailbox mode and per-key capability toggles — see above) has no MCP wrapper today. That includes the revoke endpoint, which — like the inbound-triage release tools — is unprivileged and agent-key-callable server-side; it just isn't exposed here yet. Manage trusted sources from the ReplyLayer dashboard (or the REST API directly) in the meantime.
Every tool declares a title (mirrored in annotations.title, which Anthropic's directory reads) and explicit boolean readOnlyHint, destructiveHint
and openWorldHint; every tool that changes something also declares idempotentHint.
One tools/list serves every client, so where client guidelines differ the stricter
reading wins. The hints are advisory for the host. The API enforces the permission gates.
| Group | Tools | read-only | destructive | open-world | idempotent |
|---|---|---|---|---|---|
| Reads | the 19 read tools listed above | true | false | false | not declared |
| Sends | send_email, reply_to_message, send_draft, approve_review | false | true | true | false |
| Scheduled sends | create_draft, update_draft (a send_at dispatches with no further call) | false | true | true | false |
| Irreversible state changes | deny_review, block_quarantined_message, release_quarantined_message, release_firewall_blocked_message | false | true | false | false |
| Draft delete | delete_draft (deleting a scheduled draft sends a message.schedule_cancelled webhook to the account's own endpoint) | false | true | true | false |
| Irreversible, safe to repeat | delete_message (a re-delete succeeds), report_and_block (a re-report changes nothing further) | false | true | false | true |
| List and marker writes | add_suppression, add_suppressions_bulk, add_inbound_blocklist, add_inbound_blocklist_bulk, add_inbound_allowlist_entry, add_inbound_allowlist_bulk, mark_message_read, mark_thread_read, star_message, star_thread | false | true | false | true |
| Recipient write | add_recipient (emails the recipient a confirmation link; with attest, sends nothing but makes the person sendable) | false | true | true | false |
| Stub | remove_suppression (always an error) | true | false | false | not declared |
add_recipient — wraps POST /v1/recipients (free Sandbox accounts only; other
tiers get 403 FORBIDDEN, and on a paid plan the description tells the agent that a
mailbox restricted to people the account owner approves needs the user to approve
the person for that mailbox). Input: email, optional attest: boolean. Without
attest the person is emailed a confirmation link and becomes sendable when they
click it. With attest: true no email is sent and the person is sendable at once: the
account vouches for them, spending one of its per-trial attestations (never refunded),
and the result carries attestation: "account_attested" and a complaint_notice. The
description tells the agent to attest only when the user has said they know the
person. If someone added that way reports the account's email as spam, everyone added
that way must confirm by link before they can be emailed again and the account loses
its attestations; a report from a second person suspends the Sandbox account. An agent
key, including every sign-in connection on /v1/mcp/oauth, is refused with
INSUFFICIENT_SCOPE until the operator turns agent recipient writes on, and with
RECIPIENT_WRITE_AGENT_CONTAINED when a bound mailbox only lets the agent email people
the account owner approves; in both cases the hint says to ask the user to add the
person (for this tool, INSUFFICIENT_SCOPE does not suggest an admin key).
Attesting with none left is TIER_LIMIT with attestations_remaining: 0
(forfeited: true after a complaint), or attestations_limit: 0 while attestation is
off. RECIPIENT_WRITE_UNAVAILABLE means retry once; if it fails again, stop and tell
the user. A send refused with SANDBOX_RECIPIENT_NOT_VERIFIED gets a hint naming
add_recipient.star_message — wraps PATCH /v1/messages/:id/star. Input: message_id,
starred: boolean. Use one tool call to star or unstar (matches the SDK/REST {starred}
shape — there are no separate star/unstar verbs).star_thread — wraps PATCH /v1/mailboxes/:id/threads/:thread_id/star. Input:
mailbox, thread_id, starred: boolean.get_attachment_preview — wraps GET /v1/messages/:id/attachments/:idx/preview.
Returns derived text preview only (PDF, Office, text/plain, text/csv). Surfaces
404 ATTACHMENT_PREVIEW_NOT_AVAILABLE as an isError result when the derivative is not
ready, failed, or unavailable.add_inbound_allowlist_bulk — wraps POST /v1/mailboxes/:id/inbound-allowlist/bulk.
Input: mailbox, emails: string[] (max 1000). Returns the full partial-success shape:
added, already_existed, invalid (with per-entry reason), and counts.add_suppressions_bulk — wraps POST /v1/suppressions/bulk. Input:
emails: string[] (max 1000). Same partial-success shape.add_inbound_blocklist_bulk — wraps POST /v1/inbound-blocklist/bulk. Input:
emails: string[] (max 1000). Same partial-success shape.remove_suppression — policy-explanation stub. Always returns isError with code
SUPPRESSION_REMOVE_NOT_AVAILABLE. Improves agent UX by explaining why removal is not
available via MCP rather than returning a generic unknown-tool error.wait_for_message timeout — the tool reflects the real server cap: max 30 s per
call (not 120 s). For longer waits, call the tool again.structuredContent (src/lib/trim-response.ts): reviewed_by_id and six attachment
bookkeeping fields (read_message, get_thread), r2_objects_failed (becomes
r2_objects_failed_count, always present, delete_message), added_by_actor_id (the suppression,
blocklist and allowlist tools), actor_id (list_allowlist_blocked_attempts),
warmup.velocity_gate_mode (get_agent_quota), attachment.hash and
preview.extractor (get_attachment_preview), and the scanner, PII-detector,
instruction-trust and consent-bookkeeping fields (list_mailboxes). A vendor-named suppression
source reads provider_webhook or provider_sync, and an unrecognised one reads
system. A 400 validation error keeps only instancePath and message per
details.validation item, and SELF_HOSTED_DECRYPT_FAILED drops details.domain_id.
next_cursor is an opaque paging token; pass it back unchanged. The REST API, SDK and CLI are unchanged. The full table is
in the MCP guide.list_drafts — returns has_more beside drafts; pass the last draft's id as
before for the next page.Inbox search and full thread reads are first-class on MCP: list_messages filters by
keyword search, sender, date range, direction, status (incl. the held-mail states
quarantined / pending_review for triage) and starred, and pages older via
before=<oldest message id from the previous page>. list_threads lists conversations
(with starred / has_inbound), and get_thread reads a full thread — pass mailbox
to disambiguate a thread key that resolves in more than one mailbox. list_messages also
supports has_attachment (true/false) — it probes /v1/health for the
messages.has_attachment_filter capability and returns a structured
SEARCH_OPERATOR_UNSUPPORTED on older servers that don't advertise it.
send_email, reply_to_message, create_draft and update_draft take an
attachments array. What that array means depends on which server you are talking to.
Local server (this package, npx -y replylayer-mcp) — attachments are paths on
your own machine. The server reads each file, uploads it, waits for its content scan,
and references the resulting handles on the send. This is the normal way to attach files.
Hosted server (POST /v1/mcp on api.replylayer.ai) — the hosted server never
reads files. It runs in ReplyLayer's own infrastructure, so a path in attachments
would name a file on our server, not yours. Supplying a non-empty attachments array
is refused before any file is opened, with a stable code:
{
"error": "The hosted MCP server cannot read files from your machine. To attach files, run the local MCP server (npx -y replylayer-mcp) or upload through the REST API / SDK and send from there; hosted attachment handles are not yet available on MCP.",
"code": "HOSTED_LOCAL_ATTACHMENTS_UNSUPPORTED",
"details": { "attachments": 1 }
}
details reports only how many paths you sent; the paths themselves are never echoed back.
To attach a file on the hosted server, pick one of:
npx -y replylayer-mcp) and use attachments as
documented above; orPOST /v1/attachments returns a handle id,
and POST /v1/messages/send accepts attachment_ids. Send from there.Two details worth knowing:
attachments: [] is not a rejection — it behaves exactly like omitting the
field.idempotency_key, the replay probe runs first and returns the original result. The
attachments parameter therefore stays in the hosted schema (so such a retry still
parses) — only its description changes, and it is refused on a probe miss.Hosted attachment handles on MCP are not available yet; when they land, they will be an explicit handle-id parameter rather than a path.
mcpName (ai.replylayer/replylayer) so the official MCP Registry can list this package. No tool, schema or behaviour change.@modelcontextprotocol/server). The stdio binary and the hosted endpoints now serve the 2026-07-28 protocol revision (server/discover, which returns the same server instructions initialize does) alongside the 2025-era initialize handshake, from one server factory; a client that opens with initialize is served exactly as before. Tool names, descriptions, input and output schemas, annotations and results are unchanged (the tools stay on zod 3 through an adapter that reproduces the previous JSON Schema). Two SDK-generated error texts change: invalid tool arguments read Input validation error: Invalid arguments for tool <name>: <field>: Required (an isError result, as before), and calling a tool that is not registered is a JSON-RPC -32602 "Tool not found" error rather than an isError result. The replylayer-mcp/tools entry now exports buildReplyLayerMcpServer and a structural ToolServer in place of the SDK's McpServer type, so registerAllTools no longer depends on the SDK. Breaking for embedders of replylayer-mcp/tools; none for stdio users.releasable field descriptions now say it is the draft-only flag (always false on sent or received messages) and point to email_effect for held messages; the server primer gains one sentence saying the same and that held outbound mail is released only by the account owner in the dashboard. No schema or behaviour change.create_draft, reply_to_message and send_email descriptions now link the ReplyLayer API reference they call (Anthropic directory requirement). No schema or behaviour change.annotations.title (Anthropic directory requirement). The top-level title is kept. No schema or behaviour change.add_recipient description: a spam report from someone added with attest also revokes everyone added that way (they must confirm by link again), and only a report from a second person suspends the Sandbox account. No schema or behaviour change.outputSchema and returns matching structuredContent
(the same JSON as the text block, which is unchanged); remove_suppression, which
always returns an error, is the one tool without one, so every tool on the sign-in
endpoint has one. Each schema follows the API route's response schema, after the
fields the tool leaves out; objects are open, enum-like values are strings, and only
the top-level fields the route always returns are required. The existing schemas gain
the fields they were missing: hold_context.review_url, review_expires_at,
review_causes and agent_instructions, the review fields and firewall_block on
message reads, the trimmed attachment fields, and the mailbox fields list_mailboxes
keeps. get_attachment_preview now requires attachment and preview. Also ships
the held-send changes merged after 0.13.0 was published: the HELD line on a held send
now tells the agent to tell the account owner where the send waits
(hold_context.review_url) and by when (hold_context.review_expires_at), and not to
send it again; send_draft now shapes its result like send_email and
reply_to_message (a held draft send leads with the same line, and a blocked one is an
isError result); the primer says the same. No tool name, input, annotation or
description changes. Requires @replylayer/sdk 0.28.1.title and
explicit boolean readOnlyHint, destructiveHint and openWorldHint, plus
idempotentHint on every tool that changes something (see
Tool annotations). create_draft, update_draft, both release
tools, add_recipient, and the ten list and marker writes (add_suppression*,
add_inbound_blocklist*, add_inbound_allowlist*, mark_*_read, star_*) are now
destructive, so hosts that honour the hints ask before running them.
remove_suppression is now read-only (it always returns an error). create_draft
and update_draft say that no email is sent unless send_at is set. The masking
guidance in the idempotency_key descriptions and the primer no longer names a
specific host. delete_message and report_and_block declare idempotentHint: true.
New grant registration option ('any' by default): the hosted sign-in endpoint
registers with grant: 'agent', which leaves out AGENT_UNAVAILABLE_TOOL_NAMES
(approve_review, deny_review, get_account_usage, remove_suppression; the
other 40 remain) and ships OAUTH_SERVER_INSTRUCTIONS, the primer with its API-key
wording replaced by connection wording. A grant: 'agent' registration also takes
oauth: { scope, challenge } (required) and adds OAuth linking metadata: every tool
carries securitySchemes ([{ type: 'oauth2', scopes: [scope] }]) in _meta and,
through a wrapped tools/list handler, top-level too, and a tool
error caused by a 401 from the API carries _meta["mcp/www_authenticate"]: [challenge],
which a client that signs in per tool (ChatGPT) needs to re-link. The stdio server and
/v1/mcp are unchanged by the grant. Apart from add_recipient's new attest (below),
no parameter changes. Results leave out internal identifiers and bookkeeping on every transport (see
Tool notes): reviewed_by_id, added_by_actor_id, actor_id,
r2_objects_failed (now r2_objects_failed_count), warmup.velocity_gate_mode,
preview.extractor, attachment hash and bookkeeping fields, and the mailbox
scanner, PII-detector, instruction-trust and consent-bookkeeping fields; a vendor-named
suppression source reads provider_webhook or provider_sync; 400 validation
details keep only instancePath and message, and SELF_HOSTED_DECRYPT_FAILED drops
details.domain_id. get_attachment_preview's output schema no longer lists
attachment.hash or preview.extractor, and list_allowlist_blocked_attempts's
description no longer names actor_id. list_drafts returns the API's has_more
again. Sandbox recipient attestation: add_recipient gains an optional attest: boolean (sendable now, no confirmation
email, spends one of the account's per-trial attestations) and a description that
states the Sandbox-only scope, both branches, the complaint consequence and the
restricted-mailbox refusal; it stays listed on the sign-in endpoint. It no longer
says other accounts "can email anyone": they don't use this list, and on a paid plan a
mailbox restricted to approved people still binds agent sends, so the agent asks the
user to approve the person. The Sandbox-recipient hints likewise say pay-as-you-go
credit removes the Sandbox recipient rule, not that it lets the agent email anyone. Tool errors gain
hints for SANDBOX_RECIPIENT_NOT_VERIFIED, RECIPIENT_WRITE_AGENT_CONTAINED,
RECIPIENT_WRITE_UNAVAILABLE and an attestation TIER_LIMIT. Requires
@replylayer/sdk 0.28.0.idempotency_key descriptions on
send_email, reply_to_message and create_draft, and the server-level primer, now
say: pass the literal key in every call, and if your host masks fields ending in
_key (OpenClaw does), retry from a new session with the full literal request instead
of reusing a masked value. The API refuses a masked key (***, a value containing
…, __OPENCLAW_REDACTED__, or a word such as [REDACTED]) with
400 IDEMPOTENCY_KEY_INVALID. The hosted server already carries this text. No tool or
schema change. The release also produces the Claude Desktop extension bundle.SERVER_INSTRUCTIONS) now tells the agent that a RATE_LIMITED whose
details.reason is failed_authentication means the API key is wrong or revoked:
stop and ask a human to fix the key, do not retry. It also names UNAUTHORIZED /
API_KEY_REVOKED as stop-and-ask-a-human codes. Tool errors gain matching friendly
hints for the failed-authentication 429 (checked before the daily-quota test) and
for API_KEY_REVOKED. No tool or schema change.attachments paths before any
filesystem access (HOSTED_LOCAL_ATTACHMENTS_UNSUPPORTED); see
Hosted vs local attachments. Additive public API: the
tool registrars exported from replylayer-mcp/tools accept an optional third
RegisterToolOptions argument ({ transport?: 'local' | 'hosted' }, default
'local'), so every existing two-argument call is unchanged. The hosted MCP server
also injects the same server-level workflow primer as this binary and advertises the
real package version; both transports read the version from package.json. The
primer branches on email_effect.effect_status (with the legacy top-level status
as a fallback for older servers) and carries the immediate-send idempotency rules.
Additive public API: replylayer-mcp/tools also exports SERVER_INSTRUCTIONS and
MCP_PACKAGE_VERSION.SKILL.md, the CLI ↔ MCP ↔ REST verb-parity map, and ENDPOINTS.md
(the REST API contract) will be published with the hosted docs site when it is
available.FAQs
MCP server for ReplyLayer — safe email for AI agents
The npm package replylayer-mcp receives a total of 372 weekly downloads. As such, replylayer-mcp popularity was classified as not popular.
We found that replylayer-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.

Research
/Security News
A new GhostAction wave hits hundreds of GitHub repos, expanding CI/CD secret theft to cloud and AI credentials in source code and git history.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.