1 MCP server, 13 databases, zero config. Multi-protocol transport with Auth + RBAC.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent — or use 1-click editor setup below.
💡 Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
One schema, 11 transports, 13 databases, multi-tenant auth — out of the box. Schema-driven multi-protocol API server for the @mostajs ecosystem. Built with TypeScript on Fastify, designed for polyglot consumption (14 native NetClients).
Author : Dr Hamid MADANI <drmdh@msn.com> Homepage : octonet.amia.fr · mcp.amia.fr
The socket board.
@mostajs/ormconnects to 13 databases; Octonet (@mostajs/net) re-exposes the same entities over 11 transports (REST, WebSocket, gRPC, MQTT, AMQP…); NetClient then fans out to 18 language clients — so any external app plugs into your data, in any runtime.
Octonet (@mostajs/net) is a Node.js multi-transport server that exposes a single @mostajs/orm schema as 11 different network protocols simultaneously : REST, GraphQL, WebSocket, SSE, JSON-RPC, MCP, gRPC, tRPC, OData, NATS, Arrow Flight.
The same User entity is reachable as :
Backed by @mostajs/orm (13 SGBD dialects). Backed by @mostajs/rbac + @mostajs/auth + @mostajs/api-keys for multi-tenant identity. Backed by @mostajs/mproject for multi-project routing.
Octonet is the second cerebral lobe of the @mostajs trilogy :
@mostajs/orm : data persistence (13 databases)The fastest way to test Octonet from any of the 14 runtimes :
alice-42)Your sandbox is :
User, Product, Order entitiesUse the apikey in any of the 14 NetClients :
| Tier | Cible | Auth | Quota | Use case |
|---|---|---|---|---|
T1 — Sandbox publique /try | "I want to test in 10 minutes" | alias seul (pas d'email) | 500 req/jour, TTL 7j | démo NetClients, intégration tests |
| T2 — Compte enregistré octocloud.amia.fr | "j'utilise vraiment, gratuit" | email + mot de passe | 10 000 req/jour | apps personnelles, side-projects |
T3 — Self-host npx @mostajs/net init | "tes données chez toi" | admin local | aucune | enterprise, on-premise, AGPL |
Auto-generated from your registered schemas. Toggle each via env var (default : all enabled).
| # | Transport | Endpoint | Use case | Notes |
|---|---|---|---|---|
| 1 | REST | /api/v1/{Entity} · /api/v1/{project}/{Entity} | universel | 15 routes par entité (CRUD + count + search + aggregate + bulk + relations) |
| 2 | GraphQL | /graphql (POST) | front-end riches | schéma + GraphiQL IDE auto-générés via mercurius |
| 3 | WebSocket | wss://…/ws | temps réel | events entity.created/updated/deleted/upserted broadcast |
| 4 | SSE | /events (GET stream) | mobile / browser-friendly | server-sent events |
| 5 | JSON-RPC | /rpc (POST) | EVM-adjacent, classic | JSON-RPC 2.0 + method discovery |
| 6 | MCP | /mcp (POST/GET SSE) | agents IA (Claude, ChatGPT) | 15 tools/entité auto-générés (listed on mcp.so) |
| 7 | gRPC | :50051 | inter-services low-latency | .proto auto-généré, 6 RPCs/entité |
| 8 | tRPC | /trpc/{Entity}.{op} | TypeScript fullstack | type generation côté client |
| 9 | OData | /odata/{Collection} (+ $metadata) | SAP/Microsoft Dynamics | OData v4 ($filter, $select, $orderby) |
| 10 | NATS | mostajs.{Entity}.{op} | pub/sub edge | request-reply messaging |
| 11 | Arrow Flight | /arrow/* | analytics columnaire | streaming zero-copy |
Le même schéma, 11 portes d'entrée différentes, 0 codegen.
Persistence dialects fournis par @mostajs/orm :
| Catégorie | Bases | Dialect ID |
|---|---|---|
| SQL mainstream | PostgreSQL, MySQL, MariaDB, SQLite | postgres, mysql, mariadb, sqlite |
| SQL enterprise | Oracle, SQL Server, DB2, SAP HANA, HSQLDB, Sybase | oracle, mssql, db2, hana, hsqldb, sybase |
| NewSQL / Cloud | CockroachDB, Google Cloud Spanner | cockroachdb, spanner |
| NoSQL | MongoDB | mongodb |
Switch dialect = changer 1 ligne d'env :
Octonet utilise un middleware d'authentification basé sur API keys avec scopes (orienté machine-to-machine) + RBAC pour la gestion humaine. L'orchestrateur agnostique vit dans @mostajs/auth/lib/check-request.ts.
Une apikey a la shape :
@mostajs/api-keys ne connaît PAS les noms projects/operations/transports — c'est volontaire. Chaque module enregistre ses scopes au boot via registerScope(dialect, {name, label, …}). Le check est générique : isScopeAuthorized(perms, scope, value).
| Cas | HTTP code | Body |
|---|---|---|
| Pas d'apikey | 401 | {error: {code:'UNAUTHORIZED', message:'API key required…'}} |
| Apikey invalide / révoquée | 401 | {error: {code:'UNAUTHORIZED', message:'Invalid or revoked API key'}} |
| Apikey valide hors scope | 403 | {error: {code:'FORBIDDEN', message:'API key not authorized for X="Y"'}} |
| Apikey OK | 200/201 | {status:'ok', data: …} (sanitized — no password/hash) |
L'endpoint /mcp autorise un fallback automatique sur l'apikey labelée public-default quand aucune clé n'est présentée — préserve la compat avec mcp.so / Claude Desktop. La clé publique est read-only sur le projet default uniquement → écritures bloquées.
Les champs password, hash, verifyToken, resetToken, apiKeyHash, secret, privateKey sont automatiquement strippés de toutes les réponses JSON par un middleware global. Aucun risque de leak à travers /api/v1/User?limit=1.
Le catalogue des scopes vit en base de données du projet accueillant (pas de fichier JSON, pas de constantes hardcodées) :
Chaque module enregistre ses scopes au boot :
L'admin UI charge le catalogue dynamique via GET /api/api-keys/scopes et rend une matrice (composant React ApiKeyScopeMatrix dans @mostajs/api-keys/components/).
Via @mostajs/mproject — N bases de données isolées sur le même serveur.
Persisté dans projects-tree.json (chemin : MOSTA_PROJECTS env var).
Console output :
Sépare la base système (apikeys, RBAC users, audit, plans, payments, project-life metadata) du dialect métier mutable. Sans ces variables, alias transparent vers le singleton métier (rétro-compat mono-base).
Voir section System dialect ci-dessous pour la motivation et les how-to.
@mostajs/config — supports profile cascade MOSTA_ENV=DEV)| Endpoint | Méthode | Auth | Description |
|---|---|---|---|
/health | GET | open | server status + transports + entities |
/try | GET | open | T1 sandbox provisioning HTML form |
/try | POST | open (rate-limit 10/h/IP) | crée sandbox + retourne apikey one-shot |
/api/v1/health | GET | open | health under api-versioned path |
| Endpoint | Méthode | Op | Description |
|---|---|---|---|
/api/v1/{Entity} | GET | findAll | list entities of default project |
/api/v1/{Entity}/:id | GET | findById | get one |
/api/v1/{Entity}/count | GET | count | count |
/api/v1/{Entity}/one | GET | findOne | first match |
/api/v1/{Entity}/search | GET | search | text search |
/api/v1/{Entity} | POST | create | insert |
/api/v1/{Entity}/:id | PUT | update | replace |
/api/v1/{Entity}/:id | DELETE | delete | remove |
/api/v1/{Entity}/:id/addToSet | POST | addToSet | add to array |
/api/v1/{Entity}/:id/pull | POST | pull | remove from array |
/api/v1/{Entity}/:id/increment | POST | increment | numeric add |
/api/v1/{Entity}/upsert | POST | upsert | insert or update |
/api/v1/{Entity}/aggregate | POST | aggregate | pipeline |
/api/v1/{Entity}/updateMany | POST | updateMany | bulk update |
/api/v1/{Entity}/deleteMany | POST | deleteMany | bulk delete |
/api/v1/{project}/{Entity}/… | * | * | same routes scoped to a project |
| Endpoint | Méthode | Description |
|---|---|---|
/api/upload-schemas-json | POST | push schemas at runtime (triggers reload) |
/api/apply-schema | POST | apply schema diff |
/api/compare-schema | POST | dry-run schema diff |
/api/schemas-config | GET | current registered schemas |
| Endpoint | Méthode | Description |
|---|---|---|
/api/api-keys | GET / POST | list / issue keys |
/api/api-keys/:id | PUT / DELETE | update / revoke |
/api/api-keys/scopes | GET | list registered scopes + values (for admin matrix UI) |
/api/api-keys/scopes | POST | register a new scope (admin) |
/api/api-keys/scopes/:name/values | PUT / DELETE | manage scope values |
| Endpoint | Description |
|---|---|
/graphql | GraphQL endpoint + GraphiQL IDE |
/ws | WebSocket connection (entity events) |
/events | SSE stream |
/rpc | JSON-RPC 2.0 |
/mcp | Model Context Protocol (Claude/Smithery/etc.) |
/trpc/{Entity}.{op} | tRPC procedure |
/odata/{Collection} · /odata/$metadata | OData v4 |
| Endpoint | Méthode | Description |
|---|---|---|
/api/projects | GET | list projects |
/api/projects | POST | add project |
/api/projects/:name | PUT / DELETE | edit / remove |
| Endpoint | Description |
|---|---|
/api/performance | live metrics (req/s, p50, p99) |
/api/config-tree | configuration tree (interactive) |
/api/live-log | streaming log feed |
| Module | Rôle dans Octonet |
|---|---|
@mostajs/orm | persistance (13 dialects) |
@mostajs/mproject | gestion multi-projet (default + sandbox + abonnés) |
@mostajs/rbac | identité (User, Role, Permission, Account) + AccountSchema + OCTONET_RBAC_SEED |
@mostajs/auth | checkRequest orchestrateur framework-agnostic, hashPassword |
@mostajs/api-keys | apikey CRUD + scopes (Scope/ScopeValue schemas) + checkApiKey + ApiKeyScopeMatrix admin UI |
@mostajs/config | env var helper avec cascade MOSTA_ENV |
@mostajs/cloud-middleware | quota / abonnement (optionnel — actif si Octocloud connecté) |
@mostajs/replicator | CQRS multi-replica (optionnel) |
@mostajs/project-life | persistence schemas Project (optionnel — si stockage SGBD vs JSON) |
Disponible depuis v2.7.5 — résout le bug « apikeys introuvables après
/api/change-dialect» observé en prod.
Octonet expose des routes admin qui mutent la connexion DB au runtime (/api/change-dialect, /api/reload-config, /api/reconnect) — légitime côté métier (les entités userland du projet courant peuvent migrer postgres → sqlite → mongodb selon les besoins de l'admin).
Mais les modules système (apikeys, RBAC users, audit, plans de souscription, payments, project-life metadata) doivent vivre dans une base stable qui ne suit pas ces mutations. Sinon : un changement de dialect métier rend les apikeys introuvables, l'admin se trouve verrouillé hors de l'IHM.
| Rôle | Variable env | Mutable au runtime ? | Lu par |
|---|---|---|---|
| Métier (entités userland) | DB_DIALECT + SGBD_URI | Oui (IHM admin) | EntityService, transports, routes data |
| Système (infra Octonet) | MOSTA_SYSTEM_DIALECT + MOSTA_SYSTEM_URI | Non (stable) | RBAC, apikey-middleware, account-scope, auth guards, sandbox /try |
Laisser MOSTA_SYSTEM_* vides → alias automatique vers le singleton métier (rétro-compat 100 %, comportement identique au pré-v2.7.5).
Avant v2.7.5, le 2ᵉ curl retournait 503 metadata DB unavailable ou 401 PostgreSQL not connected. Call connect() first.
Au boot d'octonet-mcp, deux logs apparaissent :
src/server.ts (pour référence)18 callers tirent désormais leur dialect via getSystemDialect() au lieu du singleton métier :
| Bloc | Sites | Caller |
|---|---|---|
| RBAC bootstrap | 1 | bootstrapRbac(systemDialect, …) |
| Scopes register | 4 | registerScope(systemDialect, …) × 3 + systemDialect.initSchema(scopeTables) |
| Middlewares globaux | 2 | createApiKeyMiddleware(() => systemDialect, …) + createAccountScopeMiddleware(() => systemDialect) |
| Middlewares per-transport | 2 | idem appliqués sur chaque transport.use(…) |
| Auth guards transports | 6 | authGuard(systemDialect, …) × 6 (SSE, GraphQL, JSON-RPC, gRPC, tRPC, OData) |
Custom /api/auth/verify | 2 | checkApiKey(systemDialect, …) + new UserRepository(systemDialect) |
Sandbox /try | 2 | registerTryRoutes({ dialect: systemDialect, … }) + startTrialCleanupJob({ dialect: systemDialect, … }) |
Le dialect métier (dialect) reste utilisé légitimement pour :
L98) + pm.setDefault('default', dialect, …) (L126, L240)/api/reconnect, /api/change-dialect, /api/reload-config, /api/test-connection, /api/truncate-tables, /api/drop-tables — toutes opérations explicitement métierEntityService qui sert les entités userland (opérations CRUD via les transports protégés)| Étape | Repo | Livré |
|---|---|---|
| 1 | @mostajs/data-plug v1.2.2-1.2.4 (API getSystemDialect + façade ORM) | npm |
| 2 | @mostajs/net v2.7.5 (bootstrapSystemDialect au démarrage) | git |
| 3 | @mostajs/api-keys 0.2.3, @mostajs/payment 0.4.1, @mostajs/project-life 0.1.3, @mostajs/subscriptions-plan 0.3.5 (WeakMap repos + façade) | npm |
| 4 | @mostajs/net v2.7.5 (consumers basculent sur getSystemDialect() — 18 sites) | git |
| 5 | Tests d'intégration scénario /api/change-dialect postgres → sqlite | ⏳ |
| 6 | Déploiement amia + smoke test MOSTA_SYSTEM_URI | ⏳ |
.env via @mostajs/config (profile cascade MOSTA_ENV)SGBD_URI)getAllSchemas() registry → schemas.json → SCHEMAS_PATH directory scan)dialect.initSchema(schemas) with strategy update/createoctonet-rbac-bootstrap.ts) :
seedRBAC(OCTONET_RBAC_SEED) — 6 categories, 25 permissions, 4 roles (admin/subscriber/trial/public)createAdmin() from OCTONET_ADMIN_EMAIL/PASSWORDtrial-playground (type='trial')public-demo (role=public)public-system (type='system')public-default scoped to default project (read-only, REST + MCP) — emitted ONCE in clearprojects (dynamic, Project.slug), operations (static : read/write/admin), transports (static : 11 values)projects-tree.json (ownerId=admin, visibility=public)projects-tree.jsoncomposeMiddleware([sanitizer, apikey], ormHandler) → protectedOrmHandlertransport.use(loggingMiddleware)transport.use(sanitizerMiddleware)transport.use(apiKeyMiddleware)transport.setHandler(ormHandler)transport.start(config)registerDynamicRestRoutes(app, protectedOrmHandler, pm) — /api/v1/...registerProjectRoutes(app, pm, protectedOrmHandler) — /:project/*registerTryRoutes(app, {dialect, pm}) — /try POSTregisterTryPage(app) — /try GET (HTML)startTrialCleanupJob({dialect, pm}) — cron horaire TTL 7jMOSTA_NET_PORT)Octonet est consommable depuis 14 runtimes natifs, avec la même apikey, la même URL :
| Runtime | Package | Registre |
|---|---|---|
| Node/TS | @mostajs/net/client (built-in) | npm |
| Java | com.mostajs:mostajs-net-client | Maven Central |
| Java + Spring Boot | com.mostajs:mostajs-net-client-spring-boot-starter | Maven Central |
| .NET | MostaJs.Net.Client | NuGet |
| Python | mostajs-net-client | PyPI |
| Go | github.com/apolocine/mosta-net-client-go | pkg.go.dev |
| Swift | mosta-net-client-swift | Swift Package Index |
| Kotlin | io.github.apolocine:mostajs-net-client-kt | Maven Central |
| Dart / Flutter | mostajs_net_client | pub.dev |
| Rust | mostajs-net-client | crates.io |
| PHP | mostajs/net-client | Packagist |
| Ruby | mostajs-net-client | RubyGems |
| Elixir | mostajs_net_client | Hex.pm |
| Lua | mostajs-net-client | LuaRocks |
| Delphi | MostaJsNetClient | GetIt |
| Unity (C#) | com.mostajs.net-client | OpenUPM |
Monorepo : github.com/apolocine/mosta-net-clients
Chaque NetClient suit le même contrat d'API :
Le déploiement de référence tourne sur octonet.amia.fr + mcp.amia.fr (alias compat) en backend PostgreSQL :
| URL | Rôle |
|---|---|
https://octonet.amia.fr | Octonet server (REST, MCP, GraphQL, WS, SSE, tRPC, OData, JSON-RPC) |
https://mcp.amia.fr | alias DNS de compatibilité — historique mcp.so |
https://octocloud.amia.fr | Octocloud — portail SaaS Next.js (subscriptions, admin UI) |
Le kit de déploiement complet est dans Entreprise/octonet-mcp/ :
apache/mcp.amia.fr.conf — vhost Apache2 (proxy SSE, WS upgrade, certs Let's Encrypt SAN)ecosystem.config.cjs — config PM2deploy.sh / install.sh / update.sh — scripts d'orchestrationtests/smoke-all.sh — suite de smoke tests (DNS, TLS, /health, SSE MCP, REST, /try, NetClient Java)AGPL-3.0-or-later — usage libre tant que le code dérivé reste open-source.
Licence commerciale disponible : drmdh@msn.com. Pricing par projet, pas par seat.
— (c) 2026 Dr Hamid MADANI <drmdh@msn.com>
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/mosta-net)<a href="https://allmcps.com/mcp/mosta-net"><img src="https://allmcps.com/api/badge/mosta-net?style=directory" alt="Mosta Net on AllMCPs" /></a>