Skip to content

Latest commit

 

History

History
447 lines (315 loc) · 11.9 KB

File metadata and controls

447 lines (315 loc) · 11.9 KB

Owl Dictionary(中文说明)

English

Owl 是一个自托管的 MDX / MDD Web 词典。它面向个人查词、公开词典共享、用户私有词典管理,以及 AI 客户端通过 MCP 查询词典的场景。


用户可以做什么

查词与阅读

  • 在浏览器中直接查询 MDX 词典。
  • 未登录用户可以查询已启用的公开词典
  • 登录用户可以查询公开词典,以及自己上传的私有词典。
  • 支持查询全部可用词典,也可以筛选到某一本词典。
  • 支持搜索建议和键盘导航。
  • 支持点击词条内部链接,继续跳转查询相关词。
  • 支持渲染 MDX 返回的 HTML 内容。
  • 支持通过后端读取配套 MDD 中的图片、音频、CSS、字体和其他媒体资源。
  • 词条中有音频资源时可以直接播放。
  • 支持复制纯文本释义,方便粘贴到笔记或其他工具中。
  • 支持最近搜索,保留数量可以在管理界面配置。

更舒服的输出体验

  • 查询页面同时适配桌面端和移动端。
  • 移动端提供更紧凑的词典筛选控件。
  • 移动端搜索后会直接定位到结果区域,避免最近搜索挡住结果。
  • 最佳匹配结果会被突出显示,其他匹配结果在下方继续展示。
  • 查询结果会显示公开 / 私有来源标识。
  • 支持多种主题,包括复古风格、深色主题、黑白主题等。
  • 阅读字体可以切换为 sans / serif / mono / 自定义字体。

个人偏好

  • 切换界面语言:简体中文 / English。
  • 切换视觉主题。
  • 设置阅读字体模式。
  • 上传并使用共享自定义字体。
  • 设置显示名称和头像。
  • 设置最近搜索保留数量。

词典管理功能

词典维护

  • 在网页中上传 .mdx 文件和可选的 .mdd 文件。
  • 刷新单本词典,用于重新加载或补齐资源。
  • 刷新整个词典库,用于重新扫描挂载目录。
  • 启用 / 停用词典。
  • 设置词典为公开 / 私有。
  • 删除词典。
  • 在界面中查看词典文件状态:
    • ok
    • missing_mdx
    • missing_mdd
    • missing_all
  • 查看结构化刷新报告:
    • discovered
    • updated
    • skipped
    • failed

词典文件识别规则

  • 同 basename 的 .mdx + .mdd 会被视为同一套词典。
  • 如果先上传 MDX,之后再补充同名 MDD,可以通过刷新重新发现资源。
  • 挂载的词典目录会被递归扫描。
  • 如果不挂载外部目录,也可以只使用网页上传模式。

站点级管理

管理员可以设置:

  • 是否开放新用户注册。
  • 网站 footer 额外信息。
  • 版权信息。

默认情况下,footer 信息为空时不会显示。


MCP 支持

Owl 内置基于 SSE 的 MCP 服务,方便 AI 客户端调用词典。

Endpoint

/api/mcp/sse

认证方式是每个用户自己的 MCP Token:

Authorization: Bearer <MCP_TOKEN>

临时测试也可以使用 URL 参数:

/api/mcp/sse?token=<MCP_TOKEN>

初次 SSE 连接必须携带 Token;连接建立后,SDK 后续 POST 请求会通过 MCP session 继续通信。

MCP 工具

  • list_dictionaries

    • 列出当前 token 用户可访问的词典。
    • 范围:已启用的公开词典 + 当前用户自己的私有词典。
  • search_dictionary

    • 查询当前 token 用户可访问的词典。
    • 必填:query
    • 可选:dictionary_iddictionary_name
    • 可选:format=markdown 会让 MCP 响应的文本内容以 Markdown 输出;不传 format 时保持默认 JSON 文本输出。
    • 如果不指定词典,则按 Web 查询相同范围搜索全部可访问词典。

Token 管理

每个用户都可以在管理界面维护自己的 MCP Token:

  • 保存自定义 Token
  • 生成随机 Token
  • 删除 / 撤销 Token
  • 打开使用说明弹窗查看接入方式

Token 只会以 hash 形式存储。生成后请立即复制,之后界面只显示首尾提示。


技术概览

