Skills / MCP

让本地 AI agent 直接操作你的 Otimififi 站点

安装 Otimififi Skill 和 MCP,让 OpenCode、Claude Code、Cursor 等本地 agent 在你的授权下查询个人站点、创建页面、写入 HTML/CSS/JS、预览并发布。

Skill

给 agent 的工作流、约束和工具说明。

MCP

在本地启动的工具服务,负责调用 Otimififi API。

Draft first

默认先写草稿和预览,确认后再发布。

准备工作

这套连接把本地 agent 绑定到你的 Otimififi 账户。开始前准备好下面四项:
  • Node.js 18 或更高版本

    MCP server 通过 npm exec 或 node 在本地运行。

  • 一个 Otimififi 账户

    Skill 和 MCP 使用你的账户权限读取或修改站点。

  • 本地 AI agent

    例如 OpenCode、Claude Code、Cursor 或其他支持 MCP 的客户端。

  • agent-skills 仓库权限

    当前 canonical 分发源是私有 GitHub 仓库,需要先完成 GitHub 登录或 SSH 配置。

如果你的 GitHub 账户还没有otimififi/agent-skills 访问权限,先联系项目维护者开通;安装命令本身不代表仓库已经公开。

获取 Otimififi 访问令牌

MCP 使用 Bearer token 调用 API,不要把网页登录 cookie 当作OTIMIFIFI_ACCESS_TOKEN。推荐先登录 Otimififi,再从侧边栏的 Access tokens 页面创建一个有名称和过期时间的令牌:

账户页会在创建后只显示一次完整 token,并支持查看前缀、过期时间和单独吊销。

打开 Developer access
API fallback for an authenticated session
fetch("https://api.otimififi.com/api/v1/access-tokens", {
  method: "POST",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Local AI agent",
    expires_in_days: 90
  })
})
  .then((response) => response.json())
  .then(console.log);

响应中的 payload.access_token 就是 MCP 要使用的值。账户页和 API 都只在创建响应中返回完整 token,请立即保存到本机安全位置;之后只能看到 token 前缀。

令牌拥有你的站点操作权限。不要提交到 Git、不要写入网页 HTML、不要上传为公开资源,也不要粘贴到公开 issue 或聊天记录中。

安装 Otimififi Skill

Skill 是一组给 agent 读取的工作流指令。推荐全局安装,这样不同项目中的 agent 都能使用它。
  1. 01

    先登录 GitHub

    任选 GitHub CLI 或 SSH。私有仓库至少要保证执行安装命令的终端可以访问 GitHub。

    任选一种 GitHub 认证方式
    gh auth login
    
    # 或确认 SSH key 已连接 GitHub
    ssh -T git@github.com
  2. 02

    全局安装 Skill

    --skill site 选择站点 Skill,-g 安装到全局,-y 跳过确认。

    Install
    npx skills add git@github.com:otimififi/agent-skills.git --skill site -g -y
    npx skills list
  3. 03

    只给指定 agent 安装(可选)

    如果不想让所有本地 agent 看到,可以指定 agent。下面以 OpenCode 为例,其他客户端使用其对应名称。

    Agent-specific install
    npx skills add git@github.com:otimififi/agent-skills.git --skill site -g -a opencode -y

配置本地 MCP server

MCP server 是一个本地 stdio 进程。AI agent 启动它后,工具调用通过本机进程转发到 Otimififi API,站点数据不会因为 MCP 配置而公开。

1. 准备环境变量

Shell
export OTIMIFIFI_API_BASE="https://api.otimififi.com"
export OTIMIFIFI_ACCESS_TOKEN="<paste-the-token-here>"

上面的 export 只对当前 shell 生效。也可以使用本地密码管理器或 agent 支持的环境变量引用,不要把真实 token 写入仓库配置。

2. OpenCode 配置

把下面的 MCP 条目合并到项目或用户级 opencode.json。其中{env:NAME} 表示从 shell 环境读取变量,不会把 token 写入 JSON。

opencode.json
{
  "mcp": {
    "otimififi-site": {
      "type": "local",
      "command": [
        "npm",
        "exec",
        "--yes",
        "--package=git+ssh://git@github.com/otimififi/agent-skills.git",
        "--",
        "otimififi-mcp-site"
      ],
      "enabled": true,
      "environment": {
        "OTIMIFIFI_API_BASE": "{env:OTIMIFIFI_API_BASE}",
        "OTIMIFIFI_ACCESS_TOKEN": "{env:OTIMIFIFI_ACCESS_TOKEN}"
      }
    }
  }
}

