T2 token 管理(src/api/mcp_tokens.rs):create/list/reveal/revoke + get_mcp_client_configs
服务端函数,均经 get_current_admin_user 鉴权;TokenLifetime 枚举(1/7/30/90天/永不过期)。
src/mcp/config.rs 生成 4 种客户端配置(Claude Code/Cursor/Cline/通用 + CLI)。
src/pages/admin/mcp.rs 令牌管理页:列表 + 新建表单 + 一次性明文展示/重查 + 撤销 +
配置片段卡片。路由 /admin/mcp,导航项加入 admin_layout。
T3 read 工具 + Resources(tools/read.rs, resources.rs):search_posts/get_post/list_tags
(read 作用域,仅已发布);published-post Resources(post://{slug},游标分页)。
search_published 提取为共享函数。
T4 write 工具(tools/{posts,comments,tags,media}.rs):create/update/publish/trash/delete_post、
评论审核、标签 CRUD、媒体 base64 上传(WebP 转码 + 去重)。复用既有 helper 的 SQL 与
缓存失效(moka + ssr_cache)。write 作用域,可读草稿。
T5 admin 工具(tools/{settings,runner}.rs):get/update_settings、run_code(沙箱执行)。
admin 作用域。
合并(server.rs):用 rmcp tool_router 的「命名路由 + 组合」模式,7 个工具组在
YggMcpServer 上 impl,combined_router 用 + 合并成单一 ServerHandler。各工具组鉴权
独立,经 Extension<Parts> 读 McpPrincipal + scope.grants 校验。
新增依赖 base64 0.22(媒体上传解码)。验证:server/web 双目标编译通过、clippy
--all-features -D warnings 干净、659 单测 + 1 集成全绿(+20 新测试)。
1.7 KiB
1.7 KiB
T4 — write-scope tools (post CRUD, comments, tags, media)
Blocking edges
- Blocks: T6 (hardening covers these).
- Blocked by: T1 (mount + auth + dispatch exist).
Target files
src/mcp/tools/posts.rs,src/mcp/tools/comments.rs,src/mcp/tools/tags.rs,src/mcp/tools/media.rs— new.src/mcp/server.rs— register write tools (scope-gated).
Change
Reuse existing server-fn / helper logic — do NOT duplicate business rules. Each write
tool calls the same helpers the web admin uses, then runs the same cache invalidation
(moka invalidate_* + ssr_cache::invalidate_ssr_*).
- Posts:
create_post,update_post,publish_post,trash_post,delete_post.write/adminscope. These tokens MAY read drafts (decision 7).create_postmustspawn_blocking(render_markdown_enhanced)and persistcontent_html, exactly likesrc/api/posts/create.rs. - Comments:
list_comments,approve_comment,delete_comment,set_comment_status— delegate tosrc/api/comments/*helpers. - Tags:
create_tag,rename_tag— delegate tosrc/api/posts/tags.rs. - Media:
upload_media(filename, base64, alt?)— feed the existing upload pipeline (src/api/upload.rs); return the served URL for embedding in posts.
Acceptance
- A
write-tokencreate_postwrites a row, renderscontent_html, and invalidates the matching moka + SSR caches (web admin sees the new post immediately). - A
readtoken calling any write tool →insufficient_scoperejection. write/admintokens can read drafts viaget_post;readtokens cannot.- Media upload returns a usable image URL consumable in post body.
- Both targets compile; clippy clean; existing tests pass.