技术栈

  • 后端:Go + Echo v5 + ent
  • 数据库:默认 SQLite,也支持通过 driver/DSN 配置 PostgreSQL、MySQL
  • 词典引擎:github.com/lib-x/mdx
  • MCP 服务:github.com/modelcontextprotocol/go-sdk
  • 前端:React + Vite + TypeScript
  • 搜索索引:默认使用数据库持久索引;可选 Redis + RediSearch
  • 部署方式:单 Go 服务 / 单 Docker 镜像
  • 前端生产资源:通过 go:embed 嵌入 Go 服务
  • 自动化:GitHub Actions 构建 CI、发布二进制和 Docker 镜像

搜索后端行为

Owl 可以不依赖 Redis 运行,此时会把导出的 MDX 搜索索引写入已配置数据库,只在需要渲染命中释义时才加载完整词典对象。

配置 Redis 后:

  • exact / prefix 索引可以写入 Redis
  • fuzzy 查询可以使用 RediSearch
  • 自动补全结果由后端聚合
  • 如果 RediSearch 不可用,会自动回退到前缀索引搜索

Docker 部署

仓库提供四个 Docker Compose 文件:

  • docker-compose.yml:最简单部署,SQLite,不启用 Redis
  • docker-compose.redis.yml:SQLite + Redis + RediSearch
  • docker-compose.postgres.yml:PostgreSQL,不启用 Redis
  • docker-compose.mysql.yml:MySQL,不启用 Redis

方案一:不启用 Redis

cp .env.example .env
# 先修改 OWL_JWT_SECRET 和管理员账号密码
docker compose -f docker-compose.yml pull
docker compose -f docker-compose.yml up -d

默认地址:

http://localhost:8080

该模式会启动:

  • Owl:http://localhost:8080
  • SQLite:保存在持久化 volume owl_data
  • 上传词典:保存在 /app/data/uploads
  • 不依赖 Redis

方案二:启用 Redis + RediSearch

如果你希望启用 Redis 前缀 / 精确索引和 RediSearch 模糊查询,可以使用:

cp .env.example .env
# 先修改 OWL_JWT_SECRET 和管理员账号密码
docker compose -f docker-compose.redis.yml pull
docker compose -f docker-compose.redis.yml up -d

该模式会启动:

  • Owl:http://localhost:8080
  • Redis Stack Server,用于 Redis + RediSearch
  • SQLite 数据库和上传文件保存在 owl_data
  • Redis 数据保存在 owl_redis

方案三:PostgreSQL

如果你希望 Owl 的元数据使用 PostgreSQL 而不是 SQLite,可以使用这个方案。上传的词典文件仍然保存在 owl_data;变化的是关系数据库。

cp .env.example .env
# 修改 OWL_JWT_SECRET 和管理员账号密码
docker compose -f docker-compose.postgres.yml pull
docker compose -f docker-compose.postgres.yml up -d

该 compose 会启动内置 owl 数据库 / 用户的 PostgreSQL,并设置:

OWL_DB_TYPE=postgres
OWL_DB_DSN=postgres://...

方案四:MySQL

如果你希望 Owl 的元数据使用 MySQL 而不是 SQLite,可以使用这个方案。上传的词典文件仍然保存在 owl_data;变化的是关系数据库。

cp .env.example .env
# 修改 OWL_JWT_SECRET 和管理员账号密码
docker compose -f docker-compose.mysql.yml pull
docker compose -f docker-compose.mysql.yml up -d

该 compose 会启动内置 owl 数据库 / 用户的 MySQL,并设置:

OWL_DB_TYPE=mysql
OWL_DB_DSN=owl:...@tcp(mysql:3306)/owl?parseTime=true&charset=utf8mb4&loc=Local

Compose 文件默认使用发布镜像:czyt/owl:latest


部署说明

挂载已有词典目录

如果你本机已经有很多 .mdx / .mdd 文件,可以把宿主机目录挂载到 OWL_LIBRARY_DIR

示例覆盖:

services:
  owl:
    environment:
      OWL_LIBRARY_DIR: /app/library
    volumes:
      - owl_data:/app/data
      - ./dicts:/app/library

启动后:

  1. 登录
  2. 打开 管理
  3. 点击 刷新词典库

Owl 会递归扫描目录,并自动把 name.mdxname.mdd 识别为同一套词典。

纯网页上传模式

如果你不想挂载外部词典目录,可以保持:

OWL_LIBRARY_DIR=/app/data/uploads

这样词典就可以完全通过网页上传和管理。

首次启动检查清单

  1. 打开 http://localhost:8080
  2. 使用初始化管理员账号登录。
  3. 上传一本测试词典,或挂载词典目录后刷新词典库。
  4. 根据需要设置词典公开 / 私有。
  5. 回到首页确认可以正常查词。
  6. 可选:配置注册开关、footer、字体和 MCP Token。

