You are not logged in.
Hi Arnaud, hi all,
We run mORMot 2 in production (FPC on Linux, native, no Indy/Wine) as the backend
of a SaaS for the trades. We now need an **MCP server** so our backend can expose
tools/resources to AI agents (e.g. Claude Desktop and our own agent), and ideally
LLM client drivers later on.
Before writing much code I'd like to check interest and get your guidance, because
I think this belongs **in the mORMot world**, not as yet another standalone lib.
## The gap
As far as I can see, mORMot has no AI/LLM/MCP module today. Meanwhile mORMot
already ships everything such a module needs and would do it better than the
Delphi-only options out there (which lean on Indy and `System.JSON`/`System.Rtti`):
- `mormot.net.server` / `mormot.net.async` — HTTP server for the *Streamable HTTP*
MCP transport
- `mormot.net.ws.*` — WebSockets for streaming
- `mormot.core.json` / `mormot.core.variants` — JSON-RPC 2.0 envelopes with
`TDocVariant`
- `mormot.core.rtti` — generating JSON-Schema for tool input from typed records
- cross-compiler (FPC + Delphi), cross-platform, no extra dependencies
## What I'm proposing
A small, **clean-room** extension under a new `mormot.ai.*` namespace, built
against the official **MCP specification (revision 2025-11-25)** and JSON-RPC 2.0
— not derived from any third-party MCP code. Initial, transport-neutral layout:
```
mormot.ai.mcp.types JSON-RPC/MCP types + envelope build/parse
mormot.ai.mcp.server engine: tool/resource registry + JSON-RPC dispatch
(initialize, tools/list, tools/call) — JSON in/out
mormot.ai.mcp.transport.stdio stdin/stdout (local subprocess transport)
mormot.ai.mcp.transport.http Streamable HTTP on mormot.net.server
```
The engine takes JSON in and returns JSON out, so it is fully unit-testable
without a socket; transports are thin adapters. Tools implement a small
`IMcpTool` interface (`GetName`/`GetDescription`/`GetInputSchema`/`Execute`).
I already have the first unit (`mormot.ai.mcp.types`) and FPCUnit tests for the
JSON-RPC envelopes; the rest is staged behind it.
## Questions
1. **Interest & home** — would you welcome such an extension under the
`mormot.ai.*` namespace (eventual upstream into mORMot), or would you prefer
it lives as an external companion package? Either is fine for us; I'd just
like to build it the way that has the best chance of being useful to others.
2. **Namespace & conventions** — if upstream is on the table, is `mormot.ai.*`
the naming you'd want (e.g. `mormot.ai.mcp.server`)? Any coding-style or CLA
requirements I should follow from the start?
3. **Transport** — for Streamable HTTP, what's your recommended building block:
plain `THttpServer`/`THttpAsyncServer` with manual chunked writes, or is there
a pattern you'd point me at for long-lived streaming responses + an optional
WebSocket upgrade?
4. **JSON-RPC API shape** — for a framework-grade API, would you prefer the
envelopes/dispatch built on `TDocVariant` (what I have now) or on typed records
with `mormot.core.rtti` serialization? Happy to follow your taste here.
I'm willing to maintain this and contribute it back. Thanks for mORMot — it has
been a joy to build a native FPC backend on it.
Best regards,
Sven
Offline
Hey @sh17, did you checked my mcp extension there? I pushed a new update 4 days ago that add streamable-http transport support (up to 2025-03-26 version and will be very soon updated to the latest).
Cross-platform. Fully testable. You can find also some demos.
code: mormot2-extensions/mormot-mcp-server
Last edited by flydev (Today 10:10:25)
Offline
Hi flydev,
thanks a lot — I didn't know about mormot2-extensions, and your
mormot-mcp-server is genuinely the closest thing to "MCP done the mORMot way"
I've seen. I went through it in detail;
- It reads like a mORMot core unit, not a Delphi port: IInvokable tools,
RTTI-based schema generation, TDocVariant envelopes, the tri-license header
and * section style.
- The transport layer is excellent — stdio, HTTP, SSE and a real Streamable
HTTP with token-by-token streaming (incl. the Claude CLI demo). That directly
answers the streaming question from my post.
- The TSynTestCase coverage for the transports (origin validation, sessions,
batching, notifications, bad-JSON, 405 paths) is exactly the rigor I'd want.
Where my use case still diverges — and why I think there's room for both:
1. Spec revision. Our agents target the current MCP revision
(2025-11-25); your server is on 2024-11-05 + Streamable HTTP 2025-03-26.
For us the newer revision isn't optional.
2. Auth is our product core. We're a SaaS backend with JWT, HttpOnly refresh
cookies, __Host-csrf double-submit, a role/permission model and owner-capped
scopes. MCP tool execution has to run *inside* that context on our existing
mORMot host (TUriRouter + guards), not as a separate server. Your
TMcpAuthContext is a nice foundation, but the wiring is fairly specific to us.
So I'll keep building our mormot.ai.* clean-room layer (current spec + auth bound
to our context), but I'd love to align the Streamable HTTP transport with your
approach rather than reinvent it.
Which loops back to my question for Arnaud: with community MCP servers now existing,
is there appetite to converge any of this under an official namespace, or do you
prefer it stays as companion packages? Happy either way.
Thanks again for pointing me to it.
Best,
Sven
Last edited by sh17 (Today 11:02:41)
Offline
Thanks. Yes, the extensions are meant to be written using mormot only. The spec revision will be updated next week to the latest version.
Regarding authorization, it is indeed planned and will follow MCP security/authorization, with optional support for our secure RESTful authentication scheme.
I don’t know about @ab’s decision, but FYI, a few weeks ago I wrote a mormot-only port of LiteLLM to add an AI gateway providing simplified model access. It is still not polished, as I was missing the now-available streamable HTTP transport and will be pushed to the extensions repo soon.
Do not hesitate to reuse any code and to let use know about any update on your side ![]()
edit: small note,
(incl. the Claude CLI demo). That directly answers the streaming question from my post.
This demo use the mormot.ext.os extension, more info there.
Last edited by flydev (Today 12:04:37)
Offline
This is a very nice idea.
Perhaps it would be to include this whole mormot.ai.* part to the framework, because I didn't write it and can't test it really, so I can't maintain it.
But the idea of third-party/custom mormot units like mormot.ext.* is great.
BTW https://github.com/flydev-fr/mormot2-ex … /mormot-os is likely to finish in mormot, because it is really a missing basic feature.
Perhaps together with fixing https://github.com/synopse/mORMot2/issues/463 issue.
Offline