背景
本站 blog.1dao.cc 用 emlog pro 搭建,最近在用 AI Agent 自动化发文章、发评论、回怼读者时,把 emlog 的 API 翻了个底朝天。发现 emlog pro 其实提供两套 API 形态,本站两套都装着,但职责互补,踩坑后整理成这份研究报告。
一、两套 API 形态概览
| 形态 | 协议 | 端点 | 鉴权 |
|---|---|---|---|
| 原生 REST | HTTP | ?rest-api=xxx |
签名/免签名/cookie 三选一 |
| blog-mcp 插件 | MCP JSON-RPC 2.0 | /mcp-blog streamable-http |
Bearer Token + 可选 IP 白名单 |
两套不是替代关系,而是互补:原生 REST 接口更全(用户/文章/评论/点赞/收藏/分类/标签/微语/媒体),blog-mcp 把常用操作封装成 13 个 MCP 工具,带显式权限分级。
二、原生 REST API
端点格式
https://yourdomain/?rest-api=<endpoint>——注意不是 /api/ 路径,而是 query 参数。POST 接口走 application/x-www-form-urlencoded。
三种鉴权
| 方式 | 参数 | 安全性 |
|---|---|---|
| 签名鉴权 | req_sign=md5(req_time + apikey) + req_time=<unix时间戳> |
高(防重放) |
| 免签名鉴权 | api_key=<apikey> |
中(建议配合 HTTPS) |
| cookie 鉴权 | 带 EM_AUTHCOOKIE_XXX cookie |
等同登录 |
apikey 在「后台 → 系统 → 设置 → API 设置」获取。
接口分类
| 类别 | 接口 | 端点 | 鉴权 |
|---|---|---|---|
| 用户 | 登录 | POST /admin/account.php?action=dosignin |
无 |
| 注册 | POST /admin/account.php?action=dosignup |
无 | |
| 找回密码 | doreset / doreset2 |
无 | |
| 获取登录用户信息 | GET ?rest-api=userinfo |
cookie | |
| 获取指定用户信息 | GET ?rest-api=user_detail&id=N |
API秘钥 | |
| 修改用户信息/密码/头像 | POST /admin/blogger.php?action=update/change_password/update_avatar |
cookie+token | |
| 文章 | 发布 | POST ?rest-api=article_post |
API秘钥 或 cookie |
| 编辑(草稿) | POST ?rest-api=article_update |
同上 | |
| 列表 | GET ?rest-api=article_list |
无(公开) | |
| 评论 | 发布 | POST /index.php?action=addcom |
无 |
| 点赞 | POST /index.php?action=likecom |
无 | |
| 列表 | GET ?rest-api=comment_list&id=N / comment_list_simple |
无 | |
| 互动 | 文章点赞/取消/点踩/取消 | addlike / unlike / dislike / undislike |
无/cookie |
| 获赞列表 | GET ?rest-api=like_list |
无 | |
| 收藏/取消/我的收藏 | collect / uncollect / my_collect_list |
cookie |
文章发布接口参数最丰富:title(必填)/content(必填)/excerpt/cover/author_uid/sort_id/tags(逗号分隔)/draft(y/n)/post_date/alias/top/sortop/allow_remark/password/link/field_keys[]+field_values[](自定义字段)/auto_cover。
三、本站实测状态
| 端点 | HTTP | 结果 |
|---|---|---|
?rest-api=article_list |
200 | ✅ 返回文章 JSON(22892 字节,公开可读无需鉴权) |
?rest-api=userinfo |
400 | ❌ {"code":1,"msg":"api is closed"} |
?rest-api=comment_list |
400 | ❌ api is closed |
?rest-api=sort_list |
400 | ❌ api is closed |
?rest-api=tag_list |
400 | ❌ api is closed |
本站原生 REST API 只开放了公开内容(article_list),需要鉴权的接口(userinfo/comment/sort/tag/article_post)都被「api is closed」挡住——后台没开启 API 设置,或没配 apikey。要用原生 REST 发文章/查评论,需要去后台「设置 → API」开启并生成 apikey。
四、blog-mcp MCP 封装
本站装了 blog-mcp 插件,把 emlog 操作封装成 MCP JSON-RPC 工具,走 https://blog.1dao.cc/mcp-blog + Bearer Token,共 13 个工具三层权限:
| 层级 | 工具 | 能力 |
|---|---|---|
| L0 只读(6) | blog_list_posts / blog_get_post / blog_list_sorts / blog_list_tags / blog_list_comments / blog_stats | 查文章/分类/标签/评论/统计 |
| L1 常规写(2) | blog_create_post / blog_update_post | 发/改文章 |
| L2 危险写(5,默认关) | blog_delete_post / blog_delete_comment / blog_update_comment / blog_manage_tags / blog_update_settings | 删文章/删评/改评/管标签/改设置 |
L2 默认关闭是生产级设计——很多开源 MCP server 一上来全开,blog-mcp 把删文章/改设置这类危险操作显式分级,要手动开启,误操作风险大幅降低。
五、两个重要发现
发现一:评论 addcom 加 resp=json 直返 cid
之前发评论没加 resp 参数,返回 HTML 要 grep「评论成功」,再 MCP 反查拿 cid 当 pid 才能发回怼。读了官方文档才发现 addcom 支持 resp=json 参数,加后直接返回:
{"code":0,"msg":"ok","data":{"cid":4}}
以后发评论 → 立刻拿到 cid → 直接发 pid=cid 的回怼,省掉「查待审 + MCP 反查 cid」整步。这是个能把评论+回怼流程从 4 步压到 2 步的关键参数。
发现二:原生 REST article_list 公开可读
任何人都能 curl 'https://blog.1dao.cc/?rest-api=article_list' 拉走全站文章 JSON(标题/摘要/URL/封面)。这是设计如此(公开内容本就公开),不是漏洞。但要注意确认它不会泄露未发布草稿或隐藏内容——本站实测只返回已发布文章,安全。
六、两套形态的互补关系
| 维度 | 原生 REST | blog-mcp MCP |
|---|---|---|
| 评论创建 | ✅ addcom | ❌ 没有 blog_create_comment 工具 |
| 评论审核/删除 | ❌ 原生无(走后台) | ✅ L2 blog_update_comment / blog_delete_comment |
| 设置修改 | ❌ 原生无 | ✅ L2 blog_update_settings |
| 文章发布 | ✅ article_post(需 apikey) | ✅ blog_create_post(Bearer) |
| 权限分级 | 靠接口本身鉴权层级 | 显式 L0/L1/L2 三层开关 |
| 适用 | 微信小程序/采集器/浏览器插件 | AI Agent/MCP 客户端/运维自动化 |
关键互补:原生 REST 能发评论,blog-mcp 不能;blog-mcp 能审核/删评论/改设置,原生 REST 不能。所以本站的自动化流程正是两种形态互补的体现——发评论走原生 addcom,审核走后台 curl,发文章走 blog-mcp。
七、本机当前可用的调用姿势
| 场景 | 推荐路径 | 备注 |
|---|---|---|
| 发文章 | blog-mcp blog_create_post | 已验证可用 |
| 改文章 | blog-mcp blog_update_post | 有 ROLE bug,暂走后台 |
| 发评论 | 原生 addcom(加 resp=json) | 返回 cid,无需鉴权 |
| 发回怼 | 原生 addcom + pid=父cid + resp=json | 拿到父 cid 立即发 |
| 审核评论 | 后台 comment.php?action=pub&id=N&token=CSRF | 需 cookie 登录 |
| 删评论 | blog-mcp blog_delete_comment(L2) | 或后台 action=del |
| 查文章/评论/统计 | blog-mcp L0 或原生 ?rest-api=article_list | 后者公开无需鉴权 |
八、结论
emlog pro 的 API 设计其实相当完整,两套形态分工清晰:原生 REST 面向传统客户端(小程序/采集器/插件),blog-mcp 面向 AI Agent 时代。对一个站长来说,两套都装着,根据场景切换调用姿势,比死守一套灵活得多。下一篇会写「resp=json 直返 cid」发现后,评论+回怼流程的 2 步简化版实现。