升级说明

升级 Owl 时,请使用与你启动时相同的 compose 文件。

不启用 Redis:

git pull
docker compose -f docker-compose.yml down
docker compose -f docker-compose.yml pull
docker compose -f docker-compose.yml up -d

启用 Redis:

git pull
docker compose -f docker-compose.redis.yml down
docker compose -f docker-compose.redis.yml pull
docker compose -f docker-compose.redis.yml up -d

SQLite / PostgreSQL / MySQL 数据、上传词典和 Redis 数据都会保留在 Docker volume 中,除非你手动删除 volume。


本地开发

后端

cd backend
GOPROXY=https://goproxy.cn,direct GOSUMDB=off go test ./...
GOPROXY=https://goproxy.cn,direct GOSUMDB=off go vet ./...
GOPROXY=https://goproxy.cn,direct GOSUMDB=off go run ./cmd/server

后端默认地址:

http://localhost:8080

前端

cd frontend
pnpm install
pnpm lint
pnpm build
pnpm dev

前端开发地址:

http://localhost:3000

生产风格本地运行时,pnpm build 会把前端构建产物写入 backend/web/dist,Go 服务通过嵌入资源提供页面。Vite 开发服务会把 /api 代理到后端。


环境变量

完整列表见 .env.example

核心服务

  • OWL_PORT
  • OWL_FRONTEND_ORIGIN
  • OWL_JWT_SECRET
  • OWL_DATA_DIR
  • OWL_UPLOADS_DIR
  • OWL_LIBRARY_DIR
  • OWL_WARM_DICTIONARIES:默认 false。设为 true 会在启动时预加载所有已启用词典;大词典库建议保持关闭,避免重启慢和基础内存占用过高。
  • OWL_MAX_LOADED_DICTIONARIES:进程内最多保留的完整已加载词典数量。默认 0(不限制),避免全局搜索反复冷加载;内存受限的部署可设为正整数。

数据库

  • OWL_DB_TYPE:默认 sqlite;也支持 postgres / postgresqlmysql / mariadb
  • OWL_DB_DSN:数据库连接字符串;SQLite 默认可留空,由 OWL_DB_PATH 自动生成
  • OWL_DB_PATH:SQLite 数据库路径

使用 SQLite 且 OWL_DB_DSN 为空时,Owl 会自动生成包含 shared cache、外键、WAL 日志模式、NORMAL 同步模式和 10 秒 busy timeout 的 DSN,用于改善 SQLite 下的并发读写体验,同时保留简单部署方式。

示例:

# SQLite 默认:DSN 留空,由 OWL_DB_PATH 自动生成。
OWL_DB_TYPE=sqlite
OWL_DB_DSN=

# SQLite 显式 DSN,等价于默认生成格式。
OWL_DB_TYPE=sqlite
OWL_DB_DSN=file:/app/data/data.db?cache=shared&_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)&_pragma=synchronous(NORMAL)&_pragma=busy_timeout(10000)

OWL_DB_TYPE=postgres
OWL_DB_DSN=postgres://owl:secret@postgres:5432/owl?sslmode=disable

OWL_DB_TYPE=mysql
OWL_DB_DSN=owl:secret@tcp(mysql:3306)/owl?parseTime=true&charset=utf8mb4&loc=Local

初始化管理员与注册

  • OWL_BOOTSTRAP_ADMIN
  • OWL_ADMIN_USERNAME
  • OWL_ADMIN_PASSWORD
  • OWL_ALLOW_REGISTER

Redis / RediSearch

  • OWL_REDIS_ADDR
  • OWL_REDIS_PASSWORD
  • OWL_REDIS_DB
  • OWL_REDIS_KEY_PREFIX
  • OWL_REDIS_PREFIX_MAX_LEN
  • OWL_REDIS_SEARCH_ENABLED
  • OWL_REDIS_SEARCH_KEY_PREFIX

音频资源

  • OWL_AUDIO_CACHE_DIR
  • FFMPEG_BIN

调试接口

查看搜索后端状态

游客范围:

curl http://localhost:8080/api/public/search-backends

登录范围:

curl -H 'Authorization: Bearer <token>' http://localhost:8080/api/debug/search-backends

重点字段含义:

  • fuzzy_backend: redisearch:正在使用 RediSearch
  • fuzzy_backend: sql-index:正在使用本地数据库索引
  • fuzzy_backend: memory-fuzzy:处于回退模式
  • prefix_backend: redis-prefix:Redis 前缀索引已生效
  • prefix_backend: sql-prefix:本地数据库前缀索引已生效