mcpField
O
Octonet Mcp

Octonet Mcp

远程服务
github.com/apolocine数据库021 周前更新

关于 Octonet Mcp

Octonet 是 Node.js 服务端,可将同一 ORM 模式通过 11 种网络协议开放,供使用 13 种数据库的应用和 AI Agent 接入。它集成多租户 API 密钥认证与 RBAC,并自动生成接口,包括 MCP。

主要功能

  1. 01同一模式支持 11 种协议
  2. 02支持 13 种数据库
  3. 03自动生成 CRUD 与查询工具
  4. 04多租户 API 密钥与 RBAC
  5. 05多项目数据库路由

适用场景

  1. 01通过 MCP 向 AI Agent 开放数据库实体
  2. 02通过 REST 和 GraphQL 提供相同数据
  3. 03将不同项目路由至隔离数据库

MCP 相关

Octonet 通过 MCP 端点开放根据模式生成的实体工具。API 密钥权限范围可按项目、操作和传输协议限制访问;公共密钥回退仅支持读取。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"apolocine-mosta-net": {
"command": "npx",
"args": [
"-y",
"@mostajs/net"
]
}
}
}
启动命令npx -y @mostajs/net

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@mostajs/net2.0.42

工具

45

收录的工具列表 · 更新于 2 周前

参数类型必填说明
filterstring否JSON 筛选对象(MongoDB 风格)
limitnumber否返回结果的最大数量
skipnumber否要跳过的结果数
sortstring否JSON 排序对象,例如 {"name":1}

详细介绍

@mostajs/net — Octonet

开箱即用:一种架构、11 种传输方式、13 个数据库、多租户身份验证。 面向 @mostajs 生态系统、由架构驱动的多协议 API 服务端。基于 TypeScript 和 Fastify 构建,支持多语言调用(14 个原生 NetClient)。

Octonet 标志

npm License mcp.so

作者:Dr Hamid MADANI <[email protected]> 主页:octonet.amia.fr · mcp.amia.fr


Octonet 技术栈如同电源插座:@mostajs/orm 接入 13 个数据库,@mostajs/net(Octonet)通过 11 种传输方式重新提供这些数据,Data-Plug 在两者之间搭建桥梁,而 NetClient 扩展为 18 种语言的客户端,供任何外部应用使用。

插座板。 @mostajs/orm 连接到 13 个数据库;Octonet (@mostajs/net)通过 11 种传输方式(REST、 WebSocket、gRPC、MQTT、AMQP……)重新提供相同的实体;随后 NetClient 扩展为 18 种语言的 客户端——让任何外部应用都能在任意运行时接入你的数据。


目录

  1. 什么是 Octonet
  2. 两步体验(T1 沙盒)
  3. 三级入门模式
  4. 11 种传输方式
  5. 13 个数据库
  6. 多租户身份验证
  7. 通用范围注册表
  8. 多项目支持
  9. 快速开始(自托管)
  10. 配置(.env)
  11. API 端点参考
  12. 架构
  13. 启动顺序
  14. 14 个多语言 NetClient
  15. 生产环境部署(amia.fr)
  16. 许可证

什么是 Octonet

Octonet(@mostajs/net)是一个 Node.js 多传输服务端,可将单个 @mostajs/orm 架构同时公开为 11 种不同的网络协议:REST、GraphQL、WebSocket、SSE、JSON-RPC、MCP、gRPC、tRPC、OData、NATS、Arrow Flight。

同一个 User 实体可通过以下方式访问:

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 more

底层由 @mostajs/orm 提供支持(支持 13 种数据库方言)。多租户身份由 @mostajs/rbac + @mostajs/auth + @mostajs/api-keys 提供支持。多项目路由由 @mostajs/mproject 提供支持。

Octonet 是 @mostajs 三部曲的第二个大脑叶:

  • #1 — @mostajs/orm:数据持久化(13 个数据库)
  • #2 — Octonet:多协议传输(11 种线协议)
  • #3 — 多语言 NetClient:14 个原生客户端库(Java、.NET、Python、Go、Swift、Kotlin、Dart、Rust、PHP、Ruby、Elixir、Lua、Delphi、Unity)

