convex-mcp-gatewayCAUTION
Auth-aware Convex component that exposes selected Convex functions as MCP tools
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Auth-aware MCP server for Convex. Expose selected Convex functions as MCP tools, bring your own JWT issuer, declare scopes/roles per tool, get an audit log and OAuth 2.1 protected-resource discovery for free.
Built as a Convex Component.
[](https://www.convex.dev/components/convex-mcp-gateway) [](https://github.com/tfohlmeister/convex-mcp-gateway/actions/workflows/test.yml) [](https://www.npmjs.com/package/convex-mcp-gateway) [](./LICENSE)
Features
- Type-safe tool registration:
defineMcpQuery/defineMcpMutation/
defineMcpAction declare a Convex function as an MCP tool with end-to- end-typed args and (optional) returns validators. Declare the list once and pass it as tools to handleMcpRequest, the registry auto-syncs on connect (no separate registration mutation), or call gateway.register(...) for imperative/dynamic catalogs
- MCP dual-era Streamable HTTP: legacy 2025-03-26/2025-06-18/2025-11-25
sessions remain supported alongside stateless 2026-07-28 requests, discovery, routing-header validation, and private cache hints. A client requesting an unknown revision negotiates down to 2025-11-25 (what the current official TypeScript SDK pins as latest); all three legacy revisions share one transport wire contract (2025-11-25's SSE resumability framing needs an event store the gateway doesn't have, so it isn't emitted, a deliberate SHOULD deviation)
- Stateless multi-round trips: declarative stateless-era tools use a host-side
beforeCall hook
1dfccba4c2e4OBSERVED · 2026-10-12Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add convex-mcp-gateway --env MCP_MRTR_SECRET=${MCP_MRTR_SECRET} --env MCP_PROXY_TOKEN=${MCP_PROXY_TOKEN} -- npx -y [email protected]{
"mcpServers": {
"convex-mcp-gateway": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"MCP_MRTR_SECRET": "${MCP_MRTR_SECRET}",
"MCP_PROXY_TOKEN": "${MCP_PROXY_TOKEN}"
}
}
}
}Exposed tools (92)
88 read · 2 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
A | read | d |
Intro | read | first |
Overview | read | Tenant skill overview |
Row | read | A database row |
Synced | read | Synced docs |
a | read | a |
alpha | read | Alpha tool |
archive | read | Archives |
archive_confirmed | read | Confirmed the documented direct way |
archive_confirmed_alias | read | Also confirmed, via the client wrapper |
archive_raw | read | Not confirmed |
arg1 | read | First test argument |
arg2 | read | Second test argument |
bad_mrtr_tool | read | x |
bad_tool | read | x |
beta | read | fresh-beta |
broken | read | Broken |
broken_query | read | always throws |
bulky_tool | read | x |
confirm-delete | destructive | Deletes after confirmation |
confirm_only_tool | read | x |
confirm_tool | read | x |
corrupt | read | Corrupt |
deep | read | Deep |
deep_tool | read | Deep |
delta | read | fresh-delta |
demo_tool | read | test |
drift_tool | read | injected out-of-band |
dup | read | first |
example | read | Example |
failing_job | read | Always reports a tool execution error, after about a second |
get_context | read | Read entity context |
greet | write | Greets by name. The sync-only control for the tasks scenarios |
greeting | read | Greet someone by name |
healthy | read | Healthy |
hooked_query_without_key | read | x |
hooked_without_key | read | x |
identity_collision_tool | read | x |
invoice | read | Read a single invoice by its id. |
invoice-summary | read | Total invoice count for the authenticated caller. |
invoiceId | read | The invoice to review |
invoices_archiveAfterConfirmation | read | Ask for confirmation, then archive an invoice with a replay-safe retry. |
invoices_archive_raw | read | Not confirmed |
invoices_bulkMarkPaid | read | Mark every open invoice paid, after task-based confirmation. |
invoices_list | read | List invoices, optionally filtered by status. |
invoices_markPaid | read | Mark an invoice as paid. |
invoices_recount | read | Recount all invoices as a deferred MCP task; poll tasks/get for |
invoices_review | read | Check one invoice for problems before it is sent. |
invoices_summary | read | Summarize invoices. |
invoices_whoami | read | Return the authenticated caller. Identity is injected by |
json_schema_2020_12_tool | read | Tool with JSON Schema 2020-12 features |
keyed_without_hook | read | x |
missing_arg_tool | read | x |
nested_redact | read | redact a nested path |
non_optional_key | read | x |
ok | read | Fine |
ok_tool | read | x |
old_tool | read | from a previous list |
plain | read | No arguments |
protocol_error_job | read | Always fails with a protocol-level error |
regional_lookup | read | Looks up by region |
regional_summary | read | Summary pinned to a region routing header. |
reports_generate | read | Generates a report |
resourceUri | read | URI of the resource to embed |
scalar_tool | read | returns a string |
scoped | read | with scopes |
search | read | Search |
search_alias | read | Read alias |
secret_failure | read | Demo of error-message redaction. |
secret_identity | read | identityArg + field redaction |
secret_write | write | Demo of declarative field redaction. |
sensitive_drop | destructive | tool that opts out of arg storage |
shaper | read | shapes |
slow_compute | read | Sleeps for |
solo_tool | read | registered one at a time |
spoof_probe | read | the real description |
spoofed_tool | read | spoofed description |
stale_tool | read | left over |
structured_throw | read | throws ConvexError with object data |
test_custom_headers | read | Tool whose region argument is bound to a routing header |
test_error_handling | read | Always reports a tool error |
test_prompt_with_arguments | read | A prompt with two required arguments |
test_prompt_with_embedded_resource | read | A prompt embedding the resource it is given |
test_prompt_with_image | read | A prompt carrying an image |
test_simple_prompt | read | A simple prompt without arguments |
test_simple_text | read | Returns simple text content |
test_tool_with_task | read | Task-capable tool for the MCP Tasks extension scenarios |
tmp_tool | read | tmp |
user_facing_throw | read | throws ConvexError |
who | read | Who to greet |
x | read | v1 |
zebra | read | Zebra tool |
Trust audit
CAUTIONgrade B · trust 84/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (1 observation(s))
- Network
- declared (4 observation(s))
- Shell
- declared (1 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (17)
"--disable-beacon",
failPlain: "postgres://user:pw@host exploded",
confirm-delete, sensitive_drop
.prettierrc.json
.release-please-manifest.json
"../../src/component/**/*.ts",
"!../../src/component/**/*.test.ts",
import componentSchema from "../../src/component/schema.js";
callback_url = "http://127.0.0.1/callback"
--url http://127.0.0.1:3399/mcp --requirements 2026-07-28
`http://127.0.0.1:<port>` and `http://localhost:<port>`, so an
SESSION=$(curl -sSD - -X POST http://127.0.0.1:3311/mcp/ \
curl http://127.0.0.1:3311/mcp/ \
const binary = atob(encoded);
return Uint8Array.from(atob(padded), (char) => char.charCodeAt(0));
@convex-dev/eslint-plugin, @eslint/js, @types/node, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, convex, convex-test, eslint
SESSION=$(curl -sSD - -X POST http://127.0.0.1:3311/mcp/ \
Gates applied: no_behavioural_pass.
1dfccba4c2e4full audit observations/trust-audit/mcp-server/tfohlmeister__convex-mcp-gateway.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | 1dfccba4c2e4 | CAUTION | B | 84 | first audit |
Questions
What is the convex-mcp-gateway MCP server?
Auth-aware Convex component that exposes selected Convex functions as MCP tools
What tools does convex-mcp-gateway expose?
92 in total: 88 read-only, 2 that write, and 2 that can delete or overwrite (confirm-delete, sensitive_drop). Every one is listed on this page with its risk.
Is convex-mcp-gateway safe to connect to an agent?
With care. The audit graded it B (84/100) and found 17 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does convex-mcp-gateway need?
It reads MCP_MRTR_SECRET and MCP_PROXY_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does convex-mcp-gateway run?
It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as convex-mcp-gateway at 2.1.1.
How current is this page?
The grade is for one exact copy of the source (1dfccba4c2e4), read on 2026-10-12. The repository is watched and re-audited when it changes.