3. Claude Code、Cursor 等 MCP 客户端

这类客户端通常使用 mcpServers、command、args 和env 字段。把下面的条目放入客户端规定的 MCP 配置文件,并用客户端支持的环境变量引用替换 token 占位符。

mcpServers 配置形状
{
  "mcpServers": {
    "otimififi-site": {
      "command": "npm",
      "args": [
        "exec",
        "--yes",
        "--package=git+ssh://git@github.com/otimififi/agent-skills.git",
        "--",
        "otimififi-mcp-site"
      ],
      "env": {
        "OTIMIFIFI_API_BASE": "https://api.otimififi.com",
        "OTIMIFIFI_ACCESS_TOKEN": "<your access token>"
      }
    }
  }
}

4. 使用本地源码运行(开发者可选)

如果你已经克隆 Otimififi 仓库,可以直接使用本地 MCP 源码。先安装依赖,再把客户端的 command 换成 node 进程:

Local development
cd /path/to/otimififi/modules/mcp-site
npm install
替换 command / environment
{
  "command": [
    "node",
    "/absolute/path/to/otimififi/modules/mcp-site/src/index.js"
  ],
  "environment": {
    "OTIMIFIFI_API_BASE": "{env:OTIMIFIFI_API_BASE}",
    "OTIMIFIFI_ACCESS_TOKEN": "{env:OTIMIFIFI_ACCESS_TOKEN}"
  }
}
不要在终端里单独运行 MCP 后期待 agent 自动连接。stdio MCP 应由 AI 客户端按照配置启动;改完配置后重启客户端,才能看到工具列表。

验证连接

重启 agent 后,先做一次只读检查。成功时应该能看到当前用户 profile 和可见网站列表。
推荐的第一条 prompt
请使用 otimififi-site skill。
先调用 auth_status,确认当前用户身份;然后调用 list_websites,
只读取我可见的网站并返回每个网站的 id、title 和 preview URL。
这一步不要修改或发布任何内容。

也可以直接观察 agent 是否暴露了 auth_status 和list_websites。如果工具列表为空,优先检查 MCP 配置文件路径、JSON 格式和客户端是否已重启。

查询个人站点信息

查询时让 agent 先认证、再读取站点和页面,不要一上来就修改内容。list_websites 的workspace 参数可选;不传时查询个人工作区,需要组织站点时再传组织 ID。
Read-only query prompt
请使用 otimififi-site skill 查询我的个人站点。
1. 先调用 auth_status。
2. 调用 list_websites,不传 workspace,列出 personal workspace 中的网站。
3. 对我指定的网站调用 get_website 和 list_pages。
4. 返回网站 id、标题、preview URL,以及每个页面的 page id、pathname 和 full_url。
整个过程只读,不要创建、更新或发布内容。
目的MCP tools结果
查询auth_status, list_websites, get_website, list_pages, get_page读取当前用户、网站和页面信息
创建与修改create_website, update_website, create_page, update_page_meta创建网站、页面和元数据
写入内容upsert_page_html把 body 或 full_html 写入草稿
资源upload_asset, set_page_assets, set_website_assets上传并挂载 CSS、JS、图片和字体
发布get_public_urls, publish_page获取预览/线上地址,提交草稿并切换线上版本

创建网站与页面

建站时坚持“先发现、再创建、先草稿、后发布”。这样 agent 不会因为上下文不完整而重复创建网站,也不会未经确认把页面直接上线。
  1. 01

    确认账户和已有网站

    调用 auth_status 和list_websites,先判断是否应该复用现有网站。
  2. 02

    创建网站并找到页面

    没有合适网站时调用 create_website,拿到website_id 后调用 list_pages。 如果没有首页,再用 create_page 创建pathname: "" 的首页。
  3. 03

    写入 HTML 草稿

    调用 upsert_page_html。默认import_mode: "body" 只写页面 body;需要让系统从完整文档提取 title、style、link 和 script 时使用full_html。
  4. 04

    获取预览并等待确认

    调用 get_public_urls,把预览地址返回给用户。没有明确确认前,不要调用publish_page。
