Doramagic 项目包 · 项目说明书
oto-cli 项目
面向业务自动化的命令行工具,支持 Google Workspace、浏览器数据抓取、企业数据、AI 及 CRM,适配人类和 AI 智能体使用。
oto-cli 概述:AI 代理的 CLI 工具包
oto 是一个面向 LLM / AI 代理的统一命令行工具包,目标是为那些"没有官方 CLI"的 SaaS 产品提供一等公民的脚本化入口。官方表述为:「Your LLM uses gh for GitHub, aws for AWS. oto covers the long tail — the SaaS products that don't have a CLI.」 资...
Google Workspace、LinkedIn、Notion、Pennylane、Serper、SIRENE、Crunchbase、Pappers、Indeed、G2、Folk CRM、WhatsApp、Kaspr、Hunter 等。 资料来源:[README.md:5-15]()
v0.3.0 起加入 Mistral AI 客户端模块,Gemini 客户端支持 imagesize 与 referenceimages(用于 editimage),所有工具假设由 LLM 解析 JSON / 文本输出。 资料来源:[README.md:15-30]()
v0.2.0 起在 import 时通过 GitHub Releases API 进行非阻塞版本检查,可通过 OTOMATANOUPDATECHECK=1 关闭;版本号通过 pyproject.toml 中的 hatchling 从 init.py 动态读取。 资料来源:[pyproject.toml:1-20]()
oto 是一个面向 LLM / AI 代理的统一命令行工具包,目标是为那些"没有官方 CLI"的 SaaS 产品提供一等公民的脚本化入口。官方表述为:「Your LLM uses gh for GitHub, aws for AWS. oto covers the long tail — the SaaS products that don't have a CLI.」 资料来源:README.md:1-15
项目定位与设计哲学
oto-cli 的核心理念是:让 AI 代理通过 shell 调用即可驱动 30+ 个外部 SaaS,避免每个工具单独维护一套胶水代码。仓库首次公开发布于 v1.0.0,强调「CLI toolkit for AI agents」,并在 v0.4.0 之后扩展为 Gmail 多账户 OAuth、附件与草稿等深度集成场景。 资料来源:README.md:1-30
- 覆盖长尾 SaaS:Google Workspace、LinkedIn、Notion、Pennylane、Serper、SIRENE、Crunchbase、Pappers、Indeed、G2、Folk CRM、WhatsApp、Kaspr、Hunter 等。 资料来源:README.md:5-15
- AI 优先:v0.3.0 起加入 Mistral AI 客户端模块,Gemini 客户端支持
image_size与reference_images(用于edit_image),所有工具假设由 LLM 解析 JSON / 文本输出。 资料来源:README.md:15-30 - 零阻塞更新提示:v0.2.0 起在 import 时通过 GitHub Releases API 进行非阻塞版本检查,可通过
OTOMATA_NO_UPDATE_CHECK=1关闭;版本号通过pyproject.toml中的 hatchling 从__init__.py动态读取。 资料来源:pyproject.toml:1-20
命令发现与运行时架构
CLI 入口由 oto/cli.py 承担,命令加载采用「包内 glob」机制:_commands_dir.glob("*.py") 会枚举 oto/commands/*.py 下所有模块并动态注册。 资料来源:oto/cli.py:1-40
这种设计的优势是无需在 pyproject.toml 中显式枚举子命令,新增 commands/foo.py 即可生效;缺点是无法加载包外插件——这也是社区 issue #9 的核心动因:建议通过 entry-points(如 oto.commands)暴露给第三方 / 客户端专用连接器。 资料来源:oto/cli.py:20-50
┌────────────────────────────────────────────────────────┐
│ 用户调用: oto <subcommand> [args] │
└──────────────────────┬─────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ oto/cli.py 解析参数 → _commands_dir.glob("*.py") │
└──────────────────────┬─────────────────────────────────┘
│
┌──────────────┼──────────────┬────────────────┐
▼ ▼ ▼ ▼
commands/gmail commands/linkedin commands/google ... (其余 commands/*.py)
│ │ │
▼ ▼ ▼
oto/tools/<saas> client 实现(OAuth / Playwright / REST)
连接器与浏览器客户端生态
连接器按职责分两类:API 客户端(封装 REST / GraphQL)与浏览器客户端(封装 Playwright 自动化)。浏览器客户端集中在 oto/tools/browser/,每个客户端是「unitary」的——不内置「stop on seen」状态,仅暴露原子动作,由上层脚本组合;这一约定源自 issue #1 的设计讨论。 资料来源:oto/tools/browser/:1-30
| 类别 | 代表连接器 | 使用形态 |
|---|---|---|
| 通用 SaaS | LinkedIn、Notion、Pennylane、Crunchbase、Pappers | REST / Playwright |
| 通讯 | Gmail、WhatsApp、Kaspr、Hunter | Gmail 多账户 OAuth(otomata google auth <name>) |
| 数据 / 招聘 | SIRENE、Indeed、G2、Folk CRM | API + 浏览器 |
| AI 模型 | Mistral、Gemini | client.generate() / edit_image() |
资料来源:README.md:5-30
插件机制、密钥管理与可扩展性
oto-cli 通过 Python extras 暴露可选依赖,避免重型 SaaS 客户端拖累基础安装。例如 v1.5.0 提供 oto browser vivatech(VivaTech 参展商目录),来自独立插件 o-browser-vivatech,通过 entry-point o_browser.sites 注册,安装方式为 pip install oto-cli[vivatech]。 资料来源:pyproject.toml:30-60
密钥(secrets)管理是当前的演进重点:oto config provider secrets <file|scaleway> 已支持两种 provider 并 fallback 到环境变量;社区 issue #3 计划引入 keychain 与 SOPS 作为一等公民 provider,并提供「scoped lookup」,以便在多租户 / 多客户端场景下隔离凭据。 资料来源:oto/config.py:1-40
| Provider | 现状 | 路线图(issue #3) |
|---|---|---|
file | ✅ 已支持 | — |
scaleway | ✅ 已支持 | — |
keychain | ❌ | 计划 |
sops | ❌ | 计划(基于 otomata-tech/secrets) |
| 环境变量 | ✅ fallback | 保留 |
资料来源:pyproject.toml:1-60、oto/config.py:1-40
小结
oto 的定位是「AI 代理的通用连接层」:把长尾 SaaS 收编到统一 CLI 之下,通过 glob 自动发现命令、extras 按需加载重型依赖、entry-points 隔离客户化连接器。对于希望让 LLM 直接操作浏览器或第三方 API 的团队,它是介于「手写脚本」与「重型 RPA」之间的轻量中间层。 资料来源:README.md:1-30、pyproject.toml:1-60、oto/cli.py:1-50
资料来源:README.md:5-30
系统架构与命令自动发现
oto-cli 是 Otomata 发布的"长尾 SaaS CLI"工具集,定位为 LLM 代理的"瑞士军刀"——为不提供官方 CLI 的 SaaS 产品(Google Workspace、LinkedIn、Notion、Pennylane、Pappers、Crunchbase 等)提供统一命令行入口。整体架构遵循"按子命令目录自动发现 + 可选插件 entry-point...
继续阅读本节完整说明和来源证据。
概述
oto-cli 是 Otomata 发布的"长尾 SaaS CLI"工具集,定位为 LLM 代理的"瑞士军刀"——为不提供官方 CLI 的 SaaS 产品(Google Workspace、LinkedIn、Notion、Pennylane、Pappers、Crunchbase 等)提供统一命令行入口。整体架构遵循"按子命令目录自动发现 + 可选插件 entry-point"两层模型:核心命令通过包内目录扫描装载,第三方扩展(如 o-browser-vivatech)通过 importlib.metadata 提供的 entry-point 机制注册。资料来源:docs/concepts.md:1-40
版本号动态从 oto/__init__.py 读取,并由 pyproject.toml 的 hatchling 后端在构建时注入;导入时还会通过 OTOMATA_NO_UPDATE_CHECK 环境变量控制是否对 GitHub Releases API 做非阻塞版本检查。资料来源:oto/__init__.py:1-30 资料来源:pyproject.toml:1-60
命令自动发现机制
oto/cli.py 是命令注册的核心入口。它通过 pathlib.Path 定位包内 _commands_dir = Path(__file__).parent / "commands",随后用 glob("*.py") 列出所有 Python 文件并动态 importlib.import_module 加载,最终把每个子模块中暴露的 app(Typer 实例)挂载到根 app 之下。资料来源:oto/cli.py:1-80
# oto/cli.py —— 命令发现循环(简化)
for module_file in _commands_dir.glob("*.py"):
if module_file.name == "__init__.py":
continue
module = importlib.import_module(f"oto.commands.{module_file.stem}")
if hasattr(module, "app"):
app.add_typer(module.app, name=module_file.stem)
这种"约定优于配置"的方式让新增命令只需在 oto/commands/ 下新增一个文件并导出一个 app 即可,无需改动 cli.py。资料来源:oto/commands/__init__.py:1-20
下表总结了内置子命令与对应职责:
| 子命令 | 主要模块 | 用途 |
|---|---|---|
config | commands/config.py | provider、密钥、profile 配置 |
google | commands/google.py | Gmail / Drive 多账户 OAuth |
linkedin | commands/linkedin.py | 登录、抓取、外联 |
notion | commands/notion.py | 页面/数据库读写 |
browser | tools/browser/ | 浏览器站点爬虫(插件式) |
资料来源:oto/commands/config.py:1-50
浏览器子命令的插件化扩展
browser 子命令是个例外:它不把每个站点硬编码进 oto/commands/,而是将目录扫描转向 oto/tools/browser/,并通过 importlib.metadata.entry_points(group="o_browser.sites") 把第三方包(如 o-browser-vivatech)在 pyproject.toml 中声明的 entry-point 合并进来。资料来源:oto/tools/browser/__init__.py:1-60
发布形式上,核心包只保留通用基础能力,垂直站点(如 VivaTech 展商目录)以独立包 oto-cli[vivatech] 提供,安装即出现 oto browser vivatech 子命令。资料来源:pyproject.toml:30-90
已知局限与演进方向
当前的 glob("*.py") 发现机制只在包内有效,导致社区 issue #9 提出的痛点:客户/内部专用的连接器无法在不修改 oto-cli 源码的前提下被分发。提议的方案是引入 oto.commands 组别的 entry-point,让任意第三方包能像 o_browser.sites 一样注册顶层子命令。资料来源:oto/cli.py:40-80
并行地,issue #3 推动 secrets 子系统的重构(keychain / SOPS 作为一等 provider + scoped lookup),这部分改造会复用 config 子命令的注册面,但服务端解析会在 commands/config.py 内部完成,不会暴露出新的可见命令。资料来源:oto/commands/config.py:30-100
对于想贡献新 SaaS 连接器的开发者,标准流程是:在 oto/commands/ 新建一个文件、定义 app = typer.Typer(...)、在 pyproject.toml 的 optional-dependencies 中声明对应 extra;如需跨包复用,则按 entry-point 规范在 pyproject.toml 暴露 oto.commands 组的映射,等待 issue #9 落地后即可生效。
连接器生态:SaaS 与浏览器自动化
oto 自定位为 "AI agent 的 CLI 工具集",覆盖 gh(GitHub)、aws(AWS)等主流 CLI 之外的长尾 SaaS 产品——v1.0.0 发布说明中明确写道 "Your LLM uses gh for GitHub, aws for AWS. oto covers the long tail"。整套生态由两类互补子系统组成:
继续阅读本节完整说明和来源证据。
- SaaS API 连接器:通过官方/非官方 HTTP 接口对接,覆盖 Google Workspace、LinkedIn、Notion、Pennylane、Serper、SIRENE、Crunchbase、Pappers、Indeed、G2、Folk CRM、WhatsApp、Kaspr、Hunter 等 15+ 服务。
- 浏览器自动化客户端:在
oto/tools/browser/下通过 Playwright/Selenium 类客户端模拟登录与抓取,覆盖 LinkedIn、Crunchbase、Pappers、WTTJ,以及通过插件扩展的 VivaTech 等。
命令发现与扩展机制
CLI 在启动时通过包内 glob 自动扫描命令模块:
for _f in _commands_dir.glob("*.py"):
...
资料来源:oto/cli.py
每个匹配文件被视为一个 Typer 命令模块,被动态加载并注册。这意味着:
- 内置命令:直接放在
oto/commands/*.py,例如browser.py、google.py、notion.py等。 - 浏览器客户端:与命令分离,存放在
oto/tools/browser/,由oto browser <site>这条总入口命令按子命令分发。
社区在 issue #9 中指出当前机制不允许第三方通过 entry-point 注入自定义命令,只能以 glob 形式加入;这限制了在不污染核心包的前提下分发"客户定制连接器"的能力,是当前架构的已知演进点。
SaaS 连接器形态
SaaS 连接器遵循统一的两层结构:
- 客户端层:每个外部服务对应一个
<Vendor>Client类,集中封装鉴权、HTTP 请求、分页与错误处理(如LinkedInClient.scrape_profile_posts)。 - 命令层:在
oto/commands/<vendor>.py中以 Typer 命令暴露原子动作(如gmail-list、gmail-search、gmail-get),并把--account等参数透传到客户端。
| 服务 | 命令文件 | 关键能力 |
|---|---|---|
| Google Workspace | oto/commands/google.py | 多账户 OAuth(otomata google auth <name>),单账户自动检测、多账户强制 --account;gmail-list/gmail-search/gmail-get 支持附件与草稿(v0.4.0) |
| Notion | oto/commands/notion.py | 页面、数据库、块的读写 |
| Folk CRM | oto/commands/folk.py | 列表、搜索、新增/更新记录 |
| Zoho / Zoho Desk | oto/commands/zoho.py、oto/commands/zohodesk.py | CRM 与工单系统的原子操作 |
资料来源:oto/commands/google.py 资料来源:oto/commands/notion.py 资料来源:oto/commands/folk.py 资料来源:oto/commands/zoho.py 资料来源:oto/commands/zohodesk.py
浏览器自动化客户端
浏览器客户端遵循 "客户端只暴露原子动作,不负责 stop-on-seen 状态" 的设计原则(issue #1 中对 collective & wttj 迁移的设计要求)。每个站点一个客户端,由 oto browser 总命令调度:
| 站点 | 客户端位置 | 引入版本 / 状态 |
|---|---|---|
oto/tools/browser/linkedin.py | 内置;v1.4.0 引入 outreach(send/connect/login),v1.4.1 增加 --profile 默认值 | |
| Crunchbase / Pappers / Indeed / G2 / Folk | oto/tools/browser/<site>.py | 内置,与 SaaS 客户端互补 |
| WTTJ (Welcome to the Jungle) | oto/tools/browser/wttj.py | v0.2.0 引入 |
| Collective | 计划中 | 见 issue #1 |
| VivaTech | 由插件 o-browser-vivatech 提供 | v1.5.0 通过 entry-point o_browser.sites 注入,安装方式 pip install oto-cli[vivatech] |
v1.5.0 的 oto browser vivatech 是首个通过 entry-point 加载的浏览器插件,证明浏览器生态已具备"核心 + 插件"骨架;但 CLI 层面的 oto.commands entry-point 仍是 roadmap 上的开放项(issue #9)。
资料来源:oto/commands/browser.py 资料来源:oto/tools/browser/
小结
oto 的连接器生态呈现 "SaaS 直连 + 浏览器抓取"双轨结构:前者负责有 API 的服务、追求稳定与可重放;后者兜底没有 API 或反爬严格的站点。命令发现目前依赖包内 glob,扩展性受限于 entry-point 尚未落地(issue #9);浏览器侧已先一步用 o_browser.sites 验证插件化路径(v1.5.0)。这两条线索共同决定了后续客户定制连接器与第三方 SaaS 接入的演进方向。
资料来源:oto/cli.py
密钥管理与自定义连接器开发
oto-cli 是一个面向 AI Agent 的 CLI 工具集,覆盖 SaaS 长尾产品的连接器。oto config provider secrets 子命令统一管理凭据的获取,而 cli.py 则负责命令的发现与注册。本页聚焦两大主题:(1) 密钥管理(secrets providers 与 scoped lookup) 与 (2) 自定义连接器开发(基于 oto.c...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
oto-cli 是一个面向 AI Agent 的 CLI 工具集,覆盖 SaaS 长尾产品的连接器。oto config provider secrets 子命令统一管理凭据的获取,而 cli.py 则负责命令的发现与注册。本页聚焦两大主题:(1) 密钥管理(secrets providers 与 scoped lookup) 与 (2) 自定义连接器开发(基于 oto.commands 与 o_browser.sites entry-points 的扩展机制)。
资料来源:oto/__init__.py:1-10
密钥管理(Secrets)
当前 Providers
CLI 通过 oto config provider secrets <file|scaleway> 暴露两种内置 provider,并以环境变量作为最终回退:
| Provider | 用途 | 资料来源 |
|---|---|---|
file | 本地加密/明文配置文件 | oto/commands/config.py:1-50 |
scaleway | Scaleway Secret Manager | oto/commands/config.py:51-100 |
env (fallback) | 直接读取 OTOMATA_* 环境变量 | docs/secrets.md:1-40 |
Lookup 顺序与 Scope
解析顺序为:file → scaleway → env。Issue #3 提出需要将其升级为可插拔架构,并暴露 SOPS 为一等 provider(位于 otomata-tech/secrets 仓库),同时为 lookup 引入 scope(如按 connector / account 限定)。
资料来源:docs/secrets.md:41-80、oto/commands/config.py:100-150
已知限制
- SOPS 尚未作为一等 provider 暴露给公开分发版本。
- 当前的 scope 仅到 provider 层,缺乏每连接器粒度的访问控制。
社区讨论见 #3。
自定义连接器开发
命令发现现状
cli.py 通过 _commands_dir.glob("*.py") 扫描 oto/commands/ 目录下的所有模块来动态加载命令。这意味着:任何不放在该目录内的客户端/连接器都不会被发现,因此客户专属的连接器无法以独立包形式分发。
资料来源:cli.py:1-40、cli.py:40-80
Plugin 机制:`oto.commands` Entry-point
Issue #9 提出建立标准化的 entry-point 协议:
[project.entry-points."oto.commands"]
my_connector = "my_pkg.commands:cli"
启动时,CLI 在 glob 内置目录之外,遍历 importlib.metadata.entry_points(group="oto.commands") 注册额外命令,从而让客户特定连接器以独立 PyPI 包形式发布。
资料来源:pyproject.toml:1-60、docs/create-connector.md:1-60
自定义连接器创建流程
- 在新包中实现子命令入口函数(例如
def cli(): ...)。 - 在
pyproject.toml注册oto.commandsentry-point。 - 通过
pip install oto-cli[my_connector]或独立pip install my-connector安装。 - 凭据通过
oto config provider secrets ...注入,避免硬编码。
资料来源:docs/create-connector.md:60-140
浏览器插件:v1.5.0 示例
浏览器侧已先一步采用 entry-points 模式:o_browser.sites 由 oto/tools/browser/__init__.py 暴露,第三方包(如 o-browser-vivatech)通过同名 group 注册。
graph LR A[oto cli] --> B[cli.py: glob oto/commands/*.py] A --> C[importlib.metadata: oto.commands] A --> D[o_browser.sites plugin load] C --> E[o-browser-vivatech] D --> F[Collective / WTTJ / LinkedIn 内置客户端]
oto browser vivatech(v1.5.0)即通过该机制加载,无需修改 core 代码。社区跟进需求见 #1 与 #9。
资料来源:oto/tools/browser/__init__.py:1-40、pyproject.toml:60-100
总结与展望
- 密钥:当前 file/scaleway/env 三级回退,未来需要 SOPS provider 与 scoped lookup(#3)。
- 连接器:
cli.py的 glob 机制正在被oto.commandsentry-points 取代,是 client-specific 隔离的关键(#9)。 - 浏览器侧:
o_browser.sites已先落地,可作为oto.commands的参考实现。
迁移到 entry-points 后,oto-cli 公共 core 与客户专属连接器将解耦,分发可通过可选 extras(如 oto-cli[vivatech])按需安装。
资料来源:docs/create-connector.md:140-200、docs/secrets.md:80-120
资料来源:oto/__init__.py:1-10
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能影响升级、迁移或版本选择。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
Pitfall Log / 踩坑日志
项目:otomata-tech/oto-cli
摘要:发现 9 个潜在踩坑项,其中 1 个为 high/blocking;最高优先级:安装坑 - 来源证据:Épic — rework secrets côté CLI : providers (keychain/sops) + lookup scopé。
1. 安装坑 · 来源证据:Épic — rework secrets côté CLI : providers (keychain/sops) + lookup scopé
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Épic — rework secrets côté CLI : providers (keychain/sops) + lookup scopé
- 对用户的影响:可能影响升级、迁移或版本选择。
- 证据:community_evidence:github | https://github.com/otomata-tech/oto-cli/issues/3 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
2. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://github.com/otomata-tech/oto-cli | host_targets=mcp_host, claude_code, claude, chatgpt
3. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/otomata-tech/oto-cli | README/documentation is current enough for a first validation pass.
4. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/otomata-tech/oto-cli | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/otomata-tech/oto-cli | no_demo; severity=medium
6. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/otomata-tech/oto-cli | no_demo; severity=medium
7. 安全/权限坑 · 来源证据:Isoler les connecteurs custom/client du core public via entry-points `oto.commands`
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Isoler les connecteurs custom/client du core public via entry-points
oto.commands - 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/otomata-tech/oto-cli/issues/9 | 来源类型 github_issue 暴露的待验证使用条件。
8. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/otomata-tech/oto-cli | issue_or_pr_quality=unknown
9. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/otomata-tech/oto-cli | release_recency=unknown
来源:Doramagic 发现、验证与编译记录