Octonet
Enables Octonet to use Google Cloud Spanner as a cloud-native database backend for entity CRUD operations.
Enables Octonet to use MariaDB as a database backend for entity CRUD operations.
Enables Octonet to use MongoDB as a NoSQL database backend for entity CRUD operations.
Enables Octonet to use MySQL as a database backend for entity CRUD operations.
Enables Octonet to use PostgreSQL as a database backend for entity CRUD operations.
Enables Octonet to use SAP HANA as an enterprise database backend for entity CRUD operations.
Enables Octonet to use SQLite as a database backend for entity CRUD operations.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Octonetlist users from sandbox"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@mostajs/net — Octonet
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.
Table of Contents
Related MCP server: DBHub
What is Octonet
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 :
curl https://octonet.amia.fr/api/v1/User # REST
curl https://octonet.amia.fr/graphql -d '{"query":...}' # GraphQL
wscat -c wss://octonet.amia.fr/ws # WebSocket
curl -N https://octonet.amia.fr/mcp # MCP (Claude Desktop)
# … 7 moreBacked 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 :
#1 —
@mostajs/orm: data persistence (13 databases)#2 — Octonet : multi-protocol transport (11 wire protocols)
#3 — NetClients polyglottes : 14 native client libraries (Java, .NET, Python, Go, Swift, Kotlin, Dart, Rust, PHP, Ruby, Elixir, Lua, Delphi, Unity)
Try in 2 clicks (T1 sandbox)
The fastest way to test Octonet from any of the 14 runtimes :
Pick an alias (e.g.
alice-42)Get an apikey scoped to your sandbox
curl -X POST https://octonet.amia.fr/try \
-H "Content-Type: application/json" \
-d '{"alias":"alice-42"}'
# Response:
{
"status": "ok",
"data": {
"alias": "alice-42",
"projectSlug": "sandbox-alice-42",
"apiKey": "sk_test_…(64 chars, shown ONCE)",
"permissions": { "projects":["sandbox-alice-42"], "operations":["read","write"], "transports":["rest","mcp"] },
"expiresAt": "2026-05-02T18:38:19.920Z",
"quota": { "reqPerDay": 500 },
"exampleCurl": "curl https://octonet.amia.fr/api/v1/sandbox-alice-42/User -H \"X-API-Key: sk_test_…\"",
"mcpUrl": "https://octonet.amia.fr/mcp"
}
}Your sandbox is :
A private SQLite file (isolated from other aliases)
Pre-seeded with
User,Product,OrderentitiesRead+write CRUD via REST and MCP
500 requests/day quota
TTL 7 days (auto-deleted if idle)
Free, no email required, anti-abuse rate-limited (10 sandboxes/h/IP)
Use the apikey in any of the 14 NetClients :
# Java / .NET / Python / Go / etc.
export MOSTAJS_NET_URL=https://octonet.amia.fr
export MOSTAJS_NET_API_KEY=sk_test_…3-tier onboarding model
Tier | Cible | Auth | Quota | Use case |
T1 — Sandbox publique | "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 | "tes données chez toi" | admin local | aucune | enterprise, on-premise, AGPL |
11 transports
Auto-generated from your registered schemas. Toggle each via env var (default : all enabled).
# | Transport | Endpoint | Use case | Notes |
1 | REST |
| universel | 15 routes par entité (CRUD + count + search + aggregate + bulk + relations) |
2 | GraphQL |
| front-end riches | schéma + GraphiQL IDE auto-générés via mercurius |
3 | WebSocket |
| temps réel | events |
4 | SSE |
| mobile / browser-friendly | server-sent events |
5 | JSON-RPC |
| EVM-adjacent, classic | JSON-RPC 2.0 + method discovery |
6 | MCP |
| agents IA (Claude, ChatGPT) | 15 tools/entité auto-générés (listed on mcp.so) |
7 | gRPC |
| inter-services low-latency |
|
8 | tRPC |
| TypeScript fullstack | type generation côté client |
9 | OData |
| SAP/Microsoft Dynamics | OData v4 ($filter, $select, $orderby) |
10 | NATS |
| pub/sub edge | request-reply messaging |
11 | Arrow Flight |
| analytics columnaire | streaming zero-copy |
Le même schéma, 11 portes d'entrée différentes, 0 codegen.
13 databases
Persistence dialects fournis par @mostajs/orm :
Catégorie | Bases | Dialect ID |
SQL mainstream | PostgreSQL, MySQL, MariaDB, SQLite |
|
SQL enterprise | Oracle, SQL Server, DB2, SAP HANA, HSQLDB, Sybase |
|
NewSQL / Cloud | CockroachDB, Google Cloud Spanner |
|
NoSQL | MongoDB |
|
Switch dialect = changer 1 ligne d'env :
DB_DIALECT=postgres → DB_DIALECT=mongodb
SGBD_URI=postgresql://… → SGBD_URI=mongodb://…Multi-tenant authentication
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.
Flux d'auth d'une requête
HTTP Request
│
▼
authGuard (Fastify adapter)
│
▼
checkRequest (@mostajs/auth — framework-agnostic)
│
├─ extract X-API-Key from header / Bearer token / ?apikey=
├─ resolveApiKey (@mostajs/api-keys) — DB lookup + bcrypt verify
├─ isScopeAuthorized (@mostajs/api-keys) — check scope.values
│ for each (scope, value) pair :
│ checks: [{scope:'projects', value:slug},
│ {scope:'operations', value:'read'|'write'|'admin'},
│ {scope:'transports', value:'rest'|'mcp'|...}]
├─ touchApiKey — fire-and-forget : lastUsedAt, usageCount, lastIp
│
▼
ormHandler (entité CRUD) ─→ sanitizer (strip password/hash/tokens)
│
▼
HTTP ResponseScope-based permissions (generic, extensible)
Une apikey a la shape :
{
permissions: {
scopes: {
projects: ['my-project','demo'] | '*', // declared by @mostajs/mproject
operations: ['read','write','admin'] | '*', // declared by @mostajs/orm
transports: ['rest','graphql','mcp'] | '*', // declared by @mostajs/net
// anything: any module can register a new scope
},
rateLimit: 500,
}
}@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).
HTTP status mapping
Cas | HTTP code | Body |
Pas d'apikey | 401 |
|
Apikey invalide / révoquée | 401 |
|
Apikey valide hors scope | 403 |
|
Apikey OK | 200/201 |
|
MCP fallback (compat mcp.so)
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.
Sanitizer
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.
Generic scope registry
Le catalogue des scopes vit en base de données du projet accueillant (pas de fichier JSON, pas de constantes hardcodées) :
-- Auto-créées au boot via @mostajs/api-keys
CREATE TABLE api_key_scopes (
id, name, label, description, icon, cardinality,
valuesSource ('static' | 'dynamic'), dynamicSourceRef
);
CREATE TABLE api_key_scope_values (
id, scopeName, value, label, sortOrder, metadata
);Chaque module enregistre ses scopes au boot :
import { registerScope } from '@mostajs/api-keys/server'
// Dans mosta-net/src/server.ts (boot)
await registerScope(dialect, {
name: 'transports', label: 'Network transports',
cardinality: 'low', valuesSource: 'static',
staticValues: [
{value:'rest', sortOrder:1},
{value:'graphql', sortOrder:2},
// … 9 more
],
})
await registerScope(dialect, {
name: 'projects', label: 'Projects',
cardinality: 'high', valuesSource: 'dynamic',
dynamicSourceRef: 'Project.slug', // queried at runtime
})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/).
Multi-project support
Via @mostajs/mproject — N bases de données isolées sur le même serveur.
Routes path-prefix
# Default project (DB_DIALECT + SGBD_URI au boot)
curl http://localhost:4488/api/v1/User
# Project nommé 'analytics'
curl http://localhost:4488/api/v1/analytics/events
# Ou via header (équivalent)
curl http://localhost:4488/api/v1/events -H "X-Project: analytics"Ajouter un projet à l'exécution
curl -X POST http://localhost:4488/api/projects \
-H "X-API-Key: <admin-key>" \
-d '{
"name": "analytics",
"dialect": "mongodb",
"uri": "mongodb://localhost:27017/analytics",
"schemas": [{"name":"Event", "fields":{"type":"string","ts":"date"}}]
}'Persisté dans projects-tree.json (chemin : MOSTA_PROJECTS env var).
Quick start (self-host)
Install
npm install @mostajs/net @mostajs/orm @mostajs/mproject \
@mostajs/rbac @mostajs/auth @mostajs/api-keys \
@mostajs/config better-sqlite3Run with SQLite (zero infra)
DB_DIALECT=sqlite \
SGBD_URI=./data/octonet.db \
DB_SCHEMA_STRATEGY=update \
OCTONET_ADMIN_EMAIL=admin@example.com \
OCTONET_ADMIN_PASSWORD=ChangeMe123! \
npx mostajs-net serveConsole output :
Loaded 3 schemas from schemas.json
[DAL:SQLite] INIT_SCHEMA strategy=update {"entities":["User","Product","Order"]}
✓ Apikey scopes registered (projects, operations, transports)
✓ RBAC ready — admin=admin@example.com trial=… public=…
⚠ public demo apikey emitted ONCE → sk_live_xxxxxxxx… (save it!)
✓ Sanitizer middleware on rest, graphql, ws, sse, trpc, mcp, odata, jsonrpc
✓ ApiKey middleware on rest, graphql, ws, sse, trpc, mcp, odata, jsonrpc
✓ Protected ormHandler ready (sanitizer + apikey global wrapper)
✓ T1 sandbox endpoint /try ready (rate-limited 10/h/IP, TTL 7d)
@mostajs/net v2.6.x
─────────────────────────────────────────────────
Dialect: sqlite (./data/octonet.db)
Entities: User, Product, Order (3)
Port: 4488
Strategy: update
Transports: rest, graphql, ws, sse, trpc, mcp, odata, jsonrpc (8)
Ready. 3 entities × 8 transports = 24 endpointsTest
# Sans apikey → 401
curl http://localhost:4488/api/v1/User
# {"error":{"code":"UNAUTHORIZED","message":"API key required…"}}
# Avec apikey publique (depuis les logs ↑)
curl http://localhost:4488/api/v1/User -H "X-API-Key: sk_live_…"
# {"status":"ok","data":[{"id":"…","email":"admin@example.com",…}]} ← password absentConfiguration (.env)
Database (mandatory)
DB_DIALECT=postgres # any of 13 dialects
SGBD_URI=postgresql://user:pass@localhost:5432/db
DB_SCHEMA_STRATEGY=update # 'update' (recommandé prod) | 'create' (drop+recreate, dev only)
DB_SHOW_SQL=falseSystem dialect (recommandé prod, optionnel) — v2.7.5+
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).
MOSTA_SYSTEM_DIALECT=postgres # any of 13 dialects
MOSTA_SYSTEM_URI=postgresql://user:pass@localhost:5432/octonet_systemVoir section System dialect ci-dessous pour la motivation et les how-to.
Server
MOSTA_NET_PORT=4488
MOSTA_PROJECTS=./projects-tree.json # path to multi-project config
SCHEMAS_PATH=./schemas # directory scanning fallbackTransports (toggle each)
MOSTA_NET_REST_ENABLED=true
MOSTA_NET_GRAPHQL_ENABLED=true
MOSTA_NET_WS_ENABLED=true
MOSTA_NET_SSE_ENABLED=true
MOSTA_NET_JSONRPC_ENABLED=true
MOSTA_NET_MCP_ENABLED=true
MOSTA_NET_TRPC_ENABLED=true
MOSTA_NET_ODATA_ENABLED=true
MOSTA_NET_GRPC_ENABLED=false
MOSTA_NET_NATS_ENABLED=false
MOSTA_NET_ARROW_ENABLED=false
MOSTA_NET_CORS_ORIGIN=*
MOSTA_RATE_LIMIT_CLIENT=1000RBAC bootstrap (lus via @mostajs/config — supports profile cascade MOSTA_ENV=DEV)
OCTONET_ADMIN_EMAIL=admin@example.com # 1er boot only ; ignored after
OCTONET_ADMIN_PASSWORD=secret-12345
OCTONET_ADMIN_FIRSTNAME=Admin # optional
OCTONET_ADMIN_LASTNAME=Octonet # optional
OCTONET_BOOTSTRAP_VERBOSE=false # detailed bootstrap logs
OCTONET_OPEN_MODE=false # dev only — passe sans apikeyT1 sandbox (optional)
OCTONET_TRIAL_DATA_DIR=./data/trials # SQLite files per aliasCloud middleware (optional, futur — partage DB méta avec Octocloud)
OCTONET_META_URI=postgresql://user:pass@localhost:5432/octonet_meta # shared meta DB
PORTAL_DB_URI=postgresql://user:pass@localhost:5432/octonet_cloud # legacy octocloud DBAPI endpoints reference
Public
Endpoint | Méthode | Auth | Description |
| GET | open | server status + transports + entities |
| GET | open | T1 sandbox provisioning HTML form |
| POST | open (rate-limit 10/h/IP) | crée sandbox + retourne apikey one-shot |
| GET | open | health under api-versioned path |
Project / entity CRUD (requires apikey)
Endpoint | Méthode | Op | Description |
| GET | findAll | list entities of default project |
| GET | findById | get one |
| GET | count | count |
| GET | findOne | first match |
| GET | search | text search |
| POST | create | insert |
| PUT | update | replace |
| DELETE | delete | remove |
| POST | addToSet | add to array |
| POST | pull | remove from array |
| POST | increment | numeric add |
| POST | upsert | insert or update |
| POST | aggregate | pipeline |
| POST | updateMany | bulk update |
| POST | deleteMany | bulk delete |
| * | * | same routes scoped to a project |
Schema management (requires admin apikey)
Endpoint | Méthode | Description |
| POST | push schemas at runtime (triggers reload) |
| POST | apply schema diff |
| POST | dry-run schema diff |
| GET | current registered schemas |
Auth & API keys (requires admin)
Endpoint | Méthode | Description |
| GET / POST | list / issue keys |
| PUT / DELETE | update / revoke |
| GET | list registered scopes + values (for admin matrix UI) |
| POST | register a new scope (admin) |
| PUT / DELETE | manage scope values |
Transports natifs
Endpoint | Description |
| GraphQL endpoint + GraphiQL IDE |
| WebSocket connection (entity events) |
| SSE stream |
| JSON-RPC 2.0 |
| Model Context Protocol (Claude/Smithery/etc.) |
| tRPC procedure |
| OData v4 |
Multi-project management
Endpoint | Méthode | Description |
| GET | list projects |
| POST | add project |
| PUT / DELETE | edit / remove |
Observability
Endpoint | Description |
| live metrics (req/s, p50, p99) |
| configuration tree (interactive) |
| streaming log feed |
Architecture
┌──────────────────────────────────┐
│ Fastify (port 4488) │
└────────────────┬─────────────────┘
│
┌─────────────────────────────────────────┴──────────────────────────────┐
│ │
▼ ▼
┌────────────────────────┐ ┌────────────────────────┐
│ Transports (11) │ │ Direct Fastify routes │
│ - REST │ │ - /try │
│ - GraphQL (mercurius) │ │ - /api/projects/* │
│ - WS │ │ - /api/api-keys/* │
│ - SSE │ │ - /health, /metrics │
│ - JSON-RPC │ └────────────────────────┘
│ - MCP (SDK Anthropic) │
│ - gRPC │ ┌─────────────────────────────────────┐
│ - tRPC │ │ Auth pipeline │
│ - OData │ │ ┌──────────────┐ │
│ - NATS │ │ │ extractAuth │ ← HTTP request │
│ - Arrow ├──────────────┤ │ Context │ │
└────────────────────────┘ │ └──────┬───────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ checkRequest │ ← scope-checks │
│ │ (mosta-auth) │ │
│ └──────┬───────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ checkApiKey │ ← resolve+verify │
│ │ (api-keys) │ │
│ └──────┬───────┘ │
└─────────┼───────────────────────────┘
▼
┌────────────────────────┐
│ Sanitizer middleware │
│ strips password/hash/ │
│ tokens before response │
└────────┬───────────────┘
▼
┌────────────────────────┐
│ ormHandler │
│ → ProjectManager.resolve│
│ → EntityService.execute │
└────────┬───────────────┘
▼
┌────────────────────────┐
│ @mostajs/orm dialect │
│ (13 SGBD) │
└────────────────────────┘Modules de l'écosystème consommés
Module | Rôle dans Octonet |
| persistance (13 dialects) |
| gestion multi-projet (default + sandbox + abonnés) |
| identité (User, Role, Permission, Account) + AccountSchema + OCTONET_RBAC_SEED |
|
|
| apikey CRUD + scopes ( |
| env var helper avec cascade |
| quota / abonnement (optionnel — actif si Octocloud connecté) |
| CQRS multi-replica (optionnel) |
| persistence schemas Project (optionnel — si stockage SGBD vs JSON) |
System dialect (séparé du singleton métier)
Disponible depuis v2.7.5 — résout le bug « apikeys introuvables après
/api/change-dialect» observé en prod.
Pourquoi deux dialects distincts ?
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) |
| Oui (IHM admin) |
|
Système (infra Octonet) |
| Non (stable) | RBAC, apikey-middleware, account-scope, auth guards, sandbox /try |
Configuration recommandée (prod multi-base)
# Métier — peut bouger via /api/change-dialect
DB_DIALECT=postgres
SGBD_URI=postgresql://hmd:***@127.0.0.1:5432/octonet_business
# Système — stable, jamais touché par les routes admin
MOSTA_SYSTEM_DIALECT=postgres
MOSTA_SYSTEM_URI=postgresql://hmd:***@127.0.0.1:5432/octonet_systemConfiguration mono-base (dev / déploiement simple)
Laisser MOSTA_SYSTEM_* vides → alias automatique vers le singleton métier (rétro-compat 100 %, comportement identique au pré-v2.7.5).
How-to
1. Migrer un déploiement existant vers le mode multi-base
# 1. Sauvegarder la base actuelle
pg_dump octonet_business > backup-pre-split.sql
# 2. Créer la base système (vide — RBAC seed re-exécute au boot)
createdb octonet_system
# 3. Ajouter MOSTA_SYSTEM_* dans .env
echo 'MOSTA_SYSTEM_DIALECT=postgres' >> .env.local
echo 'MOSTA_SYSTEM_URI=postgresql://hmd:***@127.0.0.1:5432/octonet_system' >> .env.local
# 4. Restart Octonet — le bootstrap RBAC + scopes seed sur octonet_system
pm2 restart octonet-mcp
# 5. Restaurer les apikeys et RBAC users de l'ancienne base
# (à scripter selon convention métier — typiquement export/import des
# tables api_keys, users, roles, permissions, scopes, scope_values)2. Vérifier que le système est bien isolé du métier
# Avant /api/change-dialect : apikey doit fonctionner
curl -H "X-API-Key: sk_live_…" http://localhost:4488/api/auth/verify
# → 200 OK
# Bouger le dialect métier vers SQLite
curl -X POST -H "Content-Type: application/json" \
-d '{"dialect":"sqlite","uri":":memory:","connect":true}' \
http://localhost:4488/api/change-dialect
# → "Dialecte changé et connecté : sqlite"
# Re-tester l'apikey — DOIT toujours fonctionner (système intact)
curl -H "X-API-Key: sk_live_…" http://localhost:4488/api/auth/verify
# → 200 OK (bug résolu en v2.7.5)Avant v2.7.5, le 2ᵉ curl retournait 503 metadata DB unavailable ou 401 PostgreSQL not connected. Call connect() first.
3. Lire le system dialect depuis du code applicatif
import { getSystemDialect } from '@mostajs/data-plug'
const sysDialect = await getSystemDialect()
// Utiliser comme un dialect normal pour requêter les tables système
// (apikeys, users, roles, audit_log, plans, etc.)4. Inspecter le bootstrap au démarrage
Au boot d'octonet-mcp, deux logs apparaissent :
✓ DB connectée: postgres ← métier
✓ System dialect: postgres (octonet_system) ← système (si MOSTA_SYSTEM_* défini)
✓ RBAC ready — admin=… trial=… public=… ← seed côté système
✓ ApiKey middleware on REST/SSE/GraphQL/... ← câblé sur systèmeSites système dans 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 |
|
Scopes register | 4 |
|
Middlewares globaux | 2 |
|
Middlewares per-transport | 2 | idem appliqués sur chaque |
Auth guards transports | 6 |
|
Custom | 2 |
|
Sandbox | 2 |
|
Le dialect métier (dialect) reste utilisé légitimement pour :
Bootstrap initial du singleton métier (
L98) +pm.setDefault('default', dialect, …)(L126,L240)Routes admin
/api/reconnect,/api/change-dialect,/api/reload-config,/api/test-connection,/api/truncate-tables,/api/drop-tables— toutes opérations explicitement métierEntityServicequi sert les entités userland (opérations CRUD via les transports protégés)
Étapes du chantier (historique)
Étape | Repo | Livré |
1 |
| npm |
2 |
| git |
3 |
| npm |
4 |
| git |
5 | Tests d'intégration scénario | ⏳ |
6 | Déploiement amia + smoke test | ⏳ |
Boot sequence
Load
.envvia@mostajs/config(profile cascadeMOSTA_ENV)Connect main dialect (
SGBD_URI)Load schemas (priority :
getAllSchemas()registry →schemas.json→SCHEMAS_PATHdirectory scan)dialect.initSchema(schemas)with strategyupdate/createBootstrap RBAC (
octonet-rbac-bootstrap.ts) :register UserSchema/RoleSchema/PermissionSchema/PermissionCategorySchema/AccountSchema/ApiKeySchema
seedRBAC(OCTONET_RBAC_SEED)— 6 categories, 25 permissions, 4 roles (admin/subscriber/trial/public)createAdmin()fromOCTONET_ADMIN_EMAIL/PASSWORDcreate Account
trial-playground(type='trial')create User
public-demo(role=public)create Account
public-system(type='system')generate ApiKey
public-defaultscoped todefaultproject (read-only, REST + MCP) — emitted ONCE in clear
Register canonical scopes :
projects(dynamic,Project.slug),operations(static : read/write/admin),transports(static : 11 values)Push default project to
projects-tree.json(ownerId=admin, visibility=public)Load additional projects from
projects-tree.jsonWrap ormHandler with
composeMiddleware([sanitizer, apikey], ormHandler)→protectedOrmHandlerStart each enabled transport :
transport.use(loggingMiddleware)transport.use(sanitizerMiddleware)transport.use(apiKeyMiddleware)transport.setHandler(ormHandler)transport.start(config)
Register Fastify routes :
registerDynamicRestRoutes(app, protectedOrmHandler, pm)—/api/v1/...registerProjectRoutes(app, pm, protectedOrmHandler)—/:project/*registerTryRoutes(app, {dialect, pm})—/tryPOSTregisterTryPage(app)—/tryGET (HTML)startTrialCleanupJob({dialect, pm})— cron horaire TTL 7j
Listen on port (
MOSTA_NET_PORT)
14 polyglot NetClients
Octonet est consommable depuis 14 runtimes natifs, avec la même apikey, la même URL :
Runtime | Package | Registre |
Node/TS |
| npm |
Java |
| Maven Central |
Java + Spring Boot |
| Maven Central |
.NET |
| NuGet |
Python |
| PyPI |
Go |
| pkg.go.dev |
Swift |
| Swift Package Index |
Kotlin |
| Maven Central |
Dart / Flutter |
| pub.dev |
Rust |
| crates.io |
PHP |
| Packagist |
Ruby |
| RubyGems |
Elixir |
| Hex.pm |
Lua |
| LuaRocks |
Delphi |
| GetIt |
Unity (C#) |
| OpenUPM |
Monorepo : github.com/apolocine/mosta-net-clients
Chaque NetClient suit le même contrat d'API :
NetClient.create()
.url(...)
.apiKey(...)
.build()
.findAll(entity, filter, options)
.findById(entity, id)
.create(entity, data)
.update(entity, id, data)
.delete(entity, id)
.uploadSchemasJson(schemas)
.health()Production deploy (amia.fr)
Le déploiement de référence tourne sur octonet.amia.fr + mcp.amia.fr (alias compat) en backend PostgreSQL :
URL | Rôle |
| Octonet server (REST, MCP, GraphQL, WS, SSE, tRPC, OData, JSON-RPC) |
| alias DNS de compatibilité — historique mcp.so |
| 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)
CLI
npx mostajs-net serve # Start server
npx mostajs-net mcp # MCP-only mode
npx mostajs-net generate-apikey <label> # Émettre une apikey via CLI
npx mostajs-net hash-password <password> # Hash bcrypt
npx mostajs-net info # JSON config dump
npx octonet-mcp --dialect=X --uri=Y # Standalone MCP server (process séparé)License
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>
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/apolocine/mosta-net'
If you have feedback or need assistance with the MCP directory API, please join our Discord server