Create + draft prompt
请使用 otimififi-site skill 创建一个个人作品集网站。
先调用 auth_status 和 list_websites,避免重复创建;如果没有合适的网站,
调用 create_website 创建一个标题为「我的作品集」的网站,然后调用 list_pages。
复用或创建 pathname 为 "" 的首页,使用 upsert_page_html 写入 full_html 草稿,
页面包含简介、精选项目和联系入口。完成后调用 get_public_urls 返回预览链接。
先不要调用 publish_page,等我确认预览后再发布。

body 和 full_html 的区别

body 模式适合只提交页面主体,站点的 head 资源另行配置;full_html 模式会读取完整文档,把<body> 保存为页面内容,并提取安全的 head 资源配置。

full_html
upsert_page_html({
  page_id: "<page_id>",
  import_mode: "full_html",
  html: "<!doctype html><html><head><title>我的作品集</title></head><body><main><h1>你好,世界</h1></main></body></html>"
})
body
upsert_page_html({
  page_id: "<page_id>",
  import_mode: "body",
  html: "<main><h1>你好,世界</h1></main>"
})
页面路径不要带开头的 /。首页使用空字符串"",例如 about 对应/about。

添加 CSS、JS、图片和字体

如果 HTML 不内联资源,先调用 upload_asset,再把返回的public_url 写入页面或网站级 head 配置。
upload_asset + set_page_assets
const css = upload_asset({
  name: "site.css",
  type: "text/css",
  content: "body { margin: 0; }",
  website_id: "<website_id>"
});

set_page_assets({
  page_id: "<page_id>",
  config: {
    cssFileLinks: [{ href: "<css public_url>" }],
    jsFileLinks: [{
      src: "<js public_url>",
      defer: true,
      position: "body_end"
    }]
  }
});

页面级资源

用 set_page_assets,只影响当前页面的 draft。

网站级资源

用 set_website_assets,合并到该网站的每个页面。

常用 MIME type:CSS 使用 text/css,JS 使用text/javascript 或application/javascript,图片使用对应的 image type,字体使用font/woff2。JS 通常设置defer: true 和position: "body_end"。

预览与发布

页面写入后仍然是 draft。发布由 publish_page 完成,它会提交 draft,并在set_live: true 时切换线上版本。
Recommended workflow
list_websites / get_public_urls
  -> create_website or reuse an existing website
  -> list_pages
  -> create_page or reuse a page
  -> upsert_page_html (draft)
  -> upload_asset / set_page_assets (optional)
  -> get_public_urls (preview)
  -> publish_page (only after confirmation)

发布前让 agent 返回 get_public_urls 的预览地址;用户确认后,再发出类似下面的明确指令:

Publish only after approval
请发布刚才确认的页面,使用 publish_page,set_live 设为 true。
发布完成后调用 get_public_urls,并返回 site_url 和该页面的 full_url。
最终交付至少应包含网站 site_url 和页面full_url。如果只返回了内部 ID,继续调用get_public_urls,不要猜测线上地址。

安全与排错

给 agent 的 prompt 越具体越安全。涉及写入或发布时,明确要求先读取、先草稿、等待确认。
GitHub 403 / clone failed
检查 GitHub 账户是否被授予私有仓库权限,并确认 SSH key 或gh auth login 使用的是同一个账户。
OTIMIFIFI_API_BASE error
MCP 进程没有拿到环境变量。检查客户端配置中的environment 或 env,并重启 agent。
401 Unauthorized
令牌无效、被替换或没有复制完整。重新生成 token,更新本地环境变量后再启动 MCP。
工具没有出现
确认 JSON 没有注释或尾逗号,command 指向正确的 npm/node,之后完全退出并重新打开 AI 客户端。
资源没有生效
确认先完成 upload_asset,再使用返回的public_url 调用 set page/site assets,并重新生成预览。
对不受信任的 HTML 保持默认安全策略:不要注入 token、javascript: URL 或事件处理器属性,例如onclick。需要外部脚本时,先上传资源并明确它的来源。

准备好后,从一次只读查询开始。

先验证身份和现有站点,再让 agent 创建草稿。这样每一步都有可检查的结果,发布也始终由你确认。