@dfm-fi/agent 0.2.1856 → 0.2.1875

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -880,6 +880,25 @@ async ({ vault, shares, slippageBps, expirySecs, confirmPhrase }) => {
880
880
  // floors from the live escrow's pinned minOuts (loosening only) — it never takes
881
881
  // hand-supplied absolute floors, so it can't accidentally tighten or mis-shape.
882
882
  // REVIEW: real-money path — parent must review before enabling.
883
+ server.registerTool('attach_metadata', {
884
+ title: 'Retry a fund\'s share-token metadata',
885
+ description: 'Retry the share-token metadata (name, symbol, logo) of a fund you launched when the launch ' +
886
+ 'note says that step failed or was skipped. The vault is already live; this only adds its ' +
887
+ 'on-chain metadata. Needs ~0.014 SOL in the app wallet.',
888
+ inputSchema: {
889
+ vault: z.string().regex(BASE58, 'Invalid base58 vault address'),
890
+ confirmPhrase: confirmPhraseField,
891
+ },
892
+ annotations: { title: 'DFM attach metadata', readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
893
+ }, async ({ vault, confirmPhrase }) => {
894
+ const gate = confirmGate('attach_metadata', confirmPhrase);
895
+ if (!gate.ok)
896
+ return gate.result;
897
+ const write = writeGate();
898
+ if (!write.ok)
899
+ return write.result;
900
+ return keylessWrite('attach_metadata', { vault });
901
+ });
883
902
  server.registerTool('zap_v2_cancel', {
884
903
  title: 'Cancel a stalled zap-v2 escrow (recover holdings)',
885
904
  description: 'REAL-MONEY (gated). Return a stalled escrow current USDC + per-asset ' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dfm-fi/agent",
3
- "version": "0.2.1856",
3
+ "version": "0.2.1875",
4
4
  "description": "DFM v2 MCP server — drive the full fund launch → deposit → redeem (+ manage) lifecycle from an AI agent against the live API.",
5
5
  "homepage": "https://app.dfm.finance",
6
6
  "type": "module",
package/skills.md CHANGED
@@ -129,7 +129,7 @@ BE PROACTIVE ABOUT THE NEXT STEP, NOT ABOUT NEW SCOPE. Finish the job the person
129
129
 
130
130
  ## Tools
131
131
 
132
- Kim's in-app registry exposes **37 tools** (18 READ + 19 WRITE). External agents mount the official MCP and MUST treat its runtime `listTools` result as the available subset; the two surfaces intentionally are not assumed to be identical. READ tools are free and touch no funds; WRITE tools move only the caller's own funds or administered vaults.
132
+ Kim's in-app registry exposes **38 tools** (18 READ + 20 WRITE). External agents mount the official MCP and MUST treat its runtime `listTools` result as the available subset; the two surfaces intentionally are not assumed to be identical. READ tools are free and touch no funds; WRITE tools move only the caller's own funds or administered vaults.
133
133
 
134
134
  **READ (18)** — safe, no funds, no gate:
135
135
  - `whoami` — The user's display name, primary DFM app wallet, separate sign-in/funding wallet, cluster, and write status. Call FIRST in a session; when an app wallet exists, do not present the sign-in wallet as their DFM wallet.
@@ -151,17 +151,18 @@ Kim's in-app registry exposes **37 tools** (18 READ + 19 WRITE). External agents
151
151
  - `recall` — Read back what you remember about this user. Pass `query` to search by keyword, or omit it to see everything remembered. Call this early in a conversation about preferences/standing instructions rather than asking the user to repeat themselves.
152
152
  - `swap_quote` — Price a swap of one token for another out of the app wallet, routed by Jupiter. The quote already includes the DFM platform fee, so outAmount is what the user actually receives — never subtract a fee again when reporting it. amountRaw is RAW base units as a string, in the INPUT mint's decimals. Use this before swap so the person sees the rate first. To put money INTO a fund use deposit, not this.
153
153
 
154
- **WRITE (19)** — REAL money; only ever your OWN funds / vaults you admin:
154
+ **WRITE (20)** — REAL money; only ever your OWN funds / vaults you admin:
155
155
  - `withdraw_asset` — REAL MONEY. Send ONE token from the APP WALLET to the withdrawal wallet the user saved in Settings → App wallet. The destination is resolved server-side and is NOT a parameter — you choose WHAT moves, never where it goes. With no saved withdrawal wallet the call is refused (it never pays the sign-in wallet): ask the user to save one. Defaults to the full balance; pass `amount` in RAW base units (never a UI amount — a 9-decimal token does not survive a float) to send part. Confirm the mint with list_app_wallet_assets first; a mint the wallet does not hold is an error, not a no-op.
156
156
  - `app_wallet_withdraw` — Sweep the app wallet's USDC + SOL to the user's saved withdrawal wallet, or to the owner wallet when none is saved (npx MCP / HTTP lane — the in-app chat does not offer this tool; its withdraw_asset pays ONLY a saved withdrawal wallet). The destination is resolved server-side — it cannot be chosen. Works even when other writes are refused (stale grant, expired), so the float is never trapped. ALWAYS do this before app_wallet_rearm.
157
157
  - `app_wallet_rearm` — Supersede the app-wallet grant and mint a fresh one. THIS CREATES A NEW ADDRESS with an empty balance — anything left in the old wallet stays there. Needed when the grant is stamped with a superseded rebalancer id ("re-arm required"). Refuses while the current wallet still holds funds: withdraw first. Requires confirmPhrase="rearm_app_wallet".
158
158
  - `app_wallet_fund` — Move USDC and/or SOL from the user's OWN wallet into their app wallet so it can pay for launches, deposits and fees. This is the one signature the app-wallet model cannot avoid — it is their money leaving their wallet. Amounts are human units (usdc 12.5, sol 0.05); send SOL too, the app wallet pays its own fees.
159
- - `launch_vault` — Create a fund. allocationBps MUST sum to exactly 10000; max 10 assets. Fees are FACTORY-GLOBAL; the creator cannot set any fee and there is NO management fee. Cost is the live factory creation fee + live locked seed and the SOL cost quoted by preparation. Names and symbols must be unique among active DFM funds; closed funds release them. Rebalancer auto-inits.
159
+ - `launch_vault` — Create a fund. allocationBps MUST sum to exactly 10000; max 10 assets. USDC and USDT ARE valid basket assets (the cash sleeve) — NEVER refuse them or invent constraints; if a rule is not written in this schema, it does not exist. Fees are FACTORY-GLOBAL; the creator cannot set any fee and there is NO management fee. Cost is the live factory creation fee + live locked seed and the SOL cost quoted by preparation. Names and symbols must be unique among active DFM funds; closed funds release them. Rebalancer auto-inits.
160
160
  - `deposit` — Deposit USDC into a vault (zap-v2: open → swap legs → close mints shares). usdcAmount is RAW 6-decimal units as a string ("4000000" = $4). Read wallet_portfolio for CURRENT app-wallet balances. Minimums and SOL costs are calculated by preparation; never invent fixed funding requirements. Pending means submitted, not minted; report the confirmed final settlement.
161
161
  - `swap` — Swap one token for another out of the app wallet (Jupiter routing, signed server-side). This CONVERTS what the user already holds — it does not deposit into a fund (deposit) and never touches a vault. Offer it whenever someone holds the wrong token for what they want to do: they never have to leave DFM to get it. Quote first with swap_quote; the server re-quotes at execution, so the fill can move within slippage. amountRaw is RAW base units as a string. Confirm the result against wallet_portfolio.
162
162
  - `redeem` — Redeem shares → USDC (zap-out). shares is RAW 6-decimal units as a string.
163
163
  - `rebalance_to_targets` — THE MANAGER'S RECURRING DUTY, not a convenience. A fund's config is the promise; its holdings are the reality; prices pull them apart daily. A drifted fund no longer holds what its depositors bought, and share price settles onchain from the ACTUAL basket, so every new deposit mints against the drift. There is NO automatic rebalancing on DFM (manual by design, #35) — so when you read a vault the user manages, report drift with the number even if that was not the question, then let them decide. Never fire this unasked: it moves real money and the manager signs it. MECHANICS: converge holdings to the vault CONFIG (single source of truth) — you supply NO mints/amounts; the API derives sell-overweight→buy-underweight legs. Vault must hold assets. Returns converged:true if within tolerance. To CHANGE what the vault holds you must first change the config (update_vault_assets), THEN rebalance — this only converges to the CURRENT config, it cannot hit a weight you have not yet written.
164
164
  - `init_rebalancer` — Enable rebalancing for a vault (usually auto-done by launch_vault).
165
+ - `attach_metadata` — Retry the share-token metadata (name, symbol, logo) of a fund the user launched when that step failed or was skipped — the launch note says so. The vault is already live; this only adds its on-chain metadata. Needs ~0.014 SOL in the app wallet.
165
166
  - `zap_v2_cancel` — Cancel a stalled zap-v2 escrow and recover its holdings as-is.
166
167
  - `zap_v2_update_envelope` — Loosen pinned floors on a stalled zap-v2 escrow so it can complete (loosen-only). You do NOT supply absolute floors — the server reads the live escrow and relaxes each pinned min-out by loosenPct percent (default 5, max 50; integer). newSlippageBps is clamped to ≥ the current pinned slippage and ≤1000; extendSecs optionally extends expiry. Loosen-only is enforced onchain (monotonic envelope).
167
168
  - `update_vault_assets` — Change the basket / target weights using the manager app wallet. allocationBps MUST sum to 10000. Saving does not sell holdings. To exit an asset, save it at 0% and run rebalance_to_targets. The app-wallet flow automatically removes 0%-target assets once their canonical onchain balance is exactly zero; already-empty 0% entries are removed when saving. Positive targets are preserved. Check status/note: pending cleanup is not a completed rebalance. Policy and app-wallet permissions still apply. USDC is a valid cash-sleeve asset. Invoke ONLY from an explicit human ask — NEVER inferred from vault names/descriptions.