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.」 资...

重点 覆盖长尾 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 客户端支持 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_sizereference_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

类别代表连接器使用形态
通用 SaaSLinkedIn、Notion、Pennylane、Crunchbase、PappersREST / Playwright
通讯Gmail、WhatsApp、Kaspr、HunterGmail 多账户 OAuth(otomata google auth <name>
数据 / 招聘SIRENE、Indeed、G2、Folk CRMAPI + 浏览器
AI 模型Mistral、Geminiclient.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-30pyproject.toml:1-60oto/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

下表总结了内置子命令与对应职责:

子命令主要模块用途
configcommands/config.pyprovider、密钥、profile 配置
googlecommands/google.pyGmail / Drive 多账户 OAuth
linkedincommands/linkedin.py登录、抓取、外联
notioncommands/notion.py页面/数据库读写
browsertools/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.tomloptional-dependencies 中声明对应 extra;如需跨包复用,则按 entry-point 规范在 pyproject.toml 暴露 oto.commands 组的映射,等待 issue #9 落地后即可生效。

资料来源:oto/commands/config.py:1-50

连接器生态: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"。整套生态由两类互补子系统组成:

章节 相关页面

继续阅读本节完整说明和来源证据。

  1. SaaS API 连接器:通过官方/非官方 HTTP 接口对接,覆盖 Google Workspace、LinkedIn、Notion、Pennylane、Serper、SIRENE、Crunchbase、Pappers、Indeed、G2、Folk CRM、WhatsApp、Kaspr、Hunter 等 15+ 服务。
  2. 浏览器自动化客户端:在 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.pygoogle.pynotion.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-listgmail-searchgmail-get),并把 --account 等参数透传到客户端。
服务命令文件关键能力
Google Workspaceoto/commands/google.py多账户 OAuth(otomata google auth <name>),单账户自动检测、多账户强制 --accountgmail-list/gmail-search/gmail-get 支持附件与草稿(v0.4.0)
Notionoto/commands/notion.py页面、数据库、块的读写
Folk CRMoto/commands/folk.py列表、搜索、新增/更新记录
Zoho / Zoho Deskoto/commands/zoho.pyoto/commands/zohodesk.pyCRM 与工单系统的原子操作

资料来源: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 总命令调度:

站点客户端位置引入版本 / 状态
LinkedInoto/tools/browser/linkedin.py内置;v1.4.0 引入 outreach(send/connect/login),v1.4.1 增加 --profile 默认值
Crunchbase / Pappers / Indeed / G2 / Folkoto/tools/browser/<site>.py内置,与 SaaS 客户端互补
WTTJ (Welcome to the Jungle)oto/tools/browser/wttj.pyv0.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...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 当前 Providers

继续阅读本节完整说明和来源证据。

章节 Lookup 顺序与 Scope

继续阅读本节完整说明和来源证据。

章节 已知限制

继续阅读本节完整说明和来源证据。

概述

oto-cli 是一个面向 AI Agent 的 CLI 工具集,覆盖 SaaS 长尾产品的连接器。oto config provider secrets 子命令统一管理凭据的获取,而 cli.py 则负责命令的发现与注册。本页聚焦两大主题:(1) 密钥管理(secrets providers 与 scoped lookup)(2) 自定义连接器开发(基于 oto.commandso_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
scalewayScaleway Secret Manageroto/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-60docs/create-connector.md:1-60

自定义连接器创建流程

  1. 在新包中实现子命令入口函数(例如 def cli(): ...)。
  2. pyproject.toml 注册 oto.commands entry-point。
  3. 通过 pip install oto-cli[my_connector] 或独立 pip install my-connector 安装。
  4. 凭据通过 oto config provider secrets ... 注入,避免硬编码。

资料来源:docs/create-connector.md:60-140

浏览器插件:v1.5.0 示例

浏览器侧已先一步采用 entry-points 模式:o_browser.sitesoto/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.commands entry-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 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 来源证据:Épic — rework secrets côté CLI : providers (keychain/sops) + lookup scopé

可能影响升级、迁移或版本选择。

medium 可能修改宿主 AI 配置

安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

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 发现、验证与编译记录