两步体验(T1 沙盒)

从 14 种运行时中的任何一种测试 Octonet,最快只需:

  1. 打开 https://octonet.amia.fr/try
  2. 选择一个别名(例如 alice-42)
  3. 获取一个作用于你的沙盒的 apikey
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"
  }
}

你的沙盒具有以下特性:

  • 一个私有的 SQLite 文件(与其他别名隔离)
  • 预先填充了 User、Product、Order 实体
  • 通过 REST 和 MCP 执行读写 CRUD 操作
  • 每日限额为 500 个请求
  • 有效期为 7 天(闲置时自动删除)
  • 免费,无需电子邮件,并设有防滥用速率限制(每个 IP 每小时最多 10 个沙盒)

在任意一个 14 个 NetClient 中使用 apikey:

# Java / .NET / Python / Go / etc.
export MOSTAJS_NET_URL=https://octonet.amia.fr
export MOSTAJS_NET_API_KEY=sk_test_…

3 层入门模式

层级目标用户身份验证配额使用场景
T1 — 公共沙盒 /try“我想在 10 分钟内试用”仅别名(无需邮箱)每天 500 次请求,TTL 7 天NetClients 演示、集成测试
T2 — 注册账户 octocloud.amia.fr“我确实要用,免费”邮箱 + 密码每天 10 000 次请求个人应用、业余项目
T3 — 自托管 npx @mostajs/net init“数据留在你自己这里”本地管理员无企业、内部部署、AGPL

11 种传输方式

根据已注册的架构自动生成。可通过环境变量逐一启用或停用(默认全部启用)。

