用途:在本地测试仅限员工使用的托管迁移 MCP 工具(managed-migrations-support-list 等)。前置条件:开发环境需 Docker 服务健康;需要 is_staff=True 的员工用户;Personal API Key 必须同时显式携带 batch_import_support:read 与 user:read;需应用 Postgres 迁移(不需要 ClickHouse)。两个 scope 缺一不可:后端单独接受 batch_import_support:read,但 MCP 工具发现会通过 /api/users/@me/ 校验员工身份,无法调用时按 fail-closed 隐藏工具;* 通配符不能替代任一 scope。
主要步骤:1) 启动环境:hogli start -d 与 hogli wait(migrate-persons-db、migrate-behavioral-cohorts 失败可忽略,migrate-postgres 失败需查端口转发)。2) 运行迁移:hogli migrations:run,ClickHouse 迁移失败无妨。3) 用 hogli dev:shell-plus 验证数据库连通。4) 造 BatchImport 种子数据,注意 secrets 为 EncryptedJSONStringField,空 {} 会序列化为 null 触发 NOT NULL 约束,须传非空 dict;本地 batch-import-worker 会认领 RUNNING 记录并可能改状态,建议停掉 worker 或使用 COMPLETED/FAILED/PAUSED。5) 将用户设为 staff 并新签发密钥(MCP 按 token 缓存 scope,编辑旧 key 会读到旧结果);为测试负例还需签发 ["*"]、仅 batch_import_support:read、以及非员工用户的全 scope 密钥。6) 用 curl 直连 http://localhost:8010/api/managed_migrations_support/ 测试。7) 通过 MCP 测试:运行 Hono 服务器而非 pnpm run dev(wrangler worker 会把 /mcp 代理到生产,导致本地 key 401),在 services/mcp 下复制 .dev.vars.example 为 .dev.vars 并设 POSTHOG_API_BASE_URL=http://localhost:8010,执行 pnpm run dev:hono,服务地址 http://localhost:3001/mcp;用 PAT 作 Bearer 头认证,不要用 OAuth(隐藏 scope 在 OAuth 中结构性缺失)。Hono 为 exec 模式,tools/list 只返回一个 exec 工具,真实工具经其发现与调用,可用 MCP Inspector CLI 测试。
预期发现矩阵:员工 + 两个 scope 可见两个工具;员工仅 * 不可见;员工仅 batch_import_support:read 不可见(员工查询 fail-closed);非员工即使两个 scope 也不可见且直连 API 返回 403。
限制与排错:localhost:8787 返回 401 说明连到了代理生产的 worker,改用 3001 或设 MCP_HONO_URL;工具不出现时依次检查 scope 是否显式、是否含 user:read、用户是否 staff、密钥是否新签发;5432 不可达可强制重建 db 容器;secrets={} 会违反 NOT NULL;worker 会改动 RUNNING 记录。安全边界由 Django 的 IsAuthenticated + IsStaffUser + APIScopePermission(scope_object=INTERNAL 与 batch_import_support:read)执行,会话仅需员工身份,PAT 需员工身份加显式 scope,仅 * 的密钥始终 403。