@zktx.io/sui-mcp 0.5.0

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.
Files changed (218) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/@mysten-bcs-2.0.5-Apache-2.0.txt +205 -0
  3. package/LICENSES/@mysten-sui-2.17.0-Apache-2.0.txt +201 -0
  4. package/LICENSES/@mysten-utils-0.3.3-Apache-2.0.txt +205 -0
  5. package/LICENSES/fancy-canvas-2.1.0-MIT.txt +7 -0
  6. package/LICENSES/lightweight-charts-5.2.0-NOTICE.txt +2 -0
  7. package/README.md +288 -0
  8. package/dist/adapters/adapterLifecycleValidators.js +5 -0
  9. package/dist/adapters/adapterPromptSurfaces.js +60 -0
  10. package/dist/adapters/deepbook/deepbookHumanReviewProducer.js +178 -0
  11. package/dist/adapters/deepbook/deepbookQuotePolicy.js +112 -0
  12. package/dist/adapters/deepbook/deepbookReviewEvidence.js +507 -0
  13. package/dist/adapters/deepbook/deepbookReviewLifecycle.js +85 -0
  14. package/dist/adapters/deepbook/deepbookSwapIntent.js +79 -0
  15. package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +254 -0
  16. package/dist/adapters/intentPlanFactories.js +51 -0
  17. package/dist/adapters/reviewAdapters.js +47 -0
  18. package/dist/core/action/adapterLifecycleValidation.js +12 -0
  19. package/dist/core/action/contractNameRegistry.js +151 -0
  20. package/dist/core/action/forbiddenFields.js +43 -0
  21. package/dist/core/action/humanReadableReviewEvidence.js +193 -0
  22. package/dist/core/action/humanReadableReviewProjectionVerifier.js +29 -0
  23. package/dist/core/action/ptbVisualizationProducer.js +71 -0
  24. package/dist/core/action/receiptPtbGraph.js +29 -0
  25. package/dist/core/action/reviewCheckResults.js +6 -0
  26. package/dist/core/action/reviewStateValidation.js +11 -0
  27. package/dist/core/action/reviewTimeSimulationEvidence.js +470 -0
  28. package/dist/core/action/schemas.js +491 -0
  29. package/dist/core/action/signableAdapterContract.js +998 -0
  30. package/dist/core/action/suiChainReceiptEvidence.js +106 -0
  31. package/dist/core/action/suiChainReceiptMapping.js +107 -0
  32. package/dist/core/action/suiChainReceiptReader.js +211 -0
  33. package/dist/core/action/suiChainReceiptVerifier.js +178 -0
  34. package/dist/core/action/swapHumanReadableReviewProjection.js +130 -0
  35. package/dist/core/action/swapQuotePolicyEvidence.js +271 -0
  36. package/dist/core/action/transactionFunding.js +244 -0
  37. package/dist/core/action/transactionObjectOwnershipEvidence.js +256 -0
  38. package/dist/core/action/transactionObjectOwnershipProducer.js +323 -0
  39. package/dist/core/action/types.js +33 -0
  40. package/dist/core/action/walletReviewContractAssembler.js +286 -0
  41. package/dist/core/activity/accountAssetTimeline.js +157 -0
  42. package/dist/core/activity/accountAssetTimelineUsdcReferences.js +120 -0
  43. package/dist/core/activity/activityStore.js +16 -0
  44. package/dist/core/activity/externalActivityCoverage.js +76 -0
  45. package/dist/core/activity/externalActivityTransactionStream.js +82 -0
  46. package/dist/core/activity/localDataService.js +296 -0
  47. package/dist/core/activity/localDataTypes.js +11 -0
  48. package/dist/core/activity/localDataValidation.js +439 -0
  49. package/dist/core/activity/schemaVersion.js +2 -0
  50. package/dist/core/activity/sqliteActivityStore.js +1068 -0
  51. package/dist/core/activity/sqliteActivityStoreRows.js +389 -0
  52. package/dist/core/activity/sqliteActivityStoreSchema.js +367 -0
  53. package/dist/core/activity/sqliteActivityStoreTypes.js +5 -0
  54. package/dist/core/activity/suiFunctionTarget.js +43 -0
  55. package/dist/core/activity/transactionActivityAccountEffects.js +186 -0
  56. package/dist/core/activity/transactionActivityAnalysis.js +295 -0
  57. package/dist/core/activity/transactionActivityClassifier.js +306 -0
  58. package/dist/core/activity/transactionActivityDetails.js +229 -0
  59. package/dist/core/activity/transactionActivityProtocolRules.js +218 -0
  60. package/dist/core/activity/transactionActivityScanPolicy.js +170 -0
  61. package/dist/core/activity/transactionActivityService.js +379 -0
  62. package/dist/core/activity/transactionActivityTypes.js +18 -0
  63. package/dist/core/eventlog/sink.js +35 -0
  64. package/dist/core/evidence/settlementFamilies.js +85 -0
  65. package/dist/core/evidence/userAnswerUse.js +1 -0
  66. package/dist/core/numeric/rawU64.js +63 -0
  67. package/dist/core/preferences/preferencesStore.js +26 -0
  68. package/dist/core/preferences/sqlitePreferencesRepository.js +136 -0
  69. package/dist/core/proposal/externalProposalReview.js +347 -0
  70. package/dist/core/proposal/schemas.js +208 -0
  71. package/dist/core/proposal/types.js +35 -0
  72. package/dist/core/read/amounts.js +14 -0
  73. package/dist/core/read/coinMetadata.js +60 -0
  74. package/dist/core/read/deepbookOfficialIndexerSource.js +373 -0
  75. package/dist/core/read/deepbookRawQuoteClient.js +86 -0
  76. package/dist/core/read/deepbookReadHelpers.js +321 -0
  77. package/dist/core/read/deepbookRegistry.js +157 -0
  78. package/dist/core/read/deepbookSourceOwners.js +159 -0
  79. package/dist/core/read/deepbookUsdcChartService.js +342 -0
  80. package/dist/core/read/intentEvidenceResponseFormatting.js +228 -0
  81. package/dist/core/read/readCardInputs.js +19 -0
  82. package/dist/core/read/readCardResult.js +40 -0
  83. package/dist/core/read/readResponseGuidance.js +402 -0
  84. package/dist/core/read/readService.js +1639 -0
  85. package/dist/core/read/readServiceTypes.js +88 -0
  86. package/dist/core/read/settlementParityFormatting.js +82 -0
  87. package/dist/core/read/walletReadHelpers.js +99 -0
  88. package/dist/core/review/reviewChecks.js +45 -0
  89. package/dist/core/review/reviewComputation.js +38 -0
  90. package/dist/core/review/reviewComputationResult.js +87 -0
  91. package/dist/core/session/cardSession.js +31 -0
  92. package/dist/core/session/cardSessionStore.js +204 -0
  93. package/dist/core/session/keyedRecordStore.js +18 -0
  94. package/dist/core/session/liveReviewSessionContract.js +3 -0
  95. package/dist/core/session/localSession.js +31 -0
  96. package/dist/core/session/privateReviewArtifacts.js +75 -0
  97. package/dist/core/session/reviewValidity.js +49 -0
  98. package/dist/core/session/sessionErrors.js +9 -0
  99. package/dist/core/session/sessionRecordStore.js +40 -0
  100. package/dist/core/session/sessionStore.js +655 -0
  101. package/dist/core/session/settingsSession.js +1 -0
  102. package/dist/core/session/settingsSessions.js +45 -0
  103. package/dist/core/session/sqliteCardStore.js +88 -0
  104. package/dist/core/session/sqliteSessionStore.js +213 -0
  105. package/dist/core/session/sqliteTransactionMaterialStore.js +64 -0
  106. package/dist/core/session/sqliteWalletWorkflowStore.js +821 -0
  107. package/dist/core/session/status.js +60 -0
  108. package/dist/core/session/transactionMaterialStore.js +221 -0
  109. package/dist/core/session/transactionRequest.js +72 -0
  110. package/dist/core/session/wait.js +79 -0
  111. package/dist/core/session/walletConnection.js +92 -0
  112. package/dist/core/session/walletRuntime.js +38 -0
  113. package/dist/core/session/walletWorkflow.js +608 -0
  114. package/dist/core/session/workflowState.js +80 -0
  115. package/dist/core/session/workflowView.js +150 -0
  116. package/dist/core/suiAddress.js +18 -0
  117. package/dist/core/suiEndpoint.js +72 -0
  118. package/dist/mcp/activeAccountResponse.js +24 -0
  119. package/dist/mcp/prompts.js +146 -0
  120. package/dist/mcp/registerTool.js +19 -0
  121. package/dist/mcp/resources.js +72 -0
  122. package/dist/mcp/responseGuidance.js +326 -0
  123. package/dist/mcp/result.js +17 -0
  124. package/dist/mcp/schemas.js +11 -0
  125. package/dist/mcp/server.js +32 -0
  126. package/dist/mcp/serverInfo.js +131 -0
  127. package/dist/mcp/toolErrors.js +118 -0
  128. package/dist/mcp/toolNames.js +58 -0
  129. package/dist/mcp/tools/account/index.js +44 -0
  130. package/dist/mcp/tools/action/prepareSuiActionReview.js +126 -0
  131. package/dist/mcp/tools/read/commonSchemas.js +43 -0
  132. package/dist/mcp/tools/read/deepbookReadTools.js +686 -0
  133. package/dist/mcp/tools/read/index.js +14 -0
  134. package/dist/mcp/tools/read/readToolHelpers.js +97 -0
  135. package/dist/mcp/tools/read/reviewActivityTools.js +179 -0
  136. package/dist/mcp/tools/read/serverStatusTools.js +100 -0
  137. package/dist/mcp/tools/read/transactionActivityOutput.js +371 -0
  138. package/dist/mcp/tools/read/transactionActivityTools.js +858 -0
  139. package/dist/mcp/tools/read/walletReadTools.js +734 -0
  140. package/dist/mcp/tools/session/executionResultTools.js +44 -0
  141. package/dist/mcp/tools/session/index.js +8 -0
  142. package/dist/mcp/tools/session/shared.js +36 -0
  143. package/dist/mcp/tools/session/statusTools.js +69 -0
  144. package/dist/mcp/tools/session/walletConnectionTools.js +69 -0
  145. package/dist/mcp/tools/settings/index.js +66 -0
  146. package/dist/mcp-app/account.html +3133 -0
  147. package/dist/mcp-app/account.notices.txt +973 -0
  148. package/dist/mcp-app/chart.html +3354 -0
  149. package/dist/mcp-app/chart.notices.txt +1194 -0
  150. package/dist/mcp-app/connect.html +3179 -0
  151. package/dist/mcp-app/connect.notices.txt +1012 -0
  152. package/dist/mcp-app/receipt.html +8430 -0
  153. package/dist/mcp-app/receipt.notices.txt +3549 -0
  154. package/dist/mcp-app/review.html +8430 -0
  155. package/dist/mcp-app/review.notices.txt +3549 -0
  156. package/dist/mcp-ui/contracts.js +31 -0
  157. package/dist/mcp-ui/readCards.js +28 -0
  158. package/dist/mcp-ui/tools.js +134 -0
  159. package/dist/review-app/brand-dark.svg +1 -0
  160. package/dist/review-app/brand-light.svg +1 -0
  161. package/dist/review-app/favicon.svg +1 -0
  162. package/dist/review-app/settings.css +1 -0
  163. package/dist/review-app/settings.js +1 -0
  164. package/dist/review-app/ui.css +809 -0
  165. package/dist/review-server/assets.js +48 -0
  166. package/dist/review-server/html.js +45 -0
  167. package/dist/review-server/http.js +47 -0
  168. package/dist/review-server/middleware/hostOrigin.js +48 -0
  169. package/dist/review-server/middleware/reviewToken.js +7 -0
  170. package/dist/review-server/reviewServerPolicy.js +1 -0
  171. package/dist/review-server/server.js +72 -0
  172. package/dist/review-server/settingsApi.js +158 -0
  173. package/dist/runtime/application.js +203 -0
  174. package/dist/runtime/config.js +97 -0
  175. package/dist/runtime/localSettingsService.js +198 -0
  176. package/dist/runtime/logger.js +66 -0
  177. package/dist/runtime/reviewDependencies.js +58 -0
  178. package/dist/runtime/reviewServerAcquire.js +93 -0
  179. package/dist/runtime/runtimeTermination.js +60 -0
  180. package/dist/runtime/shared/authenticatedFetch.js +127 -0
  181. package/dist/runtime/shared/control.js +93 -0
  182. package/dist/runtime/shared/dataAccess.js +66 -0
  183. package/dist/runtime/shared/mcpHttp.js +84 -0
  184. package/dist/runtime/shared/ownerLease.js +50 -0
  185. package/dist/runtime/shared/server.js +98 -0
  186. package/dist/runtime/shared/stdio.js +113 -0
  187. package/dist/runtime/smokeMainnetRead.js +391 -0
  188. package/dist/runtime/smokeMainnetReadAssertions.js +306 -0
  189. package/dist/runtime/smokeReview.js +40 -0
  190. package/dist/runtime/start.js +90 -0
  191. package/dist/runtime/suiEndpoint.js +97 -0
  192. package/dist/runtime/suiTransactionGraphqlMapping.js +200 -0
  193. package/dist/runtime/suiTransactionGraphqlQueries.js +231 -0
  194. package/dist/runtime/suiTransactionGraphqlSource.js +148 -0
  195. package/dist/runtime/walletConnectConfig.js +3 -0
  196. package/dist/runtime/walletConnectStorage.js +99 -0
  197. package/dist/runtime/walletConnectTransport.js +128 -0
  198. package/dist/runtime/walletSdkChild.js +3 -0
  199. package/dist/runtime/walletSdkChildRuntime.js +160 -0
  200. package/dist/runtime/walletSdkIpc.js +26 -0
  201. package/dist/runtime/walletSdkProcess.js +358 -0
  202. package/docs/AGENT_BEHAVIOR.md +524 -0
  203. package/docs/AGENT_DEVELOPMENT_POLICY.md +815 -0
  204. package/docs/FRONTEND_POLICY.md +534 -0
  205. package/docs/LOCAL_DB_ARCHITECTURE.md +381 -0
  206. package/docs/MCP_SETUP.md +742 -0
  207. package/docs/MCP_TOOLS.md +1318 -0
  208. package/docs/SDK_API.md +206 -0
  209. package/docs/SIGNABLE_ADAPTER_CONTRACT.md +396 -0
  210. package/docs/TRANSACTION_ACTIVITY_LOG.md +194 -0
  211. package/docs/UTILITY_INDEX.md +275 -0
  212. package/docs/WALLET_CONNECTION.md +238 -0
  213. package/docs/golden-scenarios/BEHAVIOR_MATRIX.md +166 -0
  214. package/docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md +161 -0
  215. package/docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md +259 -0
  216. package/package.json +79 -0
  217. package/protocols/deepbook-margin.md +15 -0
  218. package/protocols/deepbook-v3.md +24 -0
