At a glance
What it does
Build a Mobius AI extension with its required backend handler, frontend SDK integration, and manifest conventions.
Before you choose it
Use this skill when a requested feature should live as a Mobius extension instead of a separate project. It defines the extension directory layout, the stateless CommonJS backend handler contract, the frontend extCall SDK, zero-build or Vite/Webpack build options, naming rules, visibility behavior, reload steps, and debugging endpoints.
Best for
Developers extending a Mobius AI deployment.
Common tasks
- Create a new extension with extension.json, a backend handler, and a frontend entry page.
- Call an extension backend through the provided extCall SDK instead of constructing API requests directly.
- Choose a no-build frontend or a Vite/Webpack build and diagnose rebuild or handler logs.
Permissions and data
The documented extension runtime handles user identity and extension requests.
Permissions- Backend handlers receive username and display name supplied through JWT injection.
- Handlers may write only within ext_data_dir.
- The frontend SDK reads the local cc-token JWT to make extension calls.
- Extension data is stored under the extension-specific protected_data directory.
- Input payloads must be validated for type and bounds.
- Testing the documented endpoints requires a JWT signed with the Mobius JWT secret.
Limitations
- Designed specifically for Mobius extensions, not standalone applications.
- Backend handlers must remain stateless and meet documented time, payload, rate, and memory limits.
- Commercial use requires a separate commercial license.
What DSHub checked
- A complete pinned skill document was captured.
- The source commit is pinned.
What DSHub did not check
- The skill was not installed or executed by DSHub.
- No Mobius harness version range is declared in the supplied evidence.
Pinned install
Primary action
This standalone skill does not have a DSH Plugin install action. Use its source documentation for the delivery method.
Maintainer source
Skill instructions
name: mobius-extension description: 在莫比乌斯 AI 中开发一个新拓展插件 (特殊应用). 含后端 handler 协议、前端 SDK / 编译策略、目录与命名规范。一旦用户选择了这个SKILL(当然,也不排除选错的可能性),你需要认真考虑如何把用户的需求做成 Mobius 拓展,而不是一个完全独立的项目。
开发 mobius 拓展
拓展 = mobius/extension/<name>/ 一个目录. 新 tab 打开 /extension/<name>/ 运行, 后端走 /api/ext 转发, 数据落到 APP_DIR/protected_data/extension/<name>/. 样例: mobius/extension/pacman/.
mobius/extension/<name>/
├── extension.json
├── backend/extension_backend_handler.js
├── backend/...others...
└── frontend/index.html
└── frontend/...others(main.js / package.json / ...)...
1. 后端
文件固定 backend/extension_backend_handler.js, CommonJS, 导出 async 函数:
module.exports = async function ({
username, // string, JWT 注入, 可信
display_name,
ext_main_payload, // any JSON, 前端传的 payload
ext_data_dir, // 绝对路径, 你唯一可写区
extension_name,
logger, // info/warn/error → ext_data_dir/_handler.log
}) {
// 推荐按 ext_main_payload.action 分发
return { ok: true, /* ... */ }; // 或 { ok: false, error: '...' }
};
硬约束 (违反 → 504/502/500/429):
| 项 | 上限 |
|---|---|
| 单次时长 | 30 s |
| 返回 JSON | 5 MB |
| 入参 payload | 1 MB |
| 速率 | 5 rps / 用户 |
| 内存 | 256 MB |
| 状态 | stateless -- 模块顶层不能有连接/定时器/cache, 每次新 worker_thread |
| 文件 IO | 只能 path.join(ext_data_dir, ...), 不能 process.chdir() (worker_thread 禁用) |
| stdout | 不回流, 用 logger.* |
样例 (吃豆人排行榜):
const path = require('path'), fs = require('fs/promises');
module.exports = async function ({ username, ext_main_payload, ext_data_dir }) {
const lb = path.join(ext_data_dir, 'leaderboard.json');
if (ext_main_payload.action === 'submit_score') {
const score = Number(ext_main_payload.score) | 0;
if (score < 0 || score > 1e7) return { ok: false, error: 'invalid score' };
let list = []; try { list = JSON.parse(await fs.readFile(lb, 'utf8')); } catch {}
list.push({ username, score, ts: Date.now() });
list.sort((a, b) => b.score - a.score);
await fs.writeFile(lb, JSON.stringify(list.slice(0, 100)));
return { ok: true };
}
};
handler 改动按 mtime 自动失效 require 缓存, 不用重启.
2. 前端
frontend/index.html 是入口. 后端自动注入 <script>window.__EXT_NAME__="<name>";</script> 到 <head>.
调用后端只用 SDK, 别自己拼 fetch('/api/ext'):
import { extCall } from '/extension/_sdk/ext.js';
const r = await extCall({ action: 'submit_score', score: 1234 });
// SDK 自动: 从 localStorage['cc-token'] 取 JWT + 填 extension_name + 包 ext_main_payload
编译策略二选一:
- 零编译: 不写
package.json. 首访时后端把frontend/*拷到dist/. 用浏览器原生 ESM. 改完调POST /api/admin/extensions/<name>/rebuild. - vite/webpack:
frontend/package.json含"build": "vite build", 产物必须在frontend/dist/index.html. 首访自动npm install+npm run build, 用户看 loading 页轮询. 日志:protected_data/extension/<name>/_build.log, 或GET /api/extensions/<name>/build-status.
隔离: 新 tab = 独立 JS 引擎. 不要 import 主前端代码, 不要覆盖 localStorage['cc-token'].
3. 规范
命名: <name> 必须 ^[a-z][a-z0-9-]{0,31}$, 且 extension.json:name = 目录名.
manifest (extension.json):
{ "name": "<name>", "display_name": "中文名", "description": "...", "version": "0.1.0", "icon": "favicon.svg", "project": { "sync": true } }
不要写 entry / handler 路径, 是约定固定的. project 可选, 只有一个字段:
project.sync(默认true):false时该拓展不进 DB, 完全不出现在任何项目列表里 (等同于"不启用"). 其它情况都会作为一个 kind=extension的项目入库.: 已移除. 拓展一律默认可见, 不再支持"默认隐藏"; 想让某拓展不出现, 用project.default_hiddensync: false或直接不放进mobius/extension/.
可见性规则 (简单版): 每个拓展默认对所有人可见. 用户可在项目页隐藏任意拓展, 也可在「已屏蔽项目」里随时恢复显示——只对自己生效, 不影响别人, 不删数据. 后端只有一个可见性来源 (用户屏蔽 = user_muted_projects); 拓展卡片只提供"隐藏"一个动作. 彻底删除某用户在该拓展的数据是管理员专属操作 (管理中心 → 拓展 → 已隐藏的拓展 → 彻底删除), 普通用户没有这个能力.
特殊拓展项目 (kind=extension 的 project) 由 registry 自动 upsert, 锁死: bind_path=APP_DIR, worktree=false, research=false, created_by=system (但每个用户的项目页都能看到). 不能从 UI 删, 不能改 name/desc/path/repos/worktree/research, 可改 forgotten_flag.* 与星标.
生命周期: 新增 → POST /api/admin/extensions/reload (或 python3 start.py 重启). 删除 → 删目录 + reload, DB 行保留 (标 disabled), 用户在该项目下的 issue/session 不丢; 目录补回 → reload → 自动恢复.
调试套路:
# JWT
TOKEN=$(node -e "console.log(require('jsonwebtoken').sign({id:'<uid>'},'<JWT_SECRET>',{expiresIn:'1h'}))")
# 列表 / 调 handler / 重 reload / 重新 build
# find $MOBIUS_PORT in `env var` or `.env` or `.env.default`, default 33314
curl -H "Authorization: Bearer $TOKEN" http://localhost:$MOBIUS_PORT/api/extensions
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"extension_name":"<name>","ext_main_payload":{"action":"..."}}' \
http://localhost:$MOBIUS_PORT/api/ext
curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:$MOBIUS_PORT/api/admin/extensions/reload
curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:$MOBIUS_PORT/api/admin/extensions/<name>/rebuild
tail -f APP_DIR/protected_data/extension/<name>/_handler.log
tmux attach -t mobius-system # 看后端实时日志
禁忌:
- handler 顶层持有状态 / 用
process.chdir/ 写ext_data_dir之外的路径 - 直接
fetch('/api/...')调 mobius 其他接口 (走 extCall 之外的 API 没有授权也没必要) - 把
node_modules//dist/提交进仓库 - 信任
ext_main_payload: 一律校验类型 + 边界 - 回显 stack trace, 只返回
{ ok:false, error:'简短' }
4. 主项目联合修改
有时候只修改extension无法优雅地解决问题,需要主项目配合修改。这是允许的,但修改需要足够的通用性,不能只为一个特定的extension服务。
Operate deliberately
Install and manage
Prerequisites and target Profile
Target: Developer Profile
Delivery: Skill Files — https://raw.githubusercontent.com/nutshellai-tech/mobius/1eb8750d2d9012e1f50a18f7c60c2ad040c04889/skills/mobius-extension/SKILL.md。
Compatibility and access
For developing extensions for Mobius AI: Not declared in supplied evidence。
Review compatibility evidence ↗
Risk facts
Source-available license permits non-commercial use; commercial use requires a separate license.
Evidence ↗Extension handlers receive trusted user identity fields and may write only inside their assigned extension data directory.
Evidence ↗Evidence and editorial reviewManifest, Bundle patch, distribution and freshness
Immutable evidence
Review status and source activity
Approved for publication after reviewing the source-linked content and immutable release record. AI assisted with the draft; the publication decision was human.
Human reviewed Sep 4, 2026, 11:38 AM UTC。GitHub facts last checked Sep 3, 2026, 3:47 PM UTC。
No material source change has been recorded since this evidence baseline.