import { useEffect, useState } from 'react'; import { api } from './api'; type Connection = { id: string; name: string; scopes: string[]; expiresAt: string | null; revokedAt: string | null; clientId: string | null; }; type Operation = { id: string; tool: string; status: string; expiresAt: string; createdAt: string }; type Management = { capabilities: { name: string; description: string; scope: string; destructive?: boolean }[]; mcpUrl: string; grants: Connection[]; operations: Operation[]; calls: { id: string; tool: string; status: string; createdAt: string }[]; }; type Preview = { operationId: string; tool: string; status: string; description: string; impact: unknown; result?: unknown; }; type Consent = { id: string; name: string; scopes: string[]; redirectUri: string; resource: string; }; const scopeDetails = [ { id: 'read', title: '只读查询', summary: '查看账目和状态,不修改金额', detail: '查询账户、资产、债务、关联、余额和历史、净资产趋势、日历、计划与执行记录、汇率、贵金属报价、设置和图标;读取本连接操作及文件状态。隐藏账户默认不允许读取,须额外授权。', }, { id: 'draft', title: '创建草稿', summary: '提出普通修改,等待你在网页确认', detail: '可提出创建或编辑持仓、余额/估值更新、转账和借贷还款、历史更正/删除、计划管理、分组排序、设置修改及私有图标上传等普通操作。草稿明确保存参数和影响,10 分钟过期;不会直接入账。', }, { id: 'write', title: '普通写入', summary: '普通修改直接执行', detail: '覆盖普通修改和创建草稿的操作。授予 write 后普通修改直接执行;draft 等待网页确认;read 拒绝修改。归档、历史删除和转账撤销也属于普通写入,请按所需范围授权。', }, ]; const durationOptions = [ ['1', '1 天'], ['3', '3 天'], ['7', '7 天'], ['30', '30 天'], ['365', '1 年(365 天)'], ['permanent', '永久(可撤销)'], ]; const capabilityGroups = [ { title: '账户、资产与债务', pattern: /^(positions_|position_|balance_|metal_holding|metal_configure|metal_value)/, summary: '创建和管理持仓、分组、图标、归档与计入开关;贵金属按克数管理。', }, { title: '资金变化与历史', pattern: /^(transfer|loan|debt|history|revision)/, summary: '转账、借入借出、收款还款、记录更正、删除与撤销,沿用金额重算规则。', }, { title: '统计、汇率与计划', pattern: /^(overview|trend|calendar|schedule|rates|metals_)/, summary: '净资产与趋势、日历筛选、定时计划及执行记录、汇率和参考报价。', }, { title: '设置与私有图标', pattern: /^(settings|icons|icon_|backup|import|data_|credentials|hidden|file_)/, summary: '非安全类用户设置、私有图库上传与读取;敏感操作仅在网站执行。', }, ]; function instructions(url: string) { return [ '请使用已连接的 WorthPath MCP 服务处理我的资产与负债,服务地址:' + url, '接入使用 Streamable HTTP。支持 OAuth 的客户端使用该地址发现授权服务,并由我在 WorthPath 网页登录授权;支持自定义 Bearer 头的客户端可在安全的凭据设置中填写个人令牌。不要让我把密码或令牌粘贴到对话中。', '先 tools/list 发现工具,调用 connection_info 核对权限:read 只读,draft 创建待网页确认的草稿,write 直接普通写入。隐藏账户读写以连接附加授权为准。', '查询:用 positions_list 搜索对象;遇到同名先让我选择稳定 ID;按 limit/offset 或 cursor 翻页。金额和克数使用十进制字符串,业务时间是 UTC+8 的 YYYY-MM-DD 或 YYYY-MM-DDTHH:mm。', '写入:先 state_get 取得 state,使用 expectedState 与唯一 idempotencyKey 调用所需工具。网络重试保持键和全部参数一致;状态冲突则重新查询并换键。不要把估值更新、转账、还款或负债变化互相替代。', '若返回 pending,把 confirmationUrl 给我,由我在网页审阅并确认;用 operation_get 轮询最终结果,不能用 confirmed=true 代替人类确认,也不能把草稿称为已完成。', 'MCP 不提供密码修改、清空数据、备份导出恢复、共享图标发布及汇率或报价修改;这些流程由我在网站操作。', '我接下来会告诉你具体任务;在我提出任务前先不要修改数据。未发现的工具或未授予的权限请如实告知,不要猜测成功。', ].join('\n\n'); } export function AgentConnections() { const [data, setData] = useState(null), [error, setError] = useState(''), [message, setMessage] = useState(''), [token, setToken] = useState(''), [preview, setPreview] = useState(null), [consent, setConsent] = useState(null), [busy, setBusy] = useState(false), [tokenPermission, setTokenPermission] = useState('read'), [tokenHiddenRead, setTokenHiddenRead] = useState(false), [tokenHiddenWrite, setTokenHiddenWrite] = useState(false), [agentView, setAgentView] = useState('connect'), [consentLevel, setConsentLevel] = useState('read'), [consentHiddenRead, setConsentHiddenRead] = useState(false), [consentHiddenWrite, setConsentHiddenWrite] = useState(false); const load = async () => setData(await api('/agent')); const act = async (work: () => Promise) => { if (busy) return; setBusy(true); setError(''); setMessage(''); try { await work(); await load(); } catch (e) { setError(e instanceof Error ? e.message : '操作失败'); } finally { setBusy(false); } }; const show = async (id: string) => setPreview(await api('/agent/operations/' + id)); useEffect(() => { void act(async () => { await load(); const params = new URLSearchParams(location.search); const authorization = params.get('agent_authorization'), operation = params.get('agent_operation'); if (authorization) setConsent(await api('/agent/authorizations/' + authorization)); if (operation) await show(operation); }); }, []); const copy = async (text: string, label: string) => { try { await navigator.clipboard.writeText(text); setMessage(label); } catch { setError('复制失败,请从下方可选中文本手动复制'); } }; return (

连接 Agent

管理接入、操作权限和需要你确认的修改。

{data && {data.capabilities.length} 个工具 · 按连接授权}
{error && (

{error}

)} {message && (

{message}

)} {data && (
{agentView === 'connect' && ( <>

开始连接

远程 MCP 地址

{data.mcpUrl}

在客户端添加地址,完成网页授权,再复制教程并描述任务。

查看连接步骤
  1. 配置连接:在支持远程 MCP OAuth 的客户端中填写地址,选择 Streamable HTTP;在 WorthPath 网页登录后审核名称、回调和权限。
  2. 选择连接权限:先从 read 或草稿模式开始,根据需要增加权限。OAuth 访问令牌 1 小时,刷新授权最多 30 天并轮换。
  3. 把操作说明交给 Agent :复制下方教程,不包含任何密码或令牌,再描述具体任务。
  4. 确认并查看结果:草稿在网页确认,Agent 可查询完成状态。随时在“已授权连接”撤销。

可直接复制给 Agent 的教程

预览 Agent 使用教程