@@ -0,0 +1,1318 @@
1
+ # MCP Tools
2
+
3
+ Sui MCP tools are grouped by authority.
4
+
5
+ This document is the MCP API reference. It owns tool contracts, response fields, statuses, follow-up fields, and output boundaries.
6
+
7
+ It does not own installation steps or user-question playbooks. Installation and client setup live in `docs/MCP_SETUP.md`. User-question flows and response wording live in `docs/AGENT_BEHAVIOR.md`.
8
+
9
+ Tool names use dot prefixes and avoid arbitrary shell, arbitrary Move calls, and private-key handling.
10
+
11
+ ## Read-Only Tools
12
+
13
+ | Tool | Status | Purpose |
14
+ | --- | --- | --- |
15
+ | `read.get_server_status` | Implemented | Returns package, version, evidence policy, network, runtime, `implementedToolsCount`, resources, prompts, and tool implementation status. |
16
+ | `read.list_supported_protocols` | Implemented | Lists current mainnet protocol surfaces and support levels. |
17
+ | `read.list_deepbook_pools` | Implemented | Lists DeepBook mainnet pools from pinned `@mysten/deepbook-v3` constants. |
18
+ | `read.list_deepbook_tokens` | Implemented | Lists DeepBook mainnet tokens from pinned `@mysten/deepbook-v3` constants. |
19
+ | `read.inspect_deepbook_orderbook` | Implemented | Uses pinned DeepBook SDK read methods over Sui gRPC simulation reads with an internal sender placeholder; `ticks` is capped at 50. |
20
+ | `read.get_deepbook_mid_price` | Implemented | Returns a DeepBook pool mid price snapshot from pinned SDK simulation reads. |
21
+ | `read.get_deepbook_usdc_price_history` | Implemented | Returns DeepBookV3 official Indexer USDC candle evidence for a requested official interval. |
22
+ | `read.get_deepbook_usdc_price_at_time` | Implemented | Returns the DeepBookV3 official Indexer USDC candle for or nearest to one target UTC time. |
23
+ | `read.quote_deepbook_action` | Implemented | Quotes raw integer DeepBook quantities through pinned SDK transaction builders and raw `u64` simulation return values with an internal sender placeholder. |
24
+ | `read.quote_deepbook_display_amount` | Implemented | Converts an explicit display source amount through pinned DeepBook token units, then returns scoped display quote facts plus raw quote evidence. |
25
+ | `read.summarize_deepbook_account_inventory` | Implemented | Summarizes active-account DeepBook BalanceManager inventory through pinned SDK simulation reads. |
26
+ | `read.summarize_wallet_assets` | Implemented | Reads coin balances for an explicit address or the active account through Sui gRPC `client.core.listBalances`; accepts `cursor` for pagination. |
27
+ | `read.classify_wallet_assets` | Implemented | Classifies coin balances for an explicit address or the active account by balanceStatus and coin-balance roles; accepts `cursor` for pagination. |
28
+ | `read.list_settlement_asset_groups` | Implemented | Lists supported settlement asset groups derived from pinned mainnet SDK registries. |
29
+ | `read.summarize_settlement_asset_group_parity` | Implemented | Summarizes direct DeepBook mid-price parity across a supported settlement asset group against a declared measurement reference. |
30
+ | `read.preview_intent_evidence` | Implemented | Builds current wallet and DeepBook evidence for a natural-language settlement intent; not transaction building or signing. |
31
+ | `read.list_review_activity` | Implemented | Lists local Sui MCP review evidence for one account. |
32
+ | `read.summarize_review_funnel` | Implemented | Summarizes local review lifecycle counts, status distribution, and review timing. |
33
+ | `read.get_review_session_detail` | Implemented | Returns stored local evidence for one Sui MCP review session. |
34
+ | `read.inspect_sui_transaction` | Implemented | Looks up one Sui transaction digest and stores normalized facts only when the transaction sender or a returned balance-change owner matches a known local wallet. |
35
+ | `read.scan_sui_account_activity` | Implemented | Runs a bounded GraphQL activity scan for a known or explicit Sui account. |
36
+ | `read.summarize_sui_activity_scan` | Implemented | Runs a bounded Sui activity scan and returns requested-account facts plus deterministic normalized-fact analysis without full details. |
37
+ | `read.scan_sui_function_activity` | Implemented | Runs a bounded GraphQL scan for transactions the account sent that called one full `package::module::function`. |
38
+ | `read.summarize_sui_function_activity_scan` | Implemented | Runs the sent-function activity scan and returns requested-account facts plus deterministic normalized-fact analysis without full details. |
39
+ | `read.summarize_sui_account_activity` | Implemented | Summarizes stored normalized Sui activity facts from local SQLite. |
40
+ | `read.get_account_asset_timeline` | Implemented | Builds stored local account asset net-flow bars from normalized activity facts and optional DeepBook USDC token-denominated candle references. Not held balances or complete wallet history. |
41
+
42
+ Read-only tools split by address requirement.
43
+
44
+ Address-free reads do not need wallet connection. Examples include DeepBook pool lists, orderbook snapshots, mid price, and quote facts.
45
+
46
+ Current asset reads need either an explicit public Sui address supplied by the user or a selected account with a usable current wallet connection. Stored activity and transaction-result reads retain their own read-context rules.
47
+
48
+ An explicit public-address read does not prove ownership, create active account context, or authorize active-account-only tools.
49
+
50
+ Live read results include `fetchedAt` as an ISO 8601 UTC string. `fetchedAt` is a timestamp, not a freshness verdict.
51
+
52
+ ## API Response Guidance
53
+
54
+ High-risk read, review, wallet connection, and execution-status responses include `userAnswerUse` when the response needs answer guidance.
55
+
56
+ USD-denominated settlement-asset responses also include `toolAvailability`.
57
+ This object repeats the current package version, evidence policy version, network, implemented tool count, and required tool availability for that response.
58
+ If `toolAvailability.requiredToolsAvailable` is `false`, do not answer the user's USD-denominated question from that response.
59
+
60
+ Use these fields before relying on prose in this document:
61
+
62
+ - `userAnswerUse.canAnswer`: question categories this one response can support.
63
+ - `userAnswerUse.cannotAnswer`: conclusions this one response does not support.
64
+ - `userAnswerUse.answerFields`: fields to use in the user-facing answer.
65
+ - `userAnswerUse.preconditionFields`: fields to check before using answer fields.
66
+ - `userAnswerUse.conclusionRuleFields`: fields that limit what the final conclusion may claim.
67
+ - `userAnswerUse.diagnosticOnlyFields`: fields for source, troubleshooting, pagination, or limitation context.
68
+ - `userAnswerUse.followUp.tool`: exact next tool when the current response is not enough.
69
+ - `userAnswerUse.followUp.inputFields`: current-response fields to pass into the follow-up tool, when the response provides them.
70
+ - `userAnswerUse.followUp.answerFields`: fields to use in the follow-up response.
71
+ - `toolAvailability.requiredTools`: tools the current response depends on for this answer class.
72
+ - `toolAvailability.requiredToolsAvailable`: whether the current server build exposes those required tools.
73
+
74
+ `quantitySemantics`, raw evidence, source fields, and protocol facts remain in the response. `userAnswerUse` does not replace them; it tells the client which returned fields belong in the answer.
75
+
76
+ DeepBook raw quote inputs use raw integer quantities as expected by the pinned SDK.
77
+
78
+ DeepBook display quote inputs are source-side display amounts. They are converted to raw integers only through pinned DeepBook token units.
79
+
80
+ DeepBook read outputs include `source.simulation: "client.core.simulateTransaction"` because the pinned SDK uses transaction simulation for these read queries.
81
+
82
+ DeepBook pool and token lists are static pinned SDK registries.
83
+
84
+ They are not live liquidity, live token discovery, or a complete list of Sui tokens.
85
+
86
+ Token list entries are keyed by SDK symbol and include the pool keys that reference that token in `mainnetPools`.
87
+
88
+ Token entries include `decimals` derived only from pinned `mainnetCoins.scalar` when every scalar is a power of ten. If that invariant fails, the token registry tool fails closed instead of guessing.
89
+
90
+ `read.get_deepbook_mid_price` returns `priceDirection: "quote_per_base"`, so a `SUI_USDC` result is USDC per SUI.
91
+
92
+ The price is the pinned SDK `midPrice` result with `source.precision: "deepbook_v3_to_fixed_9_js_number"`.
93
+
94
+ The response includes `priceSemantics` and `userAnswerUse.cannotAnswer` for unsupported conclusions. It is a DeepBook pool snapshot, not a global market price, fiat USD cash-out estimate, external market-price conversion, USDC/USD peg assumption, quote-vs-mid slippage calculation, effective quote price, price-impact calculation, venue comparison, best-route claim, route recommendation, transaction-building input, signing data, signing readiness, P&L, or cost basis.
95
+
96
+ If the SDK returns a non-positive or non-finite mid price, both `read.get_deepbook_mid_price` and `read.inspect_deepbook_orderbook` fail closed with `quote_unavailable`.
97
+
98
+ `read.get_deepbook_usdc_price_history` returns DeepBookV3 official Indexer USDC candle evidence for a requested official interval.
99
+
100
+ Inputs require `start` and `end` as canonical ISO 8601 UTC timestamps and exactly one selector: `poolName`, `assetSymbol`, or `coinType`. Optional `interval` accepts only official Indexer interval values and defaults to `15m`.
101
+
102
+ The requested range is capped at `requested.range.maxBars: 1008` candle slots for the selected interval. Larger requests return `status: "unsupported_range"` with `reason: "requested_range_exceeds_max_bars"`.
103
+
104
+ Supported successful responses return:
105
+
106
+ - `status: "ok"`;
107
+ - `pair` with the official pool name, pool id, base asset, canonical USDC quote asset, and `priceConvention: "USDC_PER_BASE"`;
108
+ - `requested.range.interval`, `requested.range.intervalDurationMs`, and `requested.range.requestedCandleSlots`;
109
+ - `bars`, where each returned candle has `timestampMs`, `start`, `end`, `open`, `high`, `low`, `close`, and `volume`;
110
+ - `candleAvailability`, which can be `available` or `no_candles_in_range`;
111
+ - `source.poolList` and `source.candles`;
112
+ - `quantitySemantics`, `responseSummary`, and `unsupportedClaims`.
113
+
114
+ Candles are returned by the DeepBookV3 official Indexer for the requested interval. The tool does not synthesize candles, interpolate, carry forward a previous candle, call the browser, use a local price database, or fall back to an on-demand chain-history scan.
115
+
116
+ `status: "unsupported_pair"` means the selector did not resolve to exactly one official USDC-quoted pool. `status: "source_unavailable"` means the official pool list or candle response was unavailable or failed validation.
117
+
118
+ `quantitySemantics.kind: "deepbook_official_indexer_candles"` and `quantitySemantics.allowedUse: "official_deepbook_usdc_candle_history"` mean this output is candle evidence only.
119
+
120
+ `source.kind: "deepbook_v3_official_indexer"` and `source.chainRecomputedBySuiMcp: false` mean Sui MCP read official Indexer candles and did not independently recompute candle values from chain history for this response.
121
+
122
+ USDC in this tool is the token-denominated quote asset for the returned official DeepBookV3 Indexer candles. It is not fiat USD and not a USDC/USD peg guarantee.
123
+
124
+ This output is not a live quote, execution price, historical mid price, global market price, fiat USD cash-out estimate, external market-price conversion, USDC/USD peg assumption, route recommendation, best route, transaction-building input, signing data, signing readiness, P&L, tax evidence, cost basis, user-account transaction history, or user-account balance history.
125
+
126
+ `read.get_deepbook_usdc_price_at_time` uses the same official Indexer candle source and selector rules, but accepts one `targetTime` instead of a range. Optional `interval` defaults to `15m`. Optional `maxDistanceMinutes` limits how far from the target time the tool may select a candle.
127
+
128
+ Successful at-time responses return:
129
+
130
+ - `status: "ok"`;
131
+ - `target`, including `targetTime` and the UTC search window;
132
+ - `match.kind`, which can be `exact_bucket`, `nearest_before`, or `nearest_after`;
133
+ - `match.distanceMinutes`;
134
+ - `match.representativePrice`, whose `field` is `matchedCandle.close`;
135
+ - `matchedCandle`, an official Indexer candle;
136
+ - the same `pair`, `candleAvailability`, `source`, `quantitySemantics`, `responseSummary`, and `unsupportedClaims` boundaries as the range-history tool.
137
+
138
+ `status: "no_price_in_search_window"` means no official Indexer candle was available inside the bounded search window. The tool does not synthesize a price, interpolate, carry forward a previous candle outside the search window, or perform an on-demand chain-history scan.
139
+
140
+ Internal read cards are opened with `ui.open_account`, `ui.open_receipt`, and `ui.open_chart`. They require a client that provides MCP Apps. A client without that UI receives `ui_unavailable`; ordinary MCP read tools remain available.
141
+
142
+ | Tool | Input and result |
143
+ | --- | --- |
144
+ | `ui.open_account` | Optional explicit Sui address; otherwise use the selected read account only when its wallet connection is currently usable. Missing input returns `input_required` with no card or source query. Shows name, address, coin totals, Display NFTs, other-object count, fetched time and enumeration limits; no address form. |
145
+ | `ui.open_receipt` | A transaction digest is required for a query. Omission returns `input_required` with no card or source query. The result view shows execution outcome, balance changes, net gas, sender, digest and fetched time; no hash form. No wallet or active account is needed. Normalized receipt evidence and private display metadata remain available under their existing boundaries. |
146
+ | `ui.open_chart` | Optional `poolName`, official Indexer interval, UTC `startTimeMs`/`endTimeMs`, and candle `limit`. Shows one selected USDC pool as candlesticks and volume. Range shortcuts fill these query fields. The initial time axis uses the saved request boundaries, with price-free whitespace at boundaries without candles; omitted boundaries use the returned data. |
147
+
148
+ A missing Account/Receipt target returns `data: { kind, status: "input_required", field, message }`, with no permission, card ID, saved resource or query. A host-rendered view shows the message without input controls or polling. Other errors remain errors.
149
+
150
+ A successful card-creating response contains a `cardId`, `kind`, `state`, `revision`, timestamps, original `input`, and available `data`. `inputRemainingMs` is computed by the backend; `pollAfterMs` controls sequential observation of a running read. Card `ready` permits a read selection, not signing or payment readiness. An initial supplied input uses the same admission path as a form submission. DB states are `ready`, `running`, and `closed`, with terminal reasons `completed`, `expired`, `failed`, or `server_restarted`.
151
+
152
+ When Chart pool choices cannot be prepared, the backend creates a `closed`/`failed` card with a readable error. No selection is admitted and no candles are requested. Reading that card again returns the stored failure; retrying the source requires an explicit request for a new card. A database access or write failure is a tool error, not a successfully stored failure card.
153
+
154
+ `ui.read_card` and `ui.submit_card` are app-only operations. Permission travels in UI metadata and is absent from model content and public saved resources. Input submission carries card ID, permission, expected revision and typed input. There is no first-view ownership or open/close operation. Recreated frames and chat returns read the same DB record. Identical duplicate input returns the stored request; conflicting input returns `card_conflict` and the authenticated current snapshot in error details. Invalid input returns `invalid_card_input` without consuming a valid selection. Invalid permission exposes neither current state nor private display data.
155
+
156
+ Receipt model results retain input kinds/indices/object references and identify input values and PTB as UI-only details. Receipt and completed Review show the executed transaction graph above their result summary when bound private metadata is available. Technical records are in one Details slide. Missing metadata leaves the saved result available without inventing a graph. The typed `sui-mcp/receipt-display` metadata binds display data to the same card ID, transaction digest and revision. It carries individual on-chain Pure input values and the graph derived from those inputs; never a serialized transaction, signature or wallet credential. Public saved resources contain only the model projection. A missing UI detail payload means unavailable display data, not that a transaction had no inputs.
157
+
158
+ Backend expiry ends unsubmitted input. A server restart invalidates unfinished cards; stored completed results remain readable. Reset/import removes cards and their permissions with the data change. Completed input does not reopen, while still-valid unsubmitted input is unaffected by chat navigation. A lost submit response is resolved by reading the same card, without another source request.
159
+
160
+ When a Host replays a historical card without its private input permission, the
161
+ View reads `suimcp://cards/{cardId}` to restore the same card's current saved
162
+ facts. The creating snapshot alone is not current state. This path creates no
163
+ permission and offers no input, wallet or transaction actions. It does not
164
+ recover private receipt details or pairing data that the Host did not supply.
165
+ Malformed or conflicting metadata and rejected permissions remain errors.
166
+
167
+ Public saved reads use the existing backend evaluation: they can reconcile
168
+ stored wallet sessions and reflect elapsed card, review, connection or request
169
+ deadlines. They do not start a new pairing, preparation, signature, submission,
170
+ source query or chain observation. Read-only restoration does not promise that
171
+ database rows remain unchanged. A read failure can be retried explicitly for
172
+ the same card, without polling or replaying the original business operation.
173
+
174
+ A frame with valid UI permission confirms the current DB state even if its initial snapshot cannot be displayed. A display error does not change the stored state, repeat a submission, or start another source query. Required expiry and running-state observations still follow the backend hints. If a state read fails, automatic observation stops and the user can explicitly read the same saved state. Check status can also retry a failed display after confirming that same card; the completed result remains stored. A failed QR drawing can be retried for the same current connection without creating another pairing. Missing private QR metadata cannot be recovered from the public saved resource. Display recovery does not clear a failed command's explicit retry requirement or a user's pause.
175
+
176
+ Review display labels describe the available information: Ready for your review,
177
+ Review needs updating, and Review blocked. They do not rename API status enums
178
+ or establish current permission to request wallet approval. Read-only restored
179
+ cards may show prepared review details without allowing actions. Check status
180
+ reads the same card, Retry review recomputes permitted review details, and
181
+ Continue review explicitly resumes updates paused in that View. A recorded
182
+ review message describes a saved update failure or connection change, not a
183
+ current instruction or proof that a cancellation succeeded.
184
+
185
+ A failed Request delivery never triggers a repeated signature request. Same-card
186
+ reads still follow the existing expiry hints; a confirmed unadmitted stale review
187
+ may prepare new conditions, which require a new Request click. Failed initial
188
+ preparation can be retried for the displayed current wallet/account after another
189
+ state check. A delayed action response does not clear an intervening read failure:
190
+ the card retains explicit state-read recovery until a current read succeeds.
191
+
192
+ Overlapping successful responses for the same card may arrive out of order.
193
+ A lower revision does not replace displayed facts or create a read error, and
194
+ required observations continue from the retained current state. Equal revisions
195
+ are validated rather than discarded. Actual error responses remain failures.
196
+
197
+ An unconfirmed Cancel review, wallet disconnection, account selection or stop
198
+ request retains its error and pauses new automatic preparation/pairing in that
199
+ View. State reads still report already admitted work. Existing permitted actions
200
+ can be retried explicitly. An unconfirmed Cancel review followed by expired
201
+ material offers Continue review for the existing preparation action; a new
202
+ Request click is still required to request wallet approval. Retry/Continue
203
+ requires a fresh, accepted state read and an unchanged target before one send.
204
+ A completed cancellation cannot be undone through these controls. This local
205
+ pause does not claim that the backend or other frames stopped; new frames use
206
+ the actual saved state.
207
+
208
+ Connect eligibility and its SQLite admission use the same current-owner
209
+ connection set. An unexpired connected wallet, pending approval or pending disconnection
210
+ removes `connect` from `allowedActions` and prevents a second pairing even when
211
+ different cards race with current revisions. The losing card gets the existing
212
+ conflict response and its own snapshot, without another card's private QR or
213
+ permission. Later availability requires an explicit Retry for that failed
214
+ attempt; a saved-state read does not repeat it.
215
+
216
+ Failed attempts whose exact target or command authority has ended are shown as
217
+ earlier attempts, without a command retry or a saved-read button solely for that
218
+ old failure. The current stored result remains authoritative; natural completion
219
+ is not proof that an earlier stop was accepted. This includes failed automatic
220
+ connection/preparation and an unadmitted Request when its card or review expires.
221
+ Card action expiry does not end an already admitted request or result lookup.
222
+ For unadmitted disconnection or account selection, the exact target in
223
+ `connections` can establish that the earlier attempt has ended even while the
224
+ card input remains available. An account returning later does not revive that
225
+ attempt or clear its local automatic pause; the user can make a new selection.
226
+ If an unknown result needs another lookup after the card's action period, request
227
+ `session.open_review_management` with the same `reviewSessionId` and `attemptId`.
228
+ It adds no signing authority and does not repeat the transaction.
229
+
230
+ A confirmation that joins an older in-flight read retains its obligation. After
231
+ that read succeeds, one serial current read performs the needed confirmation;
232
+ an actual read failure instead requires explicit recovery. A valid current read
233
+ also clears an identified card's earlier opening-projection error. Neither path
234
+ repairs malformed permissions or changes the card's target.
235
+
236
+ Review displays one current wallet candidate without a dropdown. Its current authenticated View executes the backend-projected `automaticAction` to prepare or renew stale verified conditions. Multiple valid connections block preparation and signing until the user resolves them with targeted Disconnect actions. A failed computation requires explicit retry. `review_evidence_stale` distinguishes invalidated verified material from a failed quote/computation. Only Request wallet approval authorizes a signature request for the displayed revision. Result cards show the correct PTB, actual chain facts and one Details slide; Review keeps earlier estimates in its Reviewed conditions section.
237
+
238
+ Cards provide no clipboard actions or copy buttons. Their text remains readable and selectable. Chart values remain USDC-denominated source candles, not fiat USD, peg guarantees, route advice, portfolio valuation or P&L. Cards do not fetch chain/Indexer endpoints directly or poll completed results.
239
+
240
+
241
+ `read.quote_deepbook_action` and `read.quote_deepbook_display_amount` use the pinned DeepBook transaction builder quote functions.
242
+
243
+ Input kinds:
244
+
245
+ - `read.quote_deepbook_action`: `quantitySemantics.inputAmountKind: "raw_u64"`.
246
+ - `read.quote_deepbook_display_amount`: `inputAmountKind: "display_source_amount_converted_to_raw_u64"`.
247
+
248
+ Quote responses include `quantitySemantics` before the public quote values. The same response also includes `userAnswerUse.cannotAnswer` for unsupported conclusions such as payment coverage, shortfall contribution, route-dependent payment support, fiat USD cash-out, external market conversion or lookup, USDC/USD peg assumptions, P&L, cost basis, price impact, mid-price slippage, venue comparison, and route recommendation.
249
+
250
+ `canUseForPaymentAnswer: false`, `canUseForShortfallAnswer: false`, `doNotCombineWithPaymentAnswer: true`, and `paymentAnswerUseBlockedReason` mean quote output is a price estimate only. Do not add it to the payment amount, coverage status, or shortfall amount in a user answer.
251
+
252
+ `requiredPaymentAnswerTool: "read.preview_intent_evidence"` and `requiredPaymentAnswerField: "responseSummary"` identify the tool and field to use for payment amount and shortfall answers.
253
+
254
+ The same response-local rule is also exposed as `userAnswerUse.followUp.tool: "read.preview_intent_evidence"` and `userAnswerUse.followUp.answerFields: ["responseSummary"]`.
255
+
256
+ Raw quote source:
257
+
258
+ - `rawQuote.sourceMoveFunction` is `pool::get_quote_quantity_out` for `base_to_quote`.
259
+ - `rawQuote.sourceMoveFunction` is `pool::get_base_quantity_out` for `quote_to_base`.
260
+ - Both entrypoints delegate to `rawQuote.returnValueSourceMoveFunction: "pool::get_quantity_out"`.
261
+ - The official Move source defines return values in this order: `base_quantity_out`, `quote_quantity_out`, `deep_quantity_required`.
262
+
263
+ Returned raw fields are quote evidence only. They are not final min-out values, effective prices, price-impact calculations, venue comparisons, best-route claims, transaction-building inputs, signing data, or signing readiness.
264
+
265
+ `read.quote_deepbook_display_amount` accepts `amountDisplay` as the source coin input amount for the requested `direction`.
266
+
267
+ It does not accept output target amounts or inverse quote requests.
268
+
269
+ The tool:
270
+
271
+ - resolves the input coin from the pinned DeepBook pool;
272
+ - derives decimals from pinned `mainnetCoins.scalar` through the shared scalar invariant;
273
+ - converts to a positive raw input amount that fits the SDK `u64` quote input;
274
+ - reuses the raw DeepBook quote path.
275
+
276
+ The exact converted input is returned as `inputAmount.raw`.
277
+
278
+ The public `quote` contains exact decimal display strings for `baseOut`, `quoteOut`, and `deepRequired`. They are derived from raw `u64` return values through pinned DeepBook scalars.
279
+
280
+ Returned `quantitySemantics.kind: "deepbook_quote_display_amount"` means those display fields are presentation quote facts only.
281
+
282
+ They are not raw output amounts, min-out values, liquidity verdicts, route recommendations, venue comparisons, best-route claims, effective prices, price-impact calculations, mid-price slippage calculations, funding sources, fiat USD cash-out estimates, external market-price conversions, external market lookups, USDC/USD peg assumptions, P&L, cost basis, transaction-building inputs, signing data, or signing readiness.
283
+
284
+ This quote is not a settlement asset choice.
285
+
286
+ ### DeepBook account inventory
287
+
288
+ `read.summarize_deepbook_account_inventory` uses the selected account only when its current wallet connection is usable, to discover DeepBook BalanceManager addresses. It has no explicit public-address input. Without a usable default, a missing selection returns `active_account_not_set`, and a stored but ineligible selection returns `input_invalid`; both carry `details.reason: "connected_account_required"` and `details.followUp` naming `session.get_interaction_status` and its connection/availability/pending/default-account fields. These responses do not request an address. Unavailable wallet operations return `wallet_unavailable` with the existing safe reason and recovery message.
289
+
290
+ With both `poolKey` and `managerAddress`, it checks pool account existence and returns display-like account inventory:
291
+
292
+ - selected account ledger balances;
293
+ - locked balances;
294
+ - capped open order IDs.
295
+
296
+ Detailed inventory fields are answer evidence only when the same response has `detailStatus: "available"` and `userAnswerUse.canAnswer` includes `deepbook_pool_account_inventory_when_pool_and_manager_are_supplied`.
297
+
298
+ When `detailStatus` is `manager_discovery_only`, `pool_key_required`, `manager_address_required`, `manager_address_not_discovered_for_active_account`, or `account_not_found`, use `detailStatus`, `managerAddresses`, `requested`, and `accountExists` when present. Those responses do not provide detailed inventory values such as `accountSummary`, `lockedBalances`, `openOrderIds`, or `openOrderCount`.
299
+
300
+ `accountSummary.*Balances` are BalanceManager ledger and rebate balances. `lockedBalances` are balances tied to open orders in the pool.
301
+
302
+ The response includes `openOrderCount` and `openOrderIdsTruncated` because returned `openOrderIds` are capped.
303
+
304
+ The tool uses `managerAddress` as the public input and registers it as an ephemeral pinned-SDK BalanceManager key internally.
305
+
306
+ Returned `quantitySemantics.kind: "deepbook_display_number"` means these `number` fields are presentation inventory facts only.
307
+
308
+ They are not raw balances, route liquidity, funding sources, withdrawal readiness, transaction-building inputs, signing data, or signing readiness.
309
+
310
+ `read.summarize_wallet_assets` accepts an optional `account` input for public-address coin balance snapshots.
311
+
312
+ When `account` is omitted, it uses the same connection-qualified default as `session.get_interaction_status.assetReadAccount`. No stored selection returns `active_account_not_set` with `details.action: "provide_account"`; a stored but ineligible selection returns `input_invalid` with `details.reason: "address_required"`. Both request an explicit address. SDK unavailability is not reported as absence of a stored account.
313
+
314
+ An explicit `account` read does not prove ownership, store the address as a known wallet, or create active account context.
315
+
316
+ The response includes `quantitySemantics.kind: "sui_wallet_balance_snapshot"`.
317
+
318
+ It marks transaction history, transaction receipt proof, transaction balance deltas, acquisition source, object provenance, fiat cash-out, P&L, and cost basis as not available.
319
+
320
+ Current balances can confirm only a current coin-balance snapshot. They cannot prove that a specific digest delivered that amount or that a still-held coin came from a specific transaction.
321
+
322
+ Raw balance fields remain the pinned Sui SDK integer strings from `client.core.listBalances`.
323
+
324
+ Each balance also includes `unit`; when verified decimals are available it includes `display.amount` as presentation-only decimal text.
325
+
326
+ Display conversion uses `client.core.getCoinMetadata` and a 24 hour local metadata cache keyed by normalized coin type plus verified mainnet chain identifier.
327
+
328
+ If local metadata cache read or write fails, wallet unit reads fail with `metadata_cache_unavailable` instead of guessing or treating the unit as unavailable.
329
+
330
+ If Sui metadata is unavailable, DeepBook-registered tokens can use pinned scalar fallback.
331
+
332
+ If no verified decimals exist, `unit.status` is `unavailable` and clients must not infer decimals from the token symbol.
333
+
334
+ `read.classify_wallet_assets` reuses the same explicit-address or active-account balance, unit, display, metadata cache behavior, and wallet snapshot quantity semantics as `read.summarize_wallet_assets`.
335
+
336
+ It wraps each coin balance in `classification.assetClass: "coin_balance"`, `classification.balanceStatus`, and role labels such as `gas_candidate` or `deepbook_registered`.
337
+
338
+ It also returns `uninspectedAssetClasses` for staked or locked assets, DeepBook BalanceManager or open orders, LP or vault positions, and NFT or object assets.
339
+
340
+ These entries are explicit classifier-uninspected boundaries. They are not zero-balance claims and not spendable asset facts.
341
+
342
+ DeepBook account inventory is separate from coin-balance classification.
343
+
344
+ Inventory reporting for native staked SUI, locked or vesting assets, NFTs, generic objects, LP positions, or vault positions would not by itself make those assets funding sources.
345
+
346
+ It also would not make them route liquidity, payment readiness, portfolio completeness, transaction-building inputs, signing data, or signing readiness.
347
+
348
+ The classifier does not create funding plans, choose routes, create review sessions, return transaction bytes, or produce signing material.
349
+
350
+ `read.list_settlement_asset_groups` returns the supported natural-language settlement asset groups.
351
+
352
+ In this release, `SUI_USD_SETTLEMENT_ASSETS` maps aliases such as dollar, dollars, USD, USD-like, stablecoin, stablecoins, and Korean dollar-word wording.
353
+
354
+ The included USD-denominated assets must exist in the pinned `@mysten/deepbook-v3` mainnet token registry and be referenced by pinned DeepBook pools.
355
+
356
+ The asset group output includes included assets, excluded assets, source authority, and limitations.
357
+
358
+ This is static SDK registry evidence, not live liquidity, fiat USD support, payment execution, route recommendation, or signing readiness.
359
+
360
+ `read.summarize_settlement_asset_group_parity` returns internal parity evidence for a supported settlement asset group.
361
+
362
+ In this release it measures USD-denominated group assets against a declared reference asset. The default reference is USDC, but only as `measurement_reference_not_settlement_choice`.
363
+
364
+ The response includes:
365
+
366
+ - each inspected group asset;
367
+ - direct DeepBook pool evidence when available;
368
+ - `priceInReferenceAsset` as reference asset per group asset;
369
+ - `responseSummary` with minimum, maximum, mean, and median;
370
+ - `referenceAssetRole: "measurement_reference_not_settlement_choice"`.
371
+
372
+ Use `responseSummary` for questions about internal USD-denominated parity, highest/lowest stablecoin-like asset, or max/min/mean parity evidence.
373
+
374
+ This tool is not settlement-token choice, fiat USD cash-out, external market lookup, USDC/USD peg assumption, payment readiness, best route, route recommendation, transaction building, signing readiness, P&L, or cost basis.
375
+
376
+ `read.preview_intent_evidence` accepts natural-language settlement evidence intents.
377
+
378
+ Use it this way:
379
+
380
+ - Coverage question: `intentKind: "cover_payment_like_amount"`, `denomination: "dollar"`, and `requiredDisplayAmount: "1000"`.
381
+ - AssetGroup-total question: `intentKind: "summarize_settlement_asset_group_balance"` and `denomination: "dollar"` without a target amount.
382
+ - Account scope: explicit public `account` or a selected account with a usable current wallet connection.
383
+
384
+ For settlement-asset-only coverage, shortfall, and balance-total answers, use `responseSummary`.
385
+
386
+ The response also exposes `userAnswerUse.answerFields` with the response-specific answer path.
387
+
388
+ `responseSummary.answerCompleteness.answerCompleteFor` names the answer class. `responseSummary.answerCompleteness.requiredAnswerFields` names the fields required for that class. Do not call quote tools for the same question when `responseSummary.doNotCallQuoteToolsForThisQuestion` is `true`. If `toolAvailability.requiredToolsAvailable` is also `true`, answer from `responseSummary` and do not call `read.classify_wallet_assets`, `read.summarize_wallet_assets`, or quote tools to look for other source tokens for that same coverage, balance-total, or shortfall question. If quote tools were already called, do not use quote output for the payment amount, coverage status, or shortfall.
389
+
390
+ `responseSummary` exposes:
391
+
392
+ - `questionKind`;
393
+ - `conclusionKind`;
394
+ - `answerCompleteness`;
395
+ - `doNotCallQuoteToolsForThisQuestion`;
396
+ - `coverageBasis: "settlement_asset_wallet_balance_only"`;
397
+ - `assetGroupId`;
398
+ - current, required, and shortfall display amounts;
399
+ - `amountsUsedForAnswer`;
400
+ - `separateQuoteOutputs`;
401
+ - `requiredUserChoices`;
402
+ - `doNotUseForConclusion`;
403
+ - `excludedFromConclusion`.
404
+
405
+ For payment coverage and shortfall conclusions, use only fields named by `responseSummary.amountsUsedForAnswer`. Treat fields named by `responseSummary.doNotUseForConclusion` or `responseSummary.excludedFromConclusion`, including separate quote results and assets outside the settlement asset group, as non-conclusion context.
406
+
407
+ Selected-target evidence is available only when `targetAssetSymbol` is paired with one of these sources:
408
+
409
+ - `targetAssetSelectionSource: "user_explicit"`;
410
+ - `targetAssetSelectionSource: "prior_user_explicit_context"`.
411
+
412
+ `targetAssetSymbol` without `targetAssetSelectionSource` is invalid.
413
+
414
+ Clients must not set a selection source for an agent-inferred target.
415
+
416
+ When the response returns `responseEvidence.mode: "selected_target_context"`, answer from the fields listed in `userAnswerUse.answerFields`, including `responseSummary`, `selectedTarget`, `candidateConversions`, and `requiredUserChoices`. Do not treat `responseSummary` alone as the complete selected-target answer.
417
+
418
+ Direct pool quote evidence for a selected target is supported only when the same response returns `responseEvidence.supportedResponseClaims` with `direct_pool_quote_evidence` and `userAnswerUse.canAnswer` with `direct_pool_quote_evidence_for_user_selected_target`. If those entries are absent, use the selected-target shortfall and required-user-choice fields only; do not claim quote evidence is available from that response.
419
+
420
+ `acceptedSourceAssetSymbols` can include only assets inside the same supported settlement asset group. Separate quote tool results for SUI, WAL, RWA, or other non-group assets do not count as payment coverage or shortfall evidence.
421
+
422
+ This tool does not silently choose USDC, USDT, or any settlement token for the user. It uses selected-target evidence only when the response has explicit selection provenance. It does not rank venues, choose routes, evaluate gas reserve, create review sessions, return transaction bytes, produce signing material, estimate fiat USD cash-out, or compute P&L.
423
+
424
+ Gas reserve remains outside the current evidence boundary. `gas_reserve_not_evaluated` is an explicit non-evaluation marker, not gas readiness or a policy result.
425
+
426
+ Review activity tools read only local Sui MCP review evidence.
427
+
428
+ They are not complete wallet transaction history, gas history, P&L, or external wallet activity.
429
+
430
+ The optional `account` input is a read filter and does not change the active account context. If `account` is omitted, the tools use the active account context.
431
+
432
+ Successful review activity responses include `dataScope`, `accountSource`, `lowSampleWarning`, and `lowSampleThreshold`.
433
+
434
+ The current `lowSampleThreshold` is 5 local records, from `REVIEW_ACTIVITY_LOW_SAMPLE_THRESHOLD`.
435
+
436
+ When `lowSampleWarning` is true, treat counts as sparse local evidence and avoid drawing behavior patterns.
437
+
438
+ For `read.list_review_activity`, `dataScope.recordCount` is the full matching local review count.
439
+
440
+ The returned `activities` array can be shorter when `truncated.activities: true`.
441
+
442
+ `accountSource` reports how the read scope was selected; it is not proof of wallet ownership.
443
+
444
+ MCP error responses intentionally omit `structuredContent`; clients should read the JSON error payload from `content[0].text`.
445
+
446
+ `read.get_review_session_detail` transition rows include `isNoOp`.
447
+
448
+ A no-op transition is an observed lifecycle call whose stored status did not change, such as a repeated open or reconnect event.
449
+
450
+ `read.get_review_session_detail.userAnswerUse.answerFields` lists `execution` only when the response includes an `execution` object. If `execution` is absent and `userAnswerUse.cannotAnswer` includes `stored_review_execution_result_without_execution_field`, the response cannot answer a stored execution-result question.
451
+
452
+ Funnel summaries count distinct reviews and do not treat repeated no-op rows as additional completed steps.
453
+
454
+ Sui activity tools are user-requested read surfaces, not a background indexer.
455
+
456
+ Summary activity tools omit full transaction details by design. Digest-level detail is exposed by `read.inspect_sui_transaction`.
457
+
458
+ Tool roles:
459
+
460
+ - `read.inspect_sui_transaction` performs a single digest lookup.
461
+ - `read.scan_sui_account_activity` requests up to 100 account transactions for `affected` or `sent` relationship.
462
+ - `read.summarize_sui_activity_scan` reuses the live scan path and adds deterministic `analysis` without returning full `details`.
463
+ - `read.scan_sui_function_activity` and `read.summarize_sui_function_activity_scan` return transactions the selected account sent that called one full `package::module::function`.
464
+ - `read.summarize_sui_account_activity` reads only local SQLite stored facts.
465
+
466
+ This is a bounded provider page, not complete wallet history.
467
+
468
+ Affected activity means the account appeared in returned transaction effects; it does not mean the account sent the transaction.
469
+
470
+ Live account scans use the pinned GraphQL `last`/`before` connection direction for recent-to-older pagination. Returned rows are ordered newest-first by returned checkpoint and timestamp facts.
471
+
472
+ Live scan and live-summary responses return `requestedAccountTransactionFacts`. This flattened requested-account row array pairs each digest with account-scoped fields and `requestedAccountEffect`. The response also returns `transactionDetailAvailability`, which counts returned `transactions` rows with and without source details. It includes `transactions[].transactionContext` in `userAnswerUse.answerFields` only when `transactionDetailAvailability.allReturnedTransactionsHaveDetails: true`.
473
+
474
+ When `transactionContext` is present, it omits transaction-wide balance-change aggregates.
475
+
476
+ Function activity boundaries:
477
+
478
+ - The filter uses only the verified `function + sentAddress` GraphQL combination.
479
+ - The `function` input must be exactly `package::module::function`.
480
+ - Package-only, `package::module`, generic, and type-argument suffix forms are unsupported.
481
+ - Function scans do not include recipient-only activity, affected-address-only activity, affected-object-only activity, global function history, or complete dApp history.
482
+ - Empty function activity results mean no matching rows were returned in the bounded page; they do not prove no matching activity exists.
483
+ - The internal `accepted_empty` classifier result is not user-facing tool output.
484
+
485
+ Stored summary boundaries:
486
+
487
+ - Stored summaries aggregate local account-level facts from digest lookups, account scans, or sent-function scans.
488
+ - Scan kind is internal provenance.
489
+ - Stored summary input does not accept `kind`, `function`, or function-history filters.
490
+ - Legacy `summary` is the backward-compatible shallow count block.
491
+ - `analysis.overview.transactionCount` mirrors the stored count.
492
+ - `analysis.overview.analyzedTransactionCount` reports how many returned rows fed the richer aggregations.
493
+ - `transactionDetailAvailability` counts returned stored rows with `details`. `userAnswerUse.answerFields` includes `transactions[].compact` and `transactions[].details` only when `transactionDetailAvailability.allReturnedTransactionsHaveDetails: true`.
494
+
495
+ Coverage and pagination boundaries:
496
+
497
+ - `orderingVerified: false` means the provider page was not monotonic by returned checkpoint or timestamp facts.
498
+ - Treat unverified ordering as unproven coverage.
499
+ - Checkpoint bounds are inclusive user bounds translated to the pinned GraphQL API's exclusive checkpoint filters.
500
+ - Timestamp bounds are page filters and coverage signals, not GraphQL provider filters.
501
+ - Continue with `continuationCursor` until `windowComplete` proves coverage or the provider cannot continue.
502
+ - Provider retention and rate-limit behavior are endpoint/operator properties, not Sui MCP guarantees.
503
+ - Empty pages, bounded pages, and stored local summaries are not complete wallet or dApp history.
504
+
505
+ Local persistence boundaries:
506
+
507
+ - The default account is the active account.
508
+ - An explicit account is allowed as a read filter.
509
+ - The local DB stores only normalized facts for transactions tied to a known account by returned sender or balance-change owner facts.
510
+ - Function activity scans store only sender-matching rows for known accounts.
511
+ - Provider-returned account scan rows that cannot prove the local relation can appear in the current response but are counted as skipped for storage.
512
+ - Function activity scans drop any provider row whose sender does not match the requested account before it reaches the tool `transactions` response.
513
+ - When a known-account scan is stored, dropped function rows are counted as skipped and are not stored as transaction facts.
514
+
515
+ Detail boundaries:
516
+
517
+ - Inspect responses can include live provider detail fields for the current response, including account addresses returned by GraphQL.
518
+ - Live scan, live-summary, function-scan, and function-summary rows expose `transactionContext` for transaction-level calls, objects, events, gas, errors, truncation, and protocol labels only when source details are present.
519
+ - Inspect and stored-summary rows can include `compact` when details are available.
520
+ - `userAnswerUse.answerFields` omits `transactionContext`, `compact`, `details`, and requested-account effect fields that are absent from the current response.
521
+ - For array paths such as `transactions[].transactionContext`, `transactions[].compact`, and `transactions[].details`, `userAnswerUse.answerFields` lists the path only when every returned `transactions` row has that field. If only some rows have details, use `transactionDetailAvailability` and inspect the specific rows or follow-up digest lookup instead.
522
+ - Compact balance changes can aggregate repeated ownerless raw changes with `count`.
523
+ - Compact balance changes are transaction-level facts, not requested-wallet balance evidence.
524
+ - `analysis.coinFlows` is a transaction/page aggregate, not wallet-specific evidence.
525
+
526
+ For wallet/account-specific balance answers, use requested-account fields:
527
+
528
+ - `requestedAccountTransactionFacts`;
529
+ - `requestedAccount.coinFlows`;
530
+ - `transactions[].requestedAccountEffect`.
531
+
532
+ These fields are raw integer facts scoped to the requested account.
533
+
534
+ Row-level `requestedAccountEffect.scope` is `requested_account`.
535
+
536
+ These requested-account fields summarize the requested account's evidence for that transaction:
537
+
538
+ - `requestedAccountEffect.role`;
539
+ - `requestedAccountEffect.balanceChangeEvidence`;
540
+ - `requestedAccountEffect.balanceChangeCompleteness`;
541
+ - `requestedAccountEffect.balanceChanges`;
542
+ - `requestedAccountEffect.accountBalanceChangeInferencePolicy`;
543
+ - `requestedAccountEffect.coinFlows`;
544
+ - `requestedAccountEffect.limitations`.
545
+
546
+ `requestedAccountEffect.limitations` is part of the requested-account evidence boundary.
547
+
548
+ Incomplete balance evidence means unknown, not zero:
549
+
550
+ - `accountBalanceChangeEvidence: "incomplete_account_balance_changes"` is not zero-balance evidence.
551
+ - `accountBalanceChangeEvidence: "account_balance_changes_unavailable"` is not zero-balance evidence.
552
+ - `accountBalanceChangeInferencePolicy: "do_not_infer_from_transaction_context"` means transaction-level context, compact counts, or visible recipient patterns must not be used to infer the requested account's amount.
553
+ - Only `no_account_balance_changes_returned` with complete details supports saying no requested-account balance change was returned.
554
+ - `no_account_balance_changes_returned` is complete evidence only when requested-account balance-change evidence is complete.
555
+ - If `requestedAccount.balanceChangeCompleteness` or a row-level `requestedAccountEffect.balanceChangeCompleteness` is `truncated` or `unavailable`, the account-specific balance-change evidence is incomplete.
556
+
557
+ `analysis` aggregates only normalized facts:
558
+
559
+ - raw integer coin flows;
560
+ - gas totals;
561
+ - Move call targets;
562
+ - object and event counts;
563
+ - failure details;
564
+ - protocol counts keyed by `protocolMatches[].protocolId`.
565
+
566
+ `protocolMatches` are derived from package, module, function, event, object, or shared-object evidence already present in normalized details.
567
+
568
+ Package-derived evidence can include `mvrName` and `packageSource` when a verified MVR current package resolution was used.
569
+
570
+ Protocol matches and analysis are not a supported-protocol list, wallet position inventory, P&L, route recommendation, transaction-building input, signing data, or signing readiness.
571
+
572
+ Stored summaries return sanitized normalized details and omit non-known party account addresses.
573
+
574
+ Stored transaction details can include capped Move call targets, raw coin balance changes, object changes, event summaries, gas cost facts, execution error facts, and truncation flags when GraphQL returns them.
575
+
576
+ Balance quantities use signed raw integer strings from returned `*Raw` fields, including:
577
+
578
+ - `details.balanceChanges[].amountRaw`;
579
+ - `requestedAccount.coinFlows[].*Raw`;
580
+ - `requestedAccountTransactionFacts[].accountBalanceChanges[].amountRaw`;
581
+ - `requestedAccountTransactionFacts[].requestedAccountEffect.balanceChanges[].amountRaw`;
582
+ - `transactions[].requestedAccountEffect.balanceChanges[].amountRaw`;
583
+ - `transactions[].requestedAccountEffect.coinFlows[].*Raw`.
584
+
585
+ `requestedAccountTransactionFacts[].requestedAccountEffect.balanceChanges[].amountRaw` is one of the requested-account raw amount fields.
586
+
587
+ There is no `details.balanceChanges[].amount` field.
588
+
589
+ `requestedAccountEffect.balanceChangeEvidence` and `balanceChangeCompleteness` describe the account-scoped rows and their completeness. The corresponding flat fields are `requestedAccountTransactionFacts[].accountBalanceChangeEvidence` and `accountBalanceChangeCompleteness`.
590
+
591
+ Complete details with no rows for the requested account produce `no_account_balance_changes_returned` and `accountBalanceChangeInferencePolicy: "no_account_balance_changes_in_complete_details"`. Complete details with returned rows produce `account_balance_changes_returned`, even if a returned row has `amountRaw: "0"`. Truncated details produce `incomplete_account_balance_changes`; missing details produce `account_balance_changes_unavailable`. Neither supports a conclusion that no account balance change was returned. Use the returned raw amount rows for quantities, not the evidence or completeness labels.
592
+
593
+ Gas raw values use MIST in fields such as:
594
+
595
+ - `details.gas.netGasCostRaw`;
596
+ - `requestedAccountTransactionFacts[].transactionContext.gasNetCostRaw`;
597
+ - `analysis.gas.netGasCostRaw`.
598
+
599
+ When `gasCost` or `analysis.gas.netGasCost` is present, its `display` field is the SUI display conversion using `@mysten/sui MIST_PER_SUI`.
600
+
601
+ Summary rows can include `lastScanIncompleteReason`. When it is present, treat the row as stored evidence from an incomplete or unverified scan before using it as behavioral evidence.
602
+
603
+ Unknown explicit accounts, unrelated digest lookups, rows outside the requested window, rows that fail sender checks, rows that fail local storage-relation checks, and dropped function rows are not stored as transaction facts.
604
+
605
+ The tools do not store raw GraphQL payloads, transaction bytes, signatures, BCS payloads, non-known party account addresses, P&L, route recommendations, or signing material.
606
+
607
+ do not treat `transaction.status: "unknown"` as a not-found signal.
608
+
609
+ Protocol matches are transaction activity labels only.
610
+
611
+ Transaction activity responses include `quantitySemantics`.
612
+
613
+ They also include `userAnswerUse`. For account-specific activity answers, start with `userAnswerUse.answerFields`; it points to requested-account fields before transaction-level context.
614
+
615
+ It marks balance `amountRaw`, `increaseRaw`, `decreaseRaw`, and `netRaw` fields as raw integer facts.
616
+
617
+ It also exposes `displayConversionRequires` and `display_conversion_without_verified_decimals` boundaries for token display conversion.
618
+
619
+ Do not convert raw token amounts into display units unless the response includes verified decimals or a display amount for that asset.
620
+
621
+ Gas is the one built-in exception. `gasCost.display` and `analysis.gas.netGasCost.display`, when present, are returned SUI display facts from the pinned Sui MIST conversion.
622
+
623
+ If only raw token facts are available, answer token amounts in raw units.
624
+
625
+ For function scans, the GraphQL `sentAddress` filter is expected to return only sender-matching rows for the requested account.
626
+
627
+ The local sender check is defensive. A non-conforming provider row is dropped from the tool response before storage selection.
628
+
629
+ For a stored known-account scan, the dropped row contributes only to skipped counts. It is not treated as valid function history.
630
+
631
+ `read.scan_sui_account_activity` and `read.scan_sui_function_activity` return pagination and coverage fields:
632
+
633
+ - `hasMore`;
634
+ - `continuationCursor`;
635
+ - `windowComplete`;
636
+ - `orderingVerified`;
637
+ - optional `incompleteReason`.
638
+
639
+ `windowComplete: null` means the user asked for the latest N results without a lower bound.
640
+
641
+ `windowComplete: true` means the requested lower checkpoint or timestamp was reached, or the provider reported no more matching transactions.
642
+
643
+ `windowComplete: false` means coverage could not be proven.
644
+
645
+ Provider cursors are opaque and best-effort. Cursor rejection returns a safe error and does not create a complete-history claim.
646
+
647
+ Tool source comparison:
648
+
649
+ - `read.scan_sui_account_activity`, `read.scan_sui_function_activity`, `read.summarize_sui_activity_scan`, and `read.summarize_sui_function_activity_scan` return live GraphQL row facts.
650
+ - Those live rows include requested-account fields, transaction context, and `detailLookup` references but no full `details`.
651
+ - The summary tools also return deterministic `analysis`.
652
+ - `read.inspect_sui_transaction` is the full normalized detail path for a specific digest.
653
+ - `read.summarize_sui_account_activity` reads only stored normalized facts from local SQLite.
654
+ - `read.get_account_asset_timeline` reads only stored normalized facts from local SQLite, then can attach DeepBookV3 official Indexer USDC candle references for supported USDC-quoted assets.
655
+
656
+ If stored or summary details are missing or capped, use the digest metadata with `read.inspect_sui_transaction` instead of inferring missing calls, balances, objects, events, gas, or errors.
657
+
658
+ ### Stored Account Asset Timeline
659
+
660
+ `read.get_account_asset_timeline` returns a stored local account asset-flow timeline for one account and UTC range.
661
+
662
+ Inputs:
663
+
664
+ - `account` is optional. If omitted, the tool uses active account context. Supplying an explicit public account does not create active account context or prove ownership.
665
+ - `start` and `end` are ISO 8601 UTC timestamps. The requested range is half-open: `start` is included and `end` is excluded.
666
+ - `interval` is optional and uses the same official Indexer interval values as DeepBook USDC price tools. Omitted `interval` uses `15m`.
667
+
668
+ Output fields:
669
+
670
+ - `coverage` describes whether stored scan rows prove the requested range is complete, partial, or absent.
671
+ - `status: "account_not_known"` means the explicit account is not a known local wallet in the local activity store. In that status the tool does not return `scanNeeded`.
672
+ - `scanNeeded`, when present, names `read.scan_sui_account_activity` as the bounded scan tool that can gather local evidence for a known account.
673
+ - `netFlowBars` are observed account-scoped raw token balance-change bars from stored normalized activity rows.
674
+ - `balanceStatus` is currently `unavailable_no_balance_anchor`, and `balanceBars` is empty. Do not present net-flow bars as held balances.
675
+ - `sourceTransactions` reports how many stored rows were read, returned, truncated, and detail-covered.
676
+ - `quantitySemantics` marks raw integer net-flow fields and unsupported uses.
677
+ - `usdcReferences` can attach DeepBookV3 official Indexer USDC token-denominated candle references for supported USDC-quoted assets. These references are not fiat USD value, not a USDC/USD peg guarantee, not P&L, not cost basis, not route advice, and not signing readiness.
678
+
679
+ This tool does not run scans, start a background indexer, create a price cache, prove complete wallet history, compute held balances, calculate portfolio value, compute P&L, compute tax, compute cost basis, recommend routes, build transactions, return signing data, or provide signing readiness.
680
+
681
+
682
+ ## Action Tools
683
+
684
+ | Tool | Status | Purpose |
685
+ | --- | --- | --- |
686
+ | `action.prepare_sui_action_review` | Signable internal Review card | Creates a local review session and internal Review card for a supported swap action proposal. Account-bound DeepBook reviews may build local unsigned transaction material inside the review server, internally bind a Sui transaction digest to it, and derive object ownership, quote/policy, human-readable review, review-time simulation, and PTB visualization evidence. When every required evidence stage completes, an explicit Review card selection can admit backend-mediated WalletConnect approval for that exact transaction. The MCP tool does not return transaction bytes, signing data, or signing readiness. |
687
+ | `action.prepare_external_proposal_review` | Non-signable review | Creates a local review session and internal Review card from an untrusted structured external proposal. It does not return transaction bytes. |
688
+
689
+ `action.prepare_sui_action_review` is account-bound: a swap review computes
690
+ its evidence (balances, transaction material, digest, simulation) for a
691
+ specific sender, so the tool requires an active wallet account. Connect first
692
+ with `session.create_wallet_connection`; with no active account the tool returns
693
+ `active_account_not_set` with `details.action: "connect_wallet_connection"`
694
+ instead of creating a proposal that can never be computed or signed. The
695
+ Review card reads that account from the server as the single source of truth
696
+ and never connects a wallet itself.
697
+
698
+ `action.prepare_sui_action_review` accepts a protocol-neutral swap `intent`
699
+ (`type: "swap"`, `from.symbol`, `from.amount`, `to.symbol`,
700
+ `maxSlippageBps`, optional `protocol`). The optional `protocol` field carries
701
+ the protocol slug from the adapter registry (the same slug vocabulary as the
702
+ prompt surfaces). With a single registered protocol for the action it may be
703
+ omitted; once several protocols support the same action the tool returns
704
+ `input_invalid` with `reason: "protocol_choice_required"` and
705
+ `availableProtocols`, and the caller must ask the user and retry with
706
+ `intent.protocol` set - the server never picks a venue silently. An unknown
707
+ slug returns `reason: "unknown_protocol"` with the available slugs.
708
+
709
+ `action.prepare_external_proposal_review` accepts `proposal` with `type:
710
+ "payment"` or `type: "sui_action"`.
711
+
712
+ Common required fields are `id`, `source`, `network: "sui:mainnet"`,
713
+ `createdAt`, and `purpose`. `expiresAt`, `assumptions`, and
714
+ `requiredUserChoices` are optional.
715
+
716
+ Payment proposals include `payment.amount`, `payment.recipient`, and optional
717
+ `payment.target`.
718
+
719
+ Sui action proposals include `action.actionKind`, `action.target`, optional
720
+ `action.recipient`, and optional `action.assetFlow` entries.
721
+
722
+ Proposal amount fields use `amountDisplay` and `amountKind:
723
+ "display_proposal"`. `amountDisplay` must be positive decimal display text such
724
+ as `100`, `100.25`, or `0.5`. Signs, commas, exponent notation, unit labels,
725
+ prose, and zero values are rejected. These fields are display proposal facts
726
+ only. They are not raw amounts or minimum outputs. They are not
727
+ transaction-building inputs. They are not signing data or signing readiness.
728
+
729
+ The external proposal schema is strict. Fields outside the contract, including
730
+ executable material such as transaction bytes, serialized transactions, signing
731
+ requests, private-key material, signatures, seeds, mnemonics, or a
732
+ route-selected plan, are rejected rather than stored as review authority.
733
+ Allowed text fields are also length-bounded and rejected when they contain
734
+ executable-material terms, private-key terms, signing-request terms,
735
+ route-selected-plan terms, recognized Sui private-key strings, valid English
736
+ BIP39 mnemonic phrases, long encoded payloads, or raw secret-like hex/base64
737
+ payloads in fields that are not Sui identifier fields.
738
+
739
+ Successful responses return `plans[].reviewModel`.
740
+
741
+ Use these `reviewModel` fields for the proposal review answer:
742
+
743
+ - `proposedAction`: what the external proposal asks to do;
744
+ - `assetFlow`: outgoing, expected incoming, and fee display proposal facts;
745
+ - `recipients` and `targets`: recipient or action target facts supplied by the
746
+ proposal;
747
+ - `evidenceUsed`: local schema and proposal facts used for the review;
748
+ - `missingEvidence`: wallet, recipient, target, simulation, or adapter evidence
749
+ not verified;
750
+ - `requiredUserChoices`: choices that remain with the user;
751
+ - `unsupportedClaims`: conclusions the review does not support;
752
+ - `freshness`: timestamp status for the proposal;
753
+ - `blockingChecks`: checks that keep the review blocked or warning-only;
754
+ - `nonSignableReason`: why the review has no sign action.
755
+
756
+ Account-bound review computation for external proposals returns `blocked` with
757
+ `blockedReason: "proposal_review_only"`. This means the local review layer
758
+ recorded the proposal facts but did not build, regenerate, simulate, or verify
759
+ transaction material.
760
+
761
+ Complete supported DeepBook review reaches ready_for_wallet_review. This
762
+ is review evidence, not transaction authority. A scoped user selection admits
763
+ one request; the backend sends the stored bytes through WalletConnect, verifies
764
+ the returned digest and signer, and submits once. It independently reads chain
765
+ effects and records them separately from request status. The Review and Receipt
766
+ cards display those facts; neither the model nor the card receives bytes or
767
+ signatures. Ordinary MCP calls cannot authorize signing or submission.
768
+
769
+ After the wallet account is bound to a supported swap review session, the
770
+ Review card and `session.get_review_status` may show protocol-specific quote
771
+ evidence and review-state checks for:
772
+
773
+ - resolved DeepBook direct pool;
774
+ - raw quote evidence;
775
+ - quote freshness;
776
+ - derived raw min-out policy;
777
+ - protocol fee evidence, including DeepBook DEEP fee evidence;
778
+ - local unsigned transaction material build when that stage completes;
779
+ - an internal Sui transaction digest commitment bound to the stored local material when that stage completes;
780
+ - object ownership evidence derived from stored local material and Sui owner/type reads when that stage completes.
781
+ - human-readable review facts derived from the material-bound quote policy,
782
+ object ownership evidence, and internal digest binding when that stage
783
+ completes.
784
+ - review-time simulation evidence derived from simulating the stored local
785
+ unsigned transaction material with validation checks enabled when that stage
786
+ completes.
787
+
788
+ When those account-bound review stages run, `reviewState.adapterLifecycle` may
789
+ list `stageCatalogId`, `completedStages`, and `missingStages` for the
790
+ adapter-owned DeepBook lifecycle. `stageCatalogId` identifies the
791
+ adapter-owned stage catalog; it is not a core lifecycle enum shared by every
792
+ protocol adapter.
793
+ Completed stages are review progress only. If
794
+ `transaction_material_build_or_verify` is completed, it means the local review
795
+ server built unsigned transaction material and kept the bytes internal. If
796
+ `digest_commitment` is completed, it means the server internally derived a Sui
797
+ transaction digest from that stored material; the digest value and transaction
798
+ bytes are not MCP or review-app outputs. Missing stages explain why the review
799
+ remains blocked. This lifecycle covers review evidence producer stages through
800
+ review-time simulation. Wallet requests, signature verification, submission and
801
+ chain observation are platform responsibilities after review, separate from
802
+ adapter lifecycle stages. Only a user selection and wallet approval admit that
803
+ backend path; ordinary model calls do not authorize it.
804
+ Public producer projections are tied to those stage states:
805
+ `reviewState.humanReadableReview` is valid only after `human_readable_review`
806
+ is completed and not listed as missing, and `reviewState.simulation` is valid
807
+ only after `review_time_simulation` is completed and not listed as missing.
808
+
809
+ When `reviewState.humanReadableReview` is present, it is displayable review
810
+ evidence projected from verified review artifacts. Its `kind`
811
+ currently identifies the first swap review projection. Its `assetFlow` raw
812
+ amounts, coin types, decimals, minimum output, and fee facts come from the
813
+ material-bound quote policy evidence. Its target pool and direction come from
814
+ the same quote source. Its object-ownership evidence reference comes from
815
+ stored transaction material and Sui owner/type reads. Use it to explain the
816
+ current local review facts only. Do not use it as transaction bytes, public transaction digest values, signing data, signing readiness, route quality, wallet handoff, or execution readiness. Any display amount in this field is
817
+ presentation context only and is not a signing or simulation input.
818
+
819
+ When `reviewState.simulation` is present, it is a public summary projected from
820
+ private review-time simulation evidence for the stored local transaction
821
+ material. It may include provider, enabled checks, success, raw Sui gas cost
822
+ summary components, balance changes, and object changes. It
823
+ does not expose transaction bytes or the internal transaction digest. It is not
824
+ wallet handoff, not signing data, not signing readiness, not execution
825
+ readiness, and not proof that a wallet has signed or submitted anything.
826
+
827
+ If the lifecycle runs through review-time simulation and every required
828
+ evidence artifact passes contract assembly, account-bound review returns
829
+ `ready_for_wallet_review` and records the schema-validated contract in
830
+ `reviewState.transactionReviewData`.
831
+ The contract carries the transaction commitment hash only; it is not
832
+ transaction bytes, not signing data, not signing readiness, and not
833
+ execution readiness.
834
+ If contract assembly declines, the review returns `blocked` with
835
+ `blockedReason: "wallet_review_contract_emit_missing"` and a failed
836
+ adapter-prefixed check such as `deepbook_wallet_review_contract_emit_missing`
837
+ naming the concrete reason. In
838
+ the contract-missing blocked state, wallet signature requests and execution
839
+ remain unavailable. In the `ready_for_wallet_review` state,
840
+ `reviewState.adapterLifecycle.missingStages` is empty and the human-readable
841
+ review plus simulation public summaries are present as pre-signing review
842
+ evidence. The backend verifies stored bytes against that digest before requesting
843
+ a wallet signature, then checks returned bytes and signer before submission.
844
+ The card never receives the bytes.
845
+
846
+ For a failed computation whose private material is no longer valid,
847
+ `reviewState.evidenceValidity: "invalidated"` preserves the original
848
+ `blockedReason` or `refreshReason`, checks and adapter stage history, while
849
+ omitting human-readable, simulation, transaction-review, PTB and derived balance
850
+ facts. The stages and checks describe the last computation; they do not establish
851
+ currently available material. A fresh `wallet_review_contract_emit_missing`
852
+ computation still requires human-readable and simulation summaries. Its
853
+ invalidated stored result does not. Failed computations require explicit Retry;
854
+ only previously ready material can become `review_evidence_stale` for automatic
855
+ renewal. An expired approval click never approves the renewed revision.
856
+
857
+ Those checks and lifecycle stages are pre-signing review evidence only. They do
858
+ not expose transaction bytes, signing data, signing readiness, route
859
+ recommendations, funding readiness, or execution readiness. Only a
860
+ `ready_for_wallet_review` state with an emitted wallet review contract lets the
861
+ backend admit a user-selected WalletConnect request; its byte transfer is
862
+ not an MCP response.
863
+
864
+ Do not describe those checks as wallet readiness, signing readiness, route quality, or execution safety. Mention local transaction material only when `transaction_material_build_or_verify` is completed, and state that bytes remain internal. Mention digest commitment only when `digest_commitment` is completed, and state that it is an internal binding to stored material, not a public signing artifact.
865
+
866
+ In the current release, prepared review plans label `assetFlowPreview` entries with `amountKind: "display_intent"`.
867
+
868
+ Nested `assetFlowPreview.amount` strings remain display-intent text and are not raw signable quantities.
869
+
870
+ These amounts are explanation/display context only, including unresolved placeholders such as `amount: "unknown", approx: true`.
871
+
872
+ They are not minimum outputs, simulation results, or transaction-building inputs.
873
+
874
+ DeepBook transaction material build uses the derived raw quote policy in the
875
+ account-bound review layer, not `assetFlowPreview.amount` display strings.
876
+
877
+ Any adapter that returns a signable review contract must keep a separate
878
+ contract before any wallet request. The source-level contract is
879
+ `src/core/action/signableAdapterContract.ts`; the explanatory contract document
880
+ is `docs/SIGNABLE_ADAPTER_CONTRACT.md`.
881
+
882
+ That contract requires input provenance, source-of-truth records, typed evidence
883
+ claims for each safety-critical fact, raw integer amounts with verified
884
+ decimals, gas from review-time simulation, expiry checked at review time,
885
+ slippage or min-out policy when quote evidence is used, object ownership
886
+ evidence, simulation evidence, and the same human-readable review field concepts
887
+ exposed by `plans[].reviewModel`.
888
+
889
+ Payload fields in that contract must reference typed evidence claims.
890
+ The claims must resolve to source-of-truth records through the
891
+ `SAFETY_CRITICAL_FACT_MATRIX`; source id presence alone is not enough.
892
+
893
+ The contract also defines `PtbVisualizationArtifact`. A PTB visualization
894
+ artifact may expose Mermaid `flowchart` text, diagnostics, `generatedAt`,
895
+ `source`, and unsupported-use fields. It must report
896
+ `executableMaterial.included: false`.
897
+
898
+ PTB visualization is explanatory evidence only. It is not transaction-building
899
+ authority or wallet authorization. It is not signing data, not signing
900
+ readiness, not payment execution readiness, not route recommendation, and not a
901
+ replacement for review-time simulation.
902
+
903
+ The graph is decoded from the stored transaction bytes by the pinned
904
+ deterministic renderer with no AI or model input, and only after those bytes
905
+ recompute to the bound commitment; the Mermaid source keeps raw package
906
+ addresses for independent cross-check.
907
+
908
+ The review layer renders the artifact when an account-bound review emits the
909
+ wallet review contract and the pinned renderer succeeds. The artifact is
910
+ returned as `reviewState.ptbVisualization` next to
911
+ `reviewState.transactionReviewData`. A renderer failure adds a warning
912
+ `deepbook_ptb_visualization_unavailable` check instead and does not invalidate
913
+ the emitted contract. PTB visualization is not a transaction builder,
914
+ not wallet handoff, and not a signing data source.
915
+ It is not a signing readiness signal. Review-state checks are pre-signing review evidence; wallet signing happens afterward on the internal Review card under the user's control.
916
+
917
+ ## Session Tools
918
+
919
+ | Tool | Input and result |
920
+ | --- | --- |
921
+ | `session.create_wallet_connection` | Opens an internal card with `intent: connect`, `disconnect` or `manage` (default). A connect-intent View automatically starts pairing after authenticated state confirmation; manage pairs only after the user chooses Connect wallet. A disconnect-intent card opens confirmation for a unique connected target. Disconnection requires target-specific confirmation and does not revoke onchain permissions. |
922
+ | `session.get_wallet_connection` | Reads one `cardId`; public response excludes pairing and permission. |
923
+ | `session.wait_wallet_connection` | Waits on one `cardId`, with an optional timeout up to 55 seconds; stops when user input is needed or the admitted connection/disconnection operation ends. |
924
+ | `session.open_review_management` | Opens management for exact `reviewSessionId` + `attemptId`; no refresh or signing authority. |
925
+ | `session.get_interaction_status` | Stored `activeAccount`, current-owner `connections`, `assetReadAccount`, wallet availability, and bounded pending connection/review lists. `assetReadAccount` is `available` with an account only when that selected address has a usable current connection; otherwise `address_required`. Stored `activeAccount` does not prove a live connection. `address_required` reports that no implicit default is available; it does not add an address input to connected-account-only tools. When wallet availability is unavailable, connection rows are last recorded facts, not proof of presence or absence. |
926
+ | `session.get_review_status` | Current preparation status, review revision, optional current request and chain execution. |
927
+ | `session.get_execution_result` | Observes the current explicitly referenced attempt and may read its known digest; never submits again. |
928
+ | `session.wait_execution_result` | Bounded wait on the same request, separate from its signing and chain-observation deadlines. |
929
+
930
+ `pendingWalletConnections.items[].status` is `input_required`,
931
+ `awaiting_approval`, or `disconnect_pending`. The last value describes an
932
+ admitted, running disconnect card, not a new wallet connection state. In card
933
+ workflow data, a connection's optional `pendingAction: "disconnect"` is derived
934
+ from that stored card operation. Its `status` remains the last confirmed
935
+ connection fact. Such a connection is unavailable for a new account selection,
936
+ review or signature request. `observe` remains true while disconnection can be
937
+ observed, and becomes false on completion or unavailable wallet progress.
938
+ While its SDK callback remains pending, unavailable progress preserves the
939
+ operation and its last recorded connection state. Repeating the same selection
940
+ does not send another SDK request.
941
+
942
+ `session.get_interaction_status` reconciles stored connections against current SDK sessions before reading dependent review/request facts. This can record a connection change and invalidate a review or interrupt an unsubmitted request under the existing rules. It preserves the stored account selection and submitted chain results; it does not start pairing, SDK disconnect, signing or submission.
943
+
944
+ When a disconnect callback ended but its completion write failed, current reads
945
+ reconcile that stored operation without another SDK disconnect. If the SDK is
946
+ unavailable, an unconfirmed failure is distinct from verified disconnection.
947
+ `pendingReviewSessions` includes live Review input or ongoing preparation,
948
+ request or explicit result observation. Cancelled/expired input alone is not a
949
+ pending interaction, even when the stored review is proposed or ready. Closing
950
+ the original input does not remove an admitted request that is still waiting.
951
+ `submitting` permits observation of the admitted digest during the same initial
952
+ window as `awaiting_chain_result`, without waiting for the submission response.
953
+ A stored chain result can therefore precede that response.
954
+
955
+ An unadmitted ready internal Review may include `nextStateReadAfterMs`, a
956
+ server-computed interval for checking material expiry, wallet-service startup,
957
+ or earlier request work for the same account. A positive
958
+ value schedules a same-card state read; an absent or zero value schedules no
959
+ additional wake-up. It is separate from `actionRemainingMs` (card authority),
960
+ the signing wait and the chain observation window. Only the backend changes
961
+ the stored review to `refresh_required`; the hint never authorizes a request,
962
+ extends validity or refreshes a quote. Admitted requests and their management
963
+ views do not use it to expire historical review facts.
964
+
965
+ Current card and session responses describe one backend evaluation of stored
966
+ facts. Their action choices and remaining times do not authorize a later
967
+ command: admission rechecks the selected account, revision, material and expiry
968
+ against current stored data. If review data changes during verification and
969
+ requires a new verification, the read returns `invalid_session_transition` with
970
+ `details.reason: "review_changed_during_verification"` and a safe message.
971
+ Read the same state again; do not resend a financial action. This conflict is
972
+ neither a completed result nor a wait timeout. A command already committed
973
+ before its response fails remains recorded and is recovered by reading it.
974
+
975
+ Wallet startup and restoration are asynchronous dependencies of the parent
976
+ service. Connect/manage cards remain available during initialization or failure
977
+ so the user can inspect state. They do not provide service-restart input. Ordinary evidence
978
+ and saved-result reads do not await the SDK. The package supplies its project
979
+ identifier; these failures do not ask the user for a project ID. SDK error bodies
980
+ and private configuration values are not returned.
981
+
982
+ Review status is preparation state (`proposed`, `awaiting_wallet`,
983
+ `wallet_connected`, `ready_for_wallet_review`, `blocked`, `refresh_required`,
984
+ `expired`). `requestStatus`, when present, is `awaiting_signature`, `submitting`,
985
+ `awaiting_chain_result`, `stopped`, `request_failed`, `outcome_unknown`, or
986
+ `completed`. `pollingStatus` uses the current request when there is one and
987
+ otherwise the preparation state. The `user_action_required` category and
988
+ `pollingHint.userActionRequiredStatuses` identify states where the model-facing
989
+ wait returns; they do not require a manual preparation click. A permitted live
990
+ card can prepare automatically, while an ambiguous selection or failed update
991
+ can require user input. Preparation is not an already pending wallet signature.
992
+
993
+ A review's bound account is fixed; changing the active read account does not
994
+ rebind it. Preparation choices and final admission use the same account rule.
995
+ To update a review bound to A, select A again in a new Connect card. To review
996
+ for B, request a new Review. An absent or incompatible read account removes the
997
+ preparation choice without recording a preparation failure. The existing
998
+ `review.error` card text distinguishes `Current account selection` guidance from
999
+ a quoted saved review message. It does not decide permissions. Changing
1000
+ read context alone does not revoke an already valid A review's signing choice.
1001
+ Once a signing request consumes its card, retrying needs a new Review; a
1002
+ management card only refers to its existing exact attempt.
1003
+
1004
+ Only `completed` has `executionResult`, with `attemptId`, review/plan IDs,
1005
+ `status: success | failure`, the exact digest, verified `chainReceipt` and time.
1006
+ Only failed chain effects have `failureReason: chain_execution_failed`. Wallet
1007
+ rejection, local timeout, unavailable receipts and lost submission responses
1008
+ never fabricate a chain failure. An unknown result retains the digest for later
1009
+ reads. An explicit user stop after submission stops observation, not an on-chain
1010
+ transaction. Wallet connection changes or a requested disconnect stop pending
1011
+ submission permission with their own recorded reason; they do not claim that the
1012
+ user stopped waiting or that disconnection already succeeded. After submission,
1013
+ those connection events preserve independent observation of the same digest,
1014
+ including the first lookup after the submit response. They neither stop that
1015
+ observation nor resume observation the user explicitly stopped.
1016
+
1017
+ The original request's stored deadlines are unchanged by a management card.
1018
+ A new signature requires a newly reviewed revision and explicit selection.
1019
+ Identical duplicate selections return the admitted attempt; no response-loss
1020
+ path replays a financial request. Model tools may open/read cards; only scoped
1021
+ app-only `ui.act_card` performs a user selection. UI permission and pairing QR
1022
+ travel in private metadata. Bytes/signatures never reach the card or model.
1023
+
1024
+ Connection observation uses 5 seconds and request observation 3 seconds.
1025
+ Session responses and workflow card data expose `walletAvailability` separately
1026
+ from stored review, request and chain facts:
1027
+
1028
+ - `available`: the SDK and required database publication completed;
1029
+ - `initializing`: `process_start`, `sdk_start`, `session_restore` or `state_sync`,
1030
+ with a neutral message; a failed state write remains in `state_sync` for recovery;
1031
+ - `recovering`: a fenced SDK run is being replaced by the internal supervisor;
1032
+ no current card or model action requests this transition;
1033
+ - `unavailable`: a safe `reason` and `message`.
1034
+
1035
+ The existing unavailable reasons are `initialization_failed`,
1036
+ `restoration_failed`, and `wallet_state_unavailable`. Every configured service
1037
+ has a `walletRunId`; an absent backend workflow has no run ID. Initialization or
1038
+ recovery does not mean that a wallet rejected a connection or transaction.
1039
+ Availability is a dependency fact, not account ownership or signing readiness.
1040
+ `walletObservation`, when present, carries `runId`, `sequence`, and `observedAt`
1041
+ for the last confirmed local SDK observation. Ordinary reads do not perform a
1042
+ fresh SDK check or prove that the wallet app is online. Implicit asset reads
1043
+ require an available service and a usable observation in that same run.
1044
+
1045
+ Wallet-dependent app inputs (`connect`, `disconnect`, `use_account`,
1046
+ `prepare_review`, `request_signature`) carry the displayed `walletRunId`. A stale
1047
+ run cannot be transferred to a replacement SDK. Backend commands verify the
1048
+ session, account, chain, method and stored authority at their decision boundary.
1049
+ `acceptedWalletRunId` identifies a card's stored wallet input, when present; it
1050
+ is not new permission.
1051
+
1052
+ Connect workflow data includes optional `connectionAction: "connect" | "disconnect"`
1053
+ only when that action was admitted on the card. The connection's current status
1054
+ is separate from the card's original operation. In particular, failed disconnect
1055
+ means remote removal was not confirmed, including after local service recovery.
1056
+
1057
+ `connectionConflict`, when present, is
1058
+ `{ reason: "multiple_connections", connectionIds: [...] }`. It contains distinct
1059
+ IDs for the multiple live, known connections that prevent selecting a usable
1060
+ wallet. It appears in Connect/Review `data`, the connection wait's `card.data`,
1061
+ interaction status and relevant review-status responses. Its shared schema and
1062
+ backend evaluation own the meaning; the View does not count rows to grant authority.
1063
+ `walletAvailability: available` only confirms the SDK dependency, not the absence
1064
+ of this conflict. `connections` describes recorded targets, not signing choices.
1065
+ In conflict, `assetReadAccount` is `address_required`; explicit-address reads and
1066
+ saved transaction results retain their independent access rules.
1067
+
1068
+ A valid Connect card can still offer exact-target `disconnect` during conflict.
1069
+ `connect`, `use_account`, `prepare_review` and `request_signature` remain blocked.
1070
+ Each disconnection uses the same scoped UI permission, current run and revision,
1071
+ atomic admission and saved result as an ordinary single-connection disconnect.
1072
+ No first/newest/default wallet is silently selected. When one valid connection
1073
+ remains and no connection operation is pending, normal account use can resume;
1074
+ with none, pairing is available. A failed disconnect does not prove remote removal.
1075
+ A failed or stopped product connection is not restored merely because its SDK
1076
+ session remains saved.
1077
+
1078
+ `connectionConflict` is optional. Its absence alone is not proof of a usable
1079
+ connection or permission, especially in a historical result that does not need
1080
+ current wallet eligibility. Filling optional context never adds global cleanup
1081
+ writes or SDK requests to independent saved-result reads. `allowedActions`
1082
+ identifies permitted action types; it is not a list of visible buttons or model
1083
+ authority. Only the exact current target, UI permission and final admission
1084
+ checks allow a user action.
1085
+
1086
+ Current Connect/Review `data` also publishes `usableConnectionId` and
1087
+ `assetReadAccount`. The first identifies the single connection eligible for
1088
+ account use at the backend's evaluation time; it is absent during conflict,
1089
+ pending connection work, unavailable service, or when no unexpired connection
1090
+ qualifies. It does not authorize a signature. `assetReadAccount` uses the same
1091
+ `available`/`address_required` shape as interaction status. Availability requires
1092
+ the stored default's source connection ID to match this connection and its
1093
+ address to remain approved. Matching the address in a different connection is
1094
+ insufficient. A source-less stored selection requires explicit Use address.
1095
+
1096
+ These fields are emitted together for current wallet eligibility. Independent
1097
+ historical or completed-result reads may omit them; omission does not establish
1098
+ current eligibility. Recorded `connections` and `activeAccount` remain facts,
1099
+ including expired records and a stored default that cannot currently be used.
1100
+ Views consume the published selection instead of counting recorded rows or
1101
+ using their own clock. An expired record may remain a disconnection target;
1102
+ expiry alone does not confirm remote removal. Final admission checks current
1103
+ backend facts again. Changing a read default never changes an existing review's
1104
+ account or grants new authority to an admitted transaction.
1105
+
1106
+ Views additionally know whether their own confirmation read or command response
1107
+ is pending. They show neutral communication guidance without synthesizing DB
1108
+ state, unlocking input, starting timers, or resending wallet commands. Uncertain
1109
+ signature delivery retains the exact-request check instead of new approval.
1110
+
1111
+ Stored request reads use the exact management/admitted attempt or the ID-only
1112
+ session's current attempt. Unrelated callback cleanup, request deadlines and
1113
+ connection expiry do not block recorded results. Current wallet eligibility and
1114
+ new chain observation retain their required writes. Target session/card expiry
1115
+ errors still fail the read without deleting the stored execution result.
1116
+
1117
+ Connect does not accept `restart_wallet_service`; that input returns
1118
+ `invalid_card_input` without consuming the card or changing the SDK run.
1119
+ There is no model-facing or Settings replacement command. Operational app
1120
+ restart is described in [MCP Setup](MCP_SETUP.md#wallet-connection-boundary).
1121
+
1122
+ A historical `runtimeRecovery` result retains its prior/next run IDs,
1123
+ admission/update times and `available`, `failed`, `superseded`, or
1124
+ `server_restarted` outcome. It does not grant another input. Parent restart
1125
+ terminates unfinished recovery records without replay. `waitOutcome:
1126
+ status_reached` means observation ended, not that remote disconnection or chain
1127
+ execution succeeded.
1128
+
1129
+ A live Connect or internal Review view may use the existing five-second
1130
+ `nextStateReadAfterMs` hint to refresh service availability without creating a
1131
+ business operation. `review.accountRequestPending: true` means an earlier
1132
+ request for the preparation account still has unfinished work. Preparation and
1133
+ signing remain unavailable; the existing request-observation interval checks
1134
+ when that work finishes. Service readiness alone cannot clear that guard or
1135
+ reset the Review input deadline.
1136
+
1137
+ Target-specific `progress.status` is `idle`, `waiting`, or `unavailable`. The last
1138
+ includes `reason: "wallet_unavailable"` and a safe message. A wait returns
1139
+ `unavailable` when a nonterminal wallet operation cannot be observed; it retains
1140
+ the saved facts. Completed requests return `status_reached` immediately, even
1141
+ when the wallet dependency is unavailable. Already submitted requests can still
1142
+ be observed by their exact digest independently of WalletConnect. Availability fields alone do not change request states or activity counts.
1143
+ Actual service loss separately records failure of unsubmitted approval requests;
1144
+ already dispatched transactions retain their digest and chain observation.
1145
+ Backend restart revokes submission authority and reconciles in-flight requests
1146
+ as uncertain without resending them. Neither event establishes cancellation or
1147
+ chain failure, and verified chain outcomes remain unchanged.
1148
+
1149
+ Wallet-dependent commands rejected for dependency failure use the error kind
1150
+ `wallet_unavailable`, with a safe reason and message. Invalid input and domain
1151
+ conflicts retain their own meaning. Validated app actions can also return a
1152
+ current snapshot with `error.code: "wallet_unavailable"`; invalid permissions
1153
+ and storage failures do not receive a success snapshot. Review creation can
1154
+ still display non-signable proposal facts and stored request management.
1155
+
1156
+ Wait `timed_out` is only a local wait outcome. Reads may update stored expiry or
1157
+ receipt facts, so these session tools are annotated `readOnlyHint: false`.
1158
+ Their effects do not include signing or submission. The returned `pollingHint`
1159
+ and `statusCategory` distinguish required user action, pending observation and
1160
+ local request closure; closure alone does not prove chain success or failure.
1161
+
1162
+ A request's `reason` distinguishes a directly confirmed transaction-digest
1163
+ mismatch from submission checks that could not be completed. Incomplete SDK,
1164
+ network or storage checks do not prove a wrong signer, wallet rejection or chain
1165
+ failure. Backend-authored domain reasons remain specific; raw SDK/RPC/database
1166
+ errors are not exposed. Already committed signature-verification facts are
1167
+ retained when a later submission-admission check fails.
1168
+
1169
+ ### Stored review activity
1170
+
1171
+ `read.list_review_activity` accepts account/time/limit and independent ANDed
1172
+ `reviewStatus`, `requestStatus`, `executionStatus` filters. One row represents
1173
+ one review session and its explicit current attempt, including optional
1174
+ `currentAttemptId`, `reviewRevision`, `transactionDigest`, request and chain
1175
+ status. `dataScope.recordCount` counts the complete filtered scope before limit.
1176
+
1177
+ `read.summarize_review_funnel` keeps the session denominator. `reviewStatusCounts`
1178
+ is the preparation distribution; `requestStatusCounts` is a list of
1179
+ `{ requestStatus, count }` entries (including zero counts); `executionStatusCounts`
1180
+ has success/failure counts. Status strings are data values, not secret-like JSON
1181
+ field names. Request counts plus `withoutRequest` equal total. Chain counts plus
1182
+ `withoutExecutionResult` equal total. Wallet rejection is not chain failure.
1183
+
1184
+ `opened` counts first authenticated normal Review-card state reads, not frames,
1185
+ model creation or wallet approval. walletConnected/stateComputed and review
1186
+ states reached are distinct-session history. `everAwaitedChainResult` counts
1187
+ sessions that reached that request stage; `expiredWithoutExecutionResult` counts
1188
+ expired reviews with no result in any attempt. Timing fields
1189
+ `avgCreatedToSignatureVerifiedSeconds` and `avgOpenedToSignatureVerifiedSeconds`
1190
+ use each review's first backend-verified signature time, or null when absent.
1191
+ Overlapping history stages must not be summed as a denominator.
1192
+ A request can move directly from `submitting` to `completed` when its receipt is
1193
+ observed before the submission response or after a failed follow-up write. That
1194
+ result counts as completed and as its verified chain outcome, but does not count
1195
+ as `everAwaitedChainResult` unless the session actually reached that stage in an
1196
+ attempt. This metric is neither a submission total nor a mandatory funnel step.
1197
+
1198
+ `read.get_review_session_detail` returns the current `request`, full
1199
+ `requestCount`, capped `requests`, revision-bound state snapshots and transitions
1200
+ with `domain` and optional attemptId. Each request may contain a verified
1201
+ `execution`; absent execution does not imply failure. Current request is returned
1202
+ even if the history list is truncated. Historical attempts remain evidence after
1203
+ live cleanup or public backup import, never authority to manage or sign.
1204
+ Response-local `userAnswerUse` only enables execution answers where execution
1205
+ facts actually exist.
1206
+
1207
+ ## Account Tools
1208
+
1209
+ | Tool | Status | Purpose |
1210
+ | --- | --- | --- |
1211
+ | `account.get_active_account` | Implemented | Reads the active wallet-account read context. |
1212
+ | `account.clear_active_account` | Implemented | Clears the active wallet-account read context. |
1213
+
1214
+ ## Settings Tools
1215
+
1216
+ | Tool | Status | Purpose |
1217
+ | --- | --- | --- |
1218
+ | `settings.create_local_settings_session` | Implemented | Creates a same-machine local settings page session. |
1219
+ | `settings.get_local_settings` | Implemented | Reads local Sui MCP settings, including effective Sui gRPC and GraphQL endpoint sources. |
1220
+
1221
+ Settings MCP tools are session-gateway/read tools, not direct mutators.
1222
+
1223
+ The settings page can change local settings after settings-token validation:
1224
+
1225
+ - stored Sui gRPC or GraphQL endpoint;
1226
+ - default endpoint restoration;
1227
+ - active account read context clearing;
1228
+ - logical local data reset;
1229
+ - local data export;
1230
+ - replace-only local data import.
1231
+
1232
+ These actions do not sign, execute, create custody, or produce signing material.
1233
+
1234
+ Endpoint changes apply after MCP server restart.
1235
+
1236
+ Custom providers can affect read data quality, so use trusted mainnet providers.
1237
+
1238
+ ## Resources
1239
+
1240
+ Sui MCP serves the URI prefixes `suimcp://` and `ui://sui-mcp/`.
1241
+ The
1242
+ `sui-mcp/card`, `sui-mcp/receipt-display` and
1243
+ `sui-mcp/wallet-display` metadata keys bind stored cards to their
1244
+ permissions and display facts. Clients must use the returned URI/key values.
1245
+
1246
+
1247
+ | URI | Purpose |
1248
+ | --- | --- |
1249
+ | `suimcp://docs/readme` | Public entry document: product purpose, current release boundary, setup path, and documentation map. |
1250
+ | `suimcp://docs/mcp-setup` | Setup guide: installation, MCP client connection, first-use flow, settings, and troubleshooting. |
1251
+ | `suimcp://docs/mcp-tools` | API reference: tool contracts, response fields, statuses, follow-up fields, and output boundaries. |
1252
+ | `suimcp://docs/wallet-connection` | Wallet connection reference: active read context, private SDK ownership and user-approved transaction requests. |
1253
+ | `suimcp://docs/agent-behavior` | Answer playbook: user-question flows, tool selection, and response wording boundaries. |
1254
+ | `suimcp://protocols/deepbook-v3` | Protocol reference only; use MCP tool responses and `read.list_supported_protocols` for current support. |
1255
+ | `suimcp://protocols/deepbook-margin` | Protocol reference only; no margin MCP read tools or signable actions are exposed in this release. |
1256
+
1257
+ Only allowlisted mainnet protocol references are exposed as MCP resources.
1258
+
1259
+ Protocol resources are not runtime registries, supported-protocol lists, live liquidity sources, route recommendations, or signing-readiness signals. Use `read.get_server_status`, `read.list_supported_protocols`, concrete tool schemas, and concrete tool responses for current product support.
1260
+
1261
+ MCP resources are runtime-facing references that connected AI clients can read.
1262
+
1263
+ They are different from contributor-only documents such as `AGENTS.md`, `docs/AGENT_DEVELOPMENT_POLICY.md`, implementation architecture notes, utility indexes, and ignored local planning notes.
1264
+
1265
+ If an answer behavior must affect AI clients, it belongs in server instructions, an MCP resource, an MCP prompt, schemas, or returned evidence fields, with tests.
1266
+
1267
+ Do not rely on contributor-only documents as the runtime source of agent behavior.
1268
+
1269
+ ## Prompts
1270
+
1271
+ | Prompt | Purpose |
1272
+ | --- | --- |
1273
+ | `inspect-supported-sui-actions` | Guides a user through checking server status and supported mainnet surfaces. |
1274
+ | `prepare-reviewable-sui-action` | Guides a user through the review-session flow without claiming unsupported signing support. |
1275
+ | `swap-deep` | Prepares a reviewable DeepBook swap from a one-line intent argument (any language), e.g. `10 sui to usdc`. |
1276
+ | `swap` | Bare-action prompt, always registered. With one protocol it routes straight there; with several it takes an optional `protocol` argument (completion suggests the slugs) and instructs the model to list the options and ask the user - never to pick a venue silently. |
1277
+
1278
+ Adapter prompt surfaces are declared per adapter in
1279
+ `src/adapters/adapterPromptSurfaces.ts` and validated against
1280
+ `adapterPromptSurfaceSchema`. Names are action-first
1281
+ (`<action>-<protocolSlug>`, e.g. `swap-deep`), so autocomplete groups by what
1282
+ the user wants to do; the bare action prompt stays registered as protocols
1283
+ are added, and once several protocols share an action it asks the user to
1284
+ choose (optional `protocol` argument with completion), so it never silently
1285
+ picks a venue. Each surface takes exactly one
1286
+ free-text `intent` argument so MCP clients can pass the whole request in one
1287
+ line; the model parses the intent, the server never does. Platform boundary
1288
+ language (no signing data or transaction bytes in MCP responses, and user-controlled wallet approval) is
1289
+ appended at registration time and cannot be weakened by an adapter. Prompts
1290
+ are standard MCP `prompts/list` entries, so any MCP client that surfaces
1291
+ prompts (Claude Desktop, Claude Code, and others) exposes them without extra
1292
+ configuration.
1293
+
1294
+ Prompts are explicit runtime-facing workflows. Tool descriptions remain concise, literal, and instruction-free; do not move behavioral policy into tool descriptions.
1295
+
1296
+ ### Funding facts in supported swap reviews
1297
+
1298
+ The human review's `transaction_funding` evidence describes the verified funding
1299
+ form of the stored transaction: actual coin objects, address balances, or a mix.
1300
+ `gas.gasObjects` describes real gas coins only and can be absent for address-balance
1301
+ gas or reservation-only funding. Absence of a gas object does not establish a
1302
+ balance shortfall. Source verification failure is distinct from confirmed
1303
+ insufficient balance. Use the review's checks and stored status for those facts.
1304
+
1305
+ Wallet balance responses retain total, coin-object and address-balance values.
1306
+ They remain balance snapshots, not payment or signing readiness. Receipt gas
1307
+ costs remain independently read chain facts; a reservation identifier is never
1308
+ presented as a real gas payment object.
1309
+
1310
+ Storage rebates can exceed simulated gas costs when coin objects are merged.
1311
+ In that case, the optional unsigned `transactionReviewData.gas.gasUsedRaw` is
1312
+ absent, not zero. The gas budget, simulation cost/rebate components and signed
1313
+ balance changes remain available; the Review card displays the signed net cost.
1314
+
1315
+ A deterministic protocol rejection during SDK build-time simulation is reported
1316
+ as a simulation rejection, not proof of missing account objects or funds. Refresh
1317
+ or a new user-selected constraint does not establish success until the complete
1318
+ review is recomputed. The backend does not relax slippage to make a build pass.