Raphael-noah

From Safari To API — Development skill for Claude Code

Development community

Turn Safari web chats (DeepSeek, etc.) into a local OpenAI/Anthropic-compatible API — no API key, no cost.

How to install From Safari To API

This entry records only its repository, not the path inside it, so there is no exact command to give. Open Raphael-noah/from-safari-to-api and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

What From Safari To API does

Turn Safari web chats (DeepSeek, etc.) into a local OpenAI/Anthropic-compatible API — no API key, no cost. Drop-in for Claude Code / ccswitch.(把 Safari 网页对话(DeepSeek 等)包装成本地 OpenAI/Anthropic 兼容 API —— 不要 API key、不花钱,可直接接入 Claude Code / ccswitch)

Alternatives in Development

  • Dario — A local OpenAI- and Anthropic-compatible proxy that brings your Claude Pro/Max subscription to Cursor, Cline 485 ★
  • Notebook Intelligence — A JupyterLab extension supporting Claude Code, Copilot, Ollama, and OpenAI-compatible LLMs, with MCP, skills 331 ★
  • Claude Code API — OpenAI-compatible API gateway for Claude Code CLI 300 ★

README

**🌐 [English](README_EN.md) | 中文**

from-safari-to-api

把 Safari 的网页对话界面(如 chat.deepseek.com)包装成 API(毕竟大多数情况下网站是免费的)。也可接入 Claude Code / ccswitch 等 agent 工具(支持Anthropic Messages API 与 OpenAI Chat Completions 两套协议)。

架构

项目由两个组件构成,各自独立:

HTTP 客户端
 │ POST /chat · /v1/chat/completions · /v1/messages
 ▼
server.py FastAPI  门面:收请求 → 调 osascript → 解析输出 → 映射成 HTTP 响应
 │ osascript check.applescript -p … -i … -r …
 ▼
check.applescript  Safari 自动化引擎:向当前标签页注入 prompt → 提交 → 轮询抓取回复
 │ do JavaScript / KeyboardEvent
 ▼
Safari 当前窗口的当前标签页
  • check.applescript 是自动化引擎。它只操作 Safari「当前窗口的当前标签页」,把 prompt 写进页面输入框、触发提交、轮询结果节点,最后把最终文本打印到 stdout。
  • server.py 是 HTTP 门面。它不接触浏览器,只负责收请求、以 argv 方式调用脚本、解析脚本的输出协议、把结果翻译成 HTTP 响应。

注:之所以那玩意叫check.applescript是因为这玩意本来是为了验证我的想法用的,后来一直没改名

两者通过一条明确的接口通信(见「输出协议」一节),可以分别修改而不互相破坏。

环境要求

  • 仅限 macOS。整个项目建立在 Safari + AppleScript + osascript 之上,Linux / Windows 跑不了。
  • Safari:脚本驱动的是 Safari 当前窗口的当前标签页,Chrome / Firefox 都不行。
  • Python 3.13+,外加 fastapi、uvicorn(见 requirements.txt)。
  • 目标网页要在 Safari 里调整到可以输入的位置,我们没有高级到帮你登录并查找网页。

组件:check.applescript

命令行接口

osascript check.applescript -p -i <输入框选择器> -r <结果选择器> [-b <发送按钮选择器>] [-c <继续按钮选择器>] [--poll-interval <秒>] [--poll-max <次数>]

参数 必填 说明
-p / --prompt 是 要注入的提示词
-i / --input 是 输入框 CSS 选择器
-r / --result 是 结果节点 CSS 选择器
-b / --button 否 发送按钮选择器;留空则对输入框派发回车键事件
-c / --continue-selector 否 「继续」按钮选择器;留空则按按钮文本自动识别
--poll-interval 否 每次轮询间隔秒数,默认 3
--poll-max 否 最大轮询次数,默认 60
-h / --help 否 打印用法

输出协议

脚本在 stdout 上输出两行式协议,server.py 按首行解析:

OK:
<结果文本>
ERR:
<错误信息>

成功时首行为 `OK:`,其后为抓取到的正文;失败时首行为 `ERR:`,其后为原因(缺少参数、注入失败、按钮/输入框未找到、轮询超时等)。首行以 \n 分隔,正文保留原始换行。

工作流程

  1. 注入:把 prompt 转义为 JS 单引号字符串,用 nativeSetter 写入输入框并派发 input 事件,然后按回车或点击发送按钮提交。
  2. 轮询:每隔 --poll-interval 秒读取结果节点文本。当文本连续 3 次轮询保持不变,判定生成完成。
  3. 续写:因为某些原因网页生成自己停止时(我不知道为什么),脚本会自动点击「继续」按钮取回剩余内容,并把该次轮询标记为「未稳定」以继续等待。 (这玩意不好用,建议自己用手