# @mostajs/net — fiche LLM > Serveur de transport multi-protocole pour @mostajs/orm : expose un schéma d'entités via REST, GraphQL, WebSocket, SSE, JSON-RPC, MCP (+ gRPC, tRPC, OData, Arrow Flight, NATS). - Version: 2.7.6 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI - Chemin: mostajs/mosta-net · Statut audit: complet (dist/) - Nom de marque: « Octonet ». Repo: github.com/apolocine/mosta-net ## RÔLE Couche transport (« second lobe » de la trilogie orm → net → NetClients) du socle @mostajs. Prend un schéma EntitySchema de @mostajs/orm et le publie simultanément sur N protocoles réseau, avec auth multi-tenant (API keys), routage multi-projet et middlewares chaînables. Fournit un serveur Fastify clé en main (startServer / CLI mostajs-net) plus des classes de transport unitaires réutilisables. Inclut un binaire MCP (octonet-mcp) pour Claude Desktop. ## INSTALLATION npm i @mostajs/net ## EXPORTS - Transports (classes): RestTransport, SSETransport, GraphQLTransport, WebSocketTransport, JsonRpcTransport, McpTransport - Coeur transport: getTransport, getActiveTransports, stopAllTransports, composeMiddleware, loggingMiddleware - Config: loadNetConfig, getEnabledTransports, TRANSPORT_NAMES - Serveur: startServer, createSandboxServer (default de mcp-cli) - Auth/API keys: readApiKeys, writeApiKeys, generateApiKey, hashApiKey, createSubscription, revokeSubscription, validateApiKey, checkPermission, createApiKeyMiddleware, createSanitizerMiddleware - Schémas: loadSchemasFromJson, scanSchemaDirs, generateSchemasJson, getSchemasConfig, parseSchemasFromZip - Types: ITransport, TransportConfig, TransportInfo, TransportContext, TransportMiddleware, NetServerConfig, TransportName, NetServer, Subscription, ApiKeysFile ## EXPORTS PAR SOUS-CHEMIN - @mostajs/net/client : NetClient, createNetDialectProxy (ré-export de @mostajs/net-client-js) ; types NetClientConfig, QueryOptions, CompareSchemaResult - @mostajs/net/middleware/cloud-hook : cloudHook (singleton — setMiddleware/removeMiddleware/isEnabled/process/getMiddleware), type CloudMiddlewareFn - @mostajs/net/middleware/transport-filter : transportFilter (singleton — autorise/restreint des transports par projet) - @mostajs/net/middleware/admin-auth : createAdminAuth(config), interface AdminAuthConfig (Basic Auth + API key) - @mostajs/net/middleware/project-metrics : projectMetrics (singleton — recordRequest, getMetrics, getSummary…), interface ProjectMetrics ## API — SIGNATURES - startServer(): Promise // lit .env.local MOSTA_NET_*, connecte l'ORM, démarre les transports activés - loadNetConfig(): NetServerConfig - getEnabledTransports(config): TransportName[] - getTransport(name: TransportName, config: TransportConfig): Promise - getActiveTransports(): ITransport[] ; stopAllTransports(): Promise - composeMiddleware(middlewares: TransportMiddleware[], handler): (req, ctx) => Promise - generateApiKey(mode?: 'live'|'test'): string // préfixe msk_live_ / msk_test_ - createSubscription(name, permissions?, mode?): { subscription, clearKey } // clearKey affiché une seule fois - validateApiKey(key): Subscription | null - checkPermission(sub, dialect, transport, op: 'r'|'c'|'u'|'d'): boolean ## TYPES CLÉS - TRANSPORT_NAMES = ['rest','grpc','graphql','ws','sse','trpc','mcp','odata','arrow','jsonrpc','nats'] - ITransport { name; start(config); stop(); registerEntity(schema); use(mw); getInfo(): TransportInfo } - TransportConfig { enabled: boolean; port?: number; path?: string; options?: Record } - TransportContext { transport; apiKey?; subscription?; permissions?; projectName?; meta? } - TransportMiddleware = (req: OrmRequest, ctx: TransportContext, next) => Promise - NetServerConfig { port: number; transports: Record } - NetServer { app: FastifyInstance; entityService; pm: ProjectManager; rm; stop() } - Subscription { name; key; hash; created; status: 'active'|'revoked'; permissions: Record> } ## PATTERN ```ts import { startServer } from '@mostajs/net'; const net = await startServer(); // serveur Fastify multi-protocole prêt // arrêt propre : await net.stop(); ``` Client polyglotte : ```ts import { NetClient } from '@mostajs/net/client'; const client = new NetClient({ baseUrl: 'http://localhost:4488', apiKey: 'msk_live_…' }); ``` CLI : `npx mostajs-net serve` · MCP : binaire `octonet-mcp`. ## DÉPEND DE - Dépendances runtime @mostajs: @mostajs/data-plug, @mostajs/net-client-js - Peers @mostajs (tous optionnels sauf @mostajs/mproject et @mostajs/orm): @mostajs/orm, @mostajs/mproject, @mostajs/auth, @mostajs/api-keys, @mostajs/rbac, @mostajs/config, @mostajs/cloud-middleware, @mostajs/project-life, @mostajs/replicator - Externes: fastify, @fastify/cors, graphql, mercurius, ws, nats, pg, mongoose, @modelcontextprotocol/sdk ## PIÈGES - Configuration par env uniquement : MOSTA_NET_{TRANSPORT}_ENABLED / _PORT / _PATH ; l'ORM via MOSTA_ORM_* + DB_DIALECT + SGBD_URI. startServer() lit .env.local, aucun argument de config. - getTransport() renvoie null si le transport n'est pas activé en config — toujours tester le retour. - createSubscription retourne clearKey une seule fois ; seul le hash est persisté dans .mosta/apikeys.json. - cloudHook / transportFilter / projectMetrics sont des singletons à état mutable global, pas des classes à instancier. - Le `projectName` du TransportContext est le nom unique du projet, pas un ID numérique. - v2.7.5 marquée « unreleased » dans le CHANGELOG : chantier « system dialect séparé du singleton métier » — les consumers système utilisent getSystemDialect() (stable) et non le dialect métier mutable. - **Champs `type:"date"` sérialisés en `{}` côté HTTP — corrigé en 2.7.6** (présent dans toute version npm ≤ 2.7.5). Symptôme : `createdAt: {}`, `updatedAt: {}`, tout `timestamp` métier devenait un objet vide dans la réponse REST, alors que l'ORM hydrate bien une `Date` JS (`instanceof Date === true`). Cause racine : `sanitizer-middleware::stripFields()` rebuild un plain object via `Object.keys(value)` — `Object.keys(new Date()) === []`, donc la Date sortait à vide ; idem pour `RegExp`, `Buffer`, BSON `ObjectId`, `Map`, `Set`. Fix 2.7.6 : garde `isNonPlainObject(value)` qui renvoie la valeur inchangée, laissant Fastify appliquer `Date.toJSON() → ISO`. Diagnostic reproductible : `test-scripts/diagnose-date-serialization.mjs`. ## TESTS / DIAGNOSTICS - `test-scripts/_test-server.mjs` : serveur @mostajs/net minimal (2 entités) pour smoke local. - `test-scripts/smoke-system-isolation.sh`, `test-scripts/test-replicator-*.sh` : scénarios d'intégration. - `test-scripts/diagnose-date-serialization.mjs` : compare la lecture d'un champ `type:"date"` via `EntityService.execute` (chemin ORM pur) **et** via fetch HTTP loopback du serveur — diagnostique si le bug Date→`{}` vient de l'ORM ou de la couche HTTP @mostajs/net. Réutilisable sur tout projet qui expose un `schemas.json` et un serveur @mostajs/net local. ## RÉFÉRENCES - README.md (présentation Octonet, 11 transports, onboarding 3 tiers, déploiement) - CHANGELOG.md (v2.7.5) - MCP.md, smithery.yaml, server.json (intégration MCP) - docs/