#传输方式端点使用场景备注
1REST/api/v1/{Entity} · /api/v1/{project}/{Entity}通用每个实体 15 个路由(CRUD + count + search + aggregate + bulk + relations)
2GraphQL/graphql (POST)丰富的前端通过 mercurius 自动生成架构 + GraphiQL IDE
3WebSocketwss://…/ws实时广播 entity.created/updated/deleted/upserted 事件
4SSE/events (GET stream)适用于移动设备 / 浏览器服务器发送事件
5JSON-RPC/rpc (POST)EVM 相邻领域、经典用途JSON-RPC 2.0 + 方法发现
6MCP/mcp (POST/GET SSE)AI Agent(Claude、ChatGPT)每个实体自动生成 15 个工具(在 mcp.so 上列出)
7gRPC:50051低延迟服务间通信自动生成 .proto,每个实体 6 个 RPC
8tRPC/trpc/{Entity}.{op}TypeScript 全栈在客户端生成类型
9OData/odata/{Collection} (+ $metadata)SAP/Microsoft DynamicsOData v4 ($filter、$select、$orderby)
10NATSmostajs.{Entity}.{op}边缘发布/订阅请求-响应消息传递
11Arrow Flight/arrow/*列式分析零拷贝流式传输

同一套架构,11 个不同入口,0 代码生成。


13 种数据库

由 @mostajs/orm 提供的持久化方言:

类别数据库方言 ID
主流 SQLPostgreSQL、MySQL、MariaDB、SQLitepostgres、mysql、mariadb、sqlite
企业级 SQLOracle、SQL Server、DB2、SAP HANA、HSQLDB、Sybaseoracle、mssql、db2、hana、hsqldb、sybase
NewSQL / 云CockroachDB、Google Cloud Spannercockroachdb、spanner
NoSQLMongoDBmongodb

切换方言 = 更改 1 行环境变量:

DB_DIALECT=postgres → DB_DIALECT=mongodb
SGBD_URI=postgresql://… → SGBD_URI=mongodb://…

多租户身份验证

Octonet 使用基于 带作用域的 API 密钥(面向机器间通信)的身份验证中间件,以及用于人工管理的 RBAC。与具体实现无关的协调器位于 @mostajs/auth/lib/check-request.ts。

请求的身份验证流程
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 Response
基于作用域的权限(通用、可扩展)

API 密钥的结构如下:

{
  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 并不知道 projects/operations/transports 这些名称——这是有意为之。每个模块都会在启动时通过 registerScope(dialect, {name, label, …}) 注册其作用域。检查过程是通用的:isScopeAuthorized(perms, scope, value)。

HTTP 状态码映射
情况HTTP 代码Body
没有 API 密钥401{error: {code:'UNAUTHORIZED', message:'API key required…'}}
API 密钥无效 / 已撤销401{error: {code:'UNAUTHORIZED', message:'Invalid or revoked API key'}}
API 密钥有效,但超出作用域403{error: {code:'FORBIDDEN', message:'API key not authorized for X="Y"'}}
API 密钥有效200/201{status:'ok', data: …}(已净化——不含密码 / 哈希)
MCP 回退(兼容 mcp.so)

当未提供密钥时,/mcp 端点会自动回退使用标记为 public-default 的 API 密钥——以保留与 mcp.so / Claude Desktop 的兼容性。此公共密钥仅对 default 项目具有只读权限 → 禁止写入。

清理器

password、hash、verifyToken、resetToken、apiKeyHash、secret、privateKey 字段会由全局中间件从所有 JSON 响应中自动剥离。通过 /api/v1/User?limit=1 不会有数据泄露风险。


通用作用域注册表

作用域目录存储在接入项目的数据库中(不是 JSON 文件,也不是硬编码常量):

-- 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
);

每个模块在启动时注册其作用域:

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
})

管理界面通过 GET /api/api-keys/scopes 加载动态目录,并呈现为矩阵(@mostajs/api-keys/components/ 中的 React 组件 ApiKeyScopeMatrix)。


多项目支持

通过 @mostajs/mproject,在同一台服务器上使用 N 个相互隔离的数据库。

路径前缀路由
# 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"
在运行时添加项目
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"}}]
  }'

持久化在 projects-tree.json 中(路径:MOSTA_PROJECTS 环境变量)。


快速开始(自托管)

安装
npm install @mostajs/net @mostajs/orm @mostajs/mproject \
            @mostajs/rbac @mostajs/auth @mostajs/api-keys \
            @mostajs/config better-sqlite3
使用 SQLite 运行(无需基础设施)
DB_DIALECT=sqlite \
SGBD_URI=./data/octonet.db \
DB_SCHEMA_STRATEGY=update \
[email protected] \
OCTONET_ADMIN_PASSWORD=ChangeMe123! \
npx mostajs-net serve

控制台输出:

Loaded 3 schemas from schemas.json
[DAL:SQLite] INIT_SCHEMA strategy=update {"entities":["User","Product","Order"]}
✓ Apikey scopes registered (projects, operations, transports)
✓ RBAC ready — [email protected] 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 endpoints
测试
# 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":"[email protected]",…}]}  ← password absent

配置(.env)

数据库(必填)
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=false
系统方言(生产环境推荐,可选)— v2.7.5+

将系统数据库(apikeys、RBAC 用户、审计、套餐、付款、项目生命周期元数据)与可变的业务方言分离。如果不设置这些变量,则透明地别名到单例业务数据库(向后兼容单数据库模式)。

MOSTA_SYSTEM_DIALECT=postgres                       # any of 13 dialects
MOSTA_SYSTEM_URI=postgresql://user:pass@localhost:5432/octonet_system

有关动机和操作指南,请参阅下文的独立系统方言部分。

服务器
MOSTA_NET_PORT=4488
MOSTA_PROJECTS=./projects-tree.json                # path to multi-project config
SCHEMAS_PATH=./schemas                              # directory scanning fallback
传输方式(分别切换)
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=1000
RBAC 引导配置(通过 @mostajs/config 读取——支持配置级联 MOSTA_ENV=DEV)
[email protected]               # 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 apikey
T1 沙盒(可选)
OCTONET_TRIAL_DATA_DIR=./data/trials                # SQLite files per alias
云中间件(可选,未来支持——与 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 DB

API 端点参考

公开端点
端点方法身份验证描述
/healthGET公开服务器状态 + 传输方式 + 实体
/tryGET公开T1 沙盒配置 HTML 表单
/tryPOST公开(每个 IP 每小时限 10 次)创建沙盒 + 返回一次性 apikey
/api/v1/healthGET公开API 版本化路径下的健康状态
项目 / 实体 CRUD(需要 apikey)
端点方法操作描述
/api/v1/{Entity}GETfindAll列出默认项目中的实体
/api/v1/{Entity}/:idGETfindById获取单个实体
/api/v1/{Entity}/countGETcount计数
/api/v1/{Entity}/oneGETfindOne获取第一条匹配项
/api/v1/{Entity}/searchGETsearch文本搜索
/api/v1/{Entity}POSTcreate插入
/api/v1/{Entity}/:idPUTupdate替换
/api/v1/{Entity}/:idDELETEdelete删除
/api/v1/{Entity}/:id/addToSetPOSTaddToSet添加到数组
/api/v1/{Entity}/:id/pullPOSTpull从数组中移除
/api/v1/{Entity}/:id/incrementPOSTincrement数值递增
/api/v1/{Entity}/upsertPOSTupsert插入或更新
/api/v1/{Entity}/aggregatePOSTaggregate聚合管道
/api/v1/{Entity}/updateManyPOSTupdateMany批量更新
/api/v1/{Entity}/deleteManyPOSTdeleteMany批量删除
/api/v1/{project}/{Entity}/…**作用域限定到项目的相同路由
模式管理(需要管理员 apikey)
端点方法描述
/api/upload-schemas-jsonPOST在运行时推送模式(触发重新加载)
/api/apply-schemaPOST应用模式差异
/api/compare-schemaPOST试运行模式差异
/api/schemas-configGET当前已注册的模式
身份验证和 API 密钥(需要管理员权限)
端点方法描述
/api/api-keysGET / POST列出 / 签发密钥
/api/api-keys/:idPUT / DELETE更新 / 撤销
/api/api-keys/scopesGET列出已注册的作用域及其值(供管理员矩阵 UI 使用)
/api/api-keys/scopesPOST注册新的作用域(管理员)
/api/api-keys/scopes/:name/valuesPUT / DELETE管理作用域值
原生传输方式
端点描述
/graphqlGraphQL 端点 + GraphiQL IDE
/wsWebSocket 连接(实体事件)
/eventsSSE 流
/rpcJSON-RPC 2.0
/mcpModel Context Protocol(Claude/Smithery 等)
/trpc/{Entity}.{op}tRPC 过程
/odata/{Collection} · /odata/$metadataOData v4
多项目管理
端点方法描述
/api/projectsGET列出项目
/api/projectsPOST添加项目
/api/projects/:namePUT / DELETE编辑 / 移除
可观测性
端点描述
/api/performance实时指标(req/s、p50、p99)
/api/config-tree配置树(交互式)
/api/live-log流式日志馈送

架构

                                 ┌──────────────────────────────────┐
                                 │       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)              │
                                        └────────────────────────┘
使用的生态系统模块
模块在 Octonet 中的作用
@mostajs/orm持久化(13 种方言)
@mostajs/mproject多项目管理(default + sandbox + 订阅者)
@mostajs/rbac身份管理(User、Role、Permission、Account)+ AccountSchema + OCTONET_RBAC_SEED
@mostajs/auth与框架无关的 checkRequest 编排器、hashPassword
@mostajs/api-keysAPI 密钥 CRUD + 作用域(Scope/ScopeValue schemas)+ checkApiKey + ApiKeyScopeMatrix 管理员 UI
@mostajs/config带有 MOSTA_ENV 级联的环境变量辅助工具
@mostajs/cloud-middleware配额 / 订阅(可选——连接 Octocloud 时启用)
@mostajs/replicatorCQRS 多副本(可选)
@mostajs/project-lifeProject 持久化 schemas(可选——用于采用 SGBD 而非 JSON 存储的情况)

系统方言(与业务单例分离)

自 v2.7.5 起提供——解决了生产环境中观察到的 “/api/change-dialect 后找不到 API 密钥” 问题。

为什么要使用两种不同的方言?

Octonet 提供了一些管理路由,可在运行时修改数据库连接 (/api/change-dialect、/api/reload-config、/api/reconnect)——这对业务侧来说是合理的 (当前项目的 userland 实体可以根据管理员需求,从 postgres 迁移至 sqlite,再迁移至 mongodb)。

但系统模块 (API 密钥、RBAC users、审计、订阅计划、payments、project-life 元数据) 必须存放在一个稳定的数据库中,不受这些变更影响。否则:业务方言变更会导致找不到 API 密钥,管理员也会被锁在管理界面之外。

角色环境变量可在运行时修改?读取方
业务 (userland 实体)DB_DIALECT + SGBD_URI是 (管理员 UI)EntityService、传输方式、数据路由
系统 (Octonet 基础设施)MOSTA_SYSTEM_DIALECT + MOSTA_SYSTEM_URI否 (稳定)RBAC、apikey-middleware、account-scope、auth guards、sandbox /try
推荐配置 (生产环境多数据库)
# 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_system
单数据库配置 (开发 / 简单部署)

将 MOSTA_SYSTEM_* 留空 → 自动别名至业务单例 (100% 向后兼容,行为与 v2.7.5 之前相同)。

操作指南
1. 将现有部署迁移至多数据库模式
# 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. 验证系统与业务已正确隔离
# 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)

在 v2.7.5 之前,第二条 curl 会返回 503 metadata DB unavailable 或 401 PostgreSQL not connected. Call connect() first.

3. 在应用代码中读取系统方言
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. 检查启动引导

octonet-mcp 启动时,会显示两条日志:

✓ 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ème
src/server.ts 中的系统位置 (供参考)

现在有 18 个调用方通过 getSystemDialect() 获取方言,而非使用业务单例:

模块位置调用方
RBAC 引导1bootstrapRbac(systemDialect, …)
Scope 注册4registerScope(systemDialect, …) × 3 + systemDialect.initSchema(scopeTables)
全局中间件2createApiKeyMiddleware(() => systemDialect, …) + createAccountScopeMiddleware(() => systemDialect)
按传输方式应用的中间件2在每个 transport.use(…) 上应用同样的中间件
传输方式的身份验证守卫6authGuard(systemDialect, …) × 6 (SSE、GraphQL、JSON-RPC、gRPC、tRPC、OData)
自定义 /api/auth/verify2checkApiKey(systemDialect, …) + new UserRepository(systemDialect)
Sandbox /try2registerTryRoutes({ dialect: systemDialect, … }) + startTrialCleanupJob({ dialect: systemDialect, … })

业务方言 (dialect) 仍在以下场景中合理使用:

  • 业务单例的初始引导 (L98) + pm.setDefault('default', dialect, …) (L126、L240)
  • 管理路由 /api/reconnect、/api/change-dialect、/api/reload-config、/api/test-connection、/api/truncate-tables、/api/drop-tables——这些操作都明确属于业务范畴
  • 为 userland 实体提供服务的 EntityService (通过受保护的传输方式执行 CRUD 操作)
项目阶段 (历史记录)
阶段仓库交付内容
1@mostajs/data-plug v1.2.2-1.2.4 (API getSystemDialect + ORM 门面)npm
2@mostajs/net v2.7.5 (启动时执行 bootstrapSystemDialect)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 仓库 + 门面)npm
4@mostajs/net v2.7.5 (消费者切换为使用 getSystemDialect()——18 个位置)git
5/api/change-dialect 场景的集成测试:postgres → sqlite⏳
6部署到 amia + MOSTA_SYSTEM_URI 冒烟测试⏳

启动序列

  1. 通过 @mostajs/config 加载 .env(配置文件级联 MOSTA_ENV)
  2. 连接主方言(SGBD_URI)
  3. 加载架构(优先级:getAllSchemas() 注册表 → schemas.json → 扫描 SCHEMAS_PATH 目录)
  4. 使用策略 update/create 执行 dialect.initSchema(schemas)
  5. 引导 RBAC(octonet-rbac-bootstrap.ts):
    • 注册 UserSchema/RoleSchema/PermissionSchema/PermissionCategorySchema/AccountSchema/ApiKeySchema
    • seedRBAC(OCTONET_RBAC_SEED) — 6 个类别、25 项权限、4 个角色(admin/subscriber/trial/public)
    • 根据 OCTONET_ADMIN_EMAIL/PASSWORD 执行 createAdmin()
    • 创建 Account trial-playground(type='trial')
    • 创建 User public-demo(role=public)
    • 创建 Account public-system(type='system')
    • 生成作用域限定为 default 项目的 ApiKey public-default(只读,REST + MCP)——仅以明文输出一次
  6. 注册规范作用域:projects(动态,Project.slug)、operations(静态:read/write/admin)、transports(静态:11 个值)
  7. 将默认项目推送到 projects-tree.json(ownerId=admin,visibility=public)
  8. 从 projects-tree.json 加载其他项目
  9. 使用 composeMiddleware([sanitizer, apikey], ormHandler) 包装 ormHandler → protectedOrmHandler
  10. 启动每个已启用的传输方式:
    • transport.use(loggingMiddleware)
    • transport.use(sanitizerMiddleware)
    • transport.use(apiKeyMiddleware)
    • transport.setHandler(ormHandler)
    • transport.start(config)
  11. 注册 Fastify 路由:
    • registerDynamicRestRoutes(app, protectedOrmHandler, pm) — /api/v1/...
    • registerProjectRoutes(app, pm, protectedOrmHandler) — /:project/*
    • registerTryRoutes(app, {dialect, pm}) — /try POST
    • registerTryPage(app) — /try GET(HTML)
    • startTrialCleanupJob({dialect, pm}) — 每小时运行的 cron 任务,TTL 为 7 天
  12. 监听端口(MOSTA_NET_PORT)

14 种多语言 NetClient

Octonet 可供 14 种原生运行时使用,使用相同的 apikey 和 URL:

运行时软件包注册表
Node/TS@mostajs/net/client(内置)npm
Javacom.mostajs:mostajs-net-clientMaven Central
Java + Spring Bootcom.mostajs:mostajs-net-client-spring-boot-starterMaven Central
.NETMostaJs.Net.ClientNuGet
Pythonmostajs-net-clientPyPI
Gogithub.com/apolocine/mosta-net-client-gopkg.go.dev
Swiftmosta-net-client-swiftSwift Package Index
Kotlinio.github.apolocine:mostajs-net-client-ktMaven Central
Dart / Fluttermostajs_net_clientpub.dev
Rustmostajs-net-clientcrates.io
PHPmostajs/net-clientPackagist
Rubymostajs-net-clientRubyGems
Elixirmostajs_net_clientHex.pm
Luamostajs-net-clientLuaRocks
DelphiMostaJsNetClientGetIt
Unity (C#)com.mostajs.net-clientOpenUPM

Monorepo:github.com/apolocine/mosta-net-clients

每个 NetClient 都遵循相同的 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()

生产环境部署(amia.fr)

参考部署使用 PostgreSQL 后端,运行于 octonet.amia.fr + mcp.amia.fr(兼容别名):

URL作用
https://octonet.amia.frOctonet 服务(REST、MCP、GraphQL、WS、SSE、tRPC、OData、JSON-RPC)
https://mcp.amia.fr兼容性 DNS 别名 — 历史域名 mcp.so
https://octocloud.amia.frOctocloud — SaaS Next.js 门户(订阅、管理 UI)

完整的部署套件位于 Entreprise/octonet-mcp/:

  • apache/mcp.amia.fr.conf — Apache2 虚拟主机(SSE 代理、WS 升级、Let's Encrypt SAN 证书)
  • ecosystem.config.cjs — PM2 配置
  • deploy.sh / install.sh / update.sh — 编排脚本
  • tests/smoke-all.sh — 冒烟测试套件(DNS、TLS、/health、SSE MCP、REST、/try、Java NetClient)

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é)

许可证

AGPL-3.0-or-later — 可自由使用,前提是衍生代码保持开源。 可购买商业许可证:[email protected]。按项目定价,不按席位定价。

— (c) 2026 Dr Hamid MADANI <[email protected]>

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。