@zktx.io/sui-mcp 0.6.2 → 0.7.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 (42) hide show
  1. package/README.md +13 -12
  2. package/dist/adapters/adapterPromptSurfaces.js +1 -1
  3. package/dist/core/read/deepbookReadHelpers.js +1 -1
  4. package/dist/core/read/readResponseGuidance.js +6 -6
  5. package/dist/core/session/settingsFileProtocol.js +1 -1
  6. package/dist/mcp/prompts.js +10 -4
  7. package/dist/mcp/resources.js +1 -1
  8. package/dist/mcp/server.js +2 -2
  9. package/dist/mcp/serverInfo.js +13 -12
  10. package/dist/mcp/toolNames.js +46 -46
  11. package/dist/mcp/tools/action/prepareSuiActionReview.js +4 -4
  12. package/dist/mcp/tools/read/deepbookReadTools.js +1 -1
  13. package/dist/mcp/tools/read/index.js +2 -2
  14. package/dist/mcp/tools/read/readToolHelpers.js +1 -1
  15. package/dist/mcp/tools/read/serverStatusTools.js +4 -5
  16. package/dist/mcp/tools/read/transactionActivityTools.js +3 -3
  17. package/dist/mcp/tools/session/walletConnectionTools.js +5 -5
  18. package/dist/mcp-app/account.html +1 -1
  19. package/dist/mcp-app/chart.html +1 -1
  20. package/dist/mcp-app/connect.html +1 -1
  21. package/dist/mcp-app/receipt.html +1 -1
  22. package/dist/mcp-app/review.html +1 -1
  23. package/dist/mcp-app/settings.html +1 -1
  24. package/dist/runtime/application.js +2 -2
  25. package/dist/runtime/config.js +3 -6
  26. package/dist/runtime/localSettingsService.js +4 -4
  27. package/dist/runtime/shared/control.js +2 -2
  28. package/dist/runtime/smokeMainnetRead.js +18 -18
  29. package/dist/runtime/smokeReview.js +7 -7
  30. package/dist/runtime/start.js +1 -1
  31. package/docs/AGENT_BEHAVIOR.md +78 -77
  32. package/docs/LOCAL_DB_ARCHITECTURE.md +5 -7
  33. package/docs/MCP_SETUP.md +76 -73
  34. package/docs/MCP_TOOLS.md +103 -102
  35. package/docs/SDK_API.md +8 -5
  36. package/docs/SIGNABLE_ADAPTER_CONTRACT.md +6 -6
  37. package/docs/TRANSACTION_ACTIVITY_LOG.md +7 -7
  38. package/docs/UTILITY_INDEX.md +59 -59
  39. package/docs/WALLET_CONNECTION.md +6 -5
  40. package/package.json +1 -1
  41. package/protocols/deepbook-margin.md +1 -1
  42. package/protocols/deepbook-v3.md +2 -2
@@ -17,7 +17,7 @@ import { verifySuiChainReceipt } from "../core/action/suiChainReceiptVerifier.js
17
17
  import { readPublicChainReceipt } from "../core/action/suiChainReceiptReader.js";
18
18
  import { LocalSessionStore } from "../core/session/sessionStore.js";
19
19
  import { createMcpServer } from "../mcp/server.js";
20
- import { SERVER_NAME, SERVER_NETWORK, SERVER_VERSION } from "../mcp/serverInfo.js";
20
+ import { PRODUCT_DISPLAY_NAME, SERVER_NAME, SERVER_NETWORK, SERVER_VERSION } from "../mcp/serverInfo.js";
21
21
  import { createReviewRequestHandler } from "../review-server/server.js";
22
22
  import { DEFAULT_SUI_GRAPHQL_URL, DEFAULT_SUI_GRPC_URL, composeRuntimeConfig } from "./config.js";
23
23
  import { DeepbookOfficialIndexerSource } from "../core/read/deepbookOfficialIndexerSource.js";
@@ -130,7 +130,7 @@ export async function createRuntimeApplication(bootConfig, logger, ownerId = ran
130
130
  logger.error("WalletConnect initialization unavailable", { stage: "initialization_failed" });
131
131
  }
132
132
  walletRuntime = new WalletSdkProcess({ projectId: WALLETCONNECT_PROJECT_ID, dataDirectory: dirname(bootConfig.activityDatabasePath),
133
- ...(metadata ? { metadata: { name: metadata.name, description: metadata.description, url: metadata.homepage } } : {}) });
133
+ ...(metadata ? { metadata: { name: PRODUCT_DISPLAY_NAME, description: metadata.description, url: metadata.homepage } } : {}) });
134
134
  workflow = new WalletWorkflow({ records: workflowRecords, sessions, ownerId,
135
135
  runtime: walletRuntime, computation: reviewComputationDeps, verifyReceipt: chainReceiptVerifier, readReceipt: publicChainReceiptReader, signatureClient: suiClient,
136
136
  assertCurrent: access.assertCurrent, bindExternalEvent: (work) => access.bind(work), logger,
@@ -2,13 +2,10 @@ import { resolveActivityDatabasePath } from "../core/activity/sqliteActivityStor
2
2
  import { DEFAULT_SUI_GRAPHQL_URL, DEFAULT_SUI_GRPC_URL, SUI_MAINNET_CHAIN_IDENTIFIER, parseGraphqlUrl, parseGrpcUrl } from "./suiEndpoint.js";
3
3
  import { SETTINGS_APPLIES_AFTER_RESTART } from "../core/preferences/preferencesStore.js";
4
4
  export function loadBootConfig(env = process.env) {
5
- const network = env.SUI_NETWORK ?? "mainnet";
5
+ const network = env.SUI_MCP_NETWORK ?? "mainnet";
6
6
  if (network !== "mainnet") {
7
7
  throw new Error("Sui MCP product runtime only supports mainnet");
8
8
  }
9
- if (env.SUI_RPC_URL) {
10
- throw new Error("Sui JSON-RPC endpoint configuration is not supported; use local settings, SUI_GRPC_URL for gRPC, or SUI_GRAPHQL_URL for GraphQL");
11
- }
12
9
  return {
13
10
  network: "mainnet",
14
11
  expectedChainIdentifier: SUI_MAINNET_CHAIN_IDENTIFIER,
@@ -34,8 +31,8 @@ export function composeRuntimeConfig(input) {
34
31
  const defaultSuiGraphqlUrl = parseGraphqlUrl(input.defaultSuiGraphqlUrl ?? DEFAULT_SUI_GRAPHQL_URL);
35
32
  const storedValue = parseGrpcUrl(input.storedSuiGrpcUrl ?? defaultSuiGrpcUrl);
36
33
  const storedGraphqlValue = parseGraphqlUrl(input.storedSuiGraphqlUrl ?? defaultSuiGraphqlUrl);
37
- const envValue = env.SUI_GRPC_URL === undefined ? undefined : parseGrpcUrl(env.SUI_GRPC_URL);
38
- const envGraphqlValue = env.SUI_GRAPHQL_URL === undefined ? undefined : parseGraphqlUrl(env.SUI_GRAPHQL_URL);
34
+ const envValue = env.SUI_MCP_GRPC_URL === undefined ? undefined : parseGrpcUrl(env.SUI_MCP_GRPC_URL);
35
+ const envGraphqlValue = env.SUI_MCP_GRAPHQL_URL === undefined ? undefined : parseGraphqlUrl(env.SUI_MCP_GRAPHQL_URL);
39
36
  const suiGrpcUrl = resolveSuiGrpcUrlView({
40
37
  defaultSuiGrpcUrl,
41
38
  storedValue,
@@ -19,12 +19,12 @@ export class RuntimeLocalSettingsService {
19
19
  this.bootSuiGrpcUrl = normalizeBootSuiGrpcUrlView(options.bootSuiGrpcUrl ??
20
20
  resolveSuiGrpcUrlView({
21
21
  defaultSuiGrpcUrl: this.defaultSuiGrpcUrl,
22
- envValue: this.env.SUI_GRPC_URL
22
+ envValue: this.env.SUI_MCP_GRPC_URL
23
23
  }));
24
24
  this.bootSuiGraphqlUrl = normalizeBootSuiGraphqlUrlView(options.bootSuiGraphqlUrl ??
25
25
  resolveSuiGraphqlUrlView({
26
26
  defaultSuiGraphqlUrl: this.defaultSuiGraphqlUrl,
27
- envValue: this.env.SUI_GRAPHQL_URL
27
+ envValue: this.env.SUI_MCP_GRAPHQL_URL
28
28
  }));
29
29
  this.verifyGrpcEndpoint = options.verifyGrpcEndpoint ?? defaultGrpcEndpointVerifier;
30
30
  this.verifyGraphqlEndpoint = options.verifyGraphqlEndpoint ?? defaultGraphqlEndpointVerifier;
@@ -45,12 +45,12 @@ export class RuntimeLocalSettingsService {
45
45
  const currentStoredView = resolveSuiGrpcUrlView({
46
46
  defaultSuiGrpcUrl: this.defaultSuiGrpcUrl,
47
47
  storedValue: stored,
48
- envValue: this.env.SUI_GRPC_URL
48
+ envValue: this.env.SUI_MCP_GRPC_URL
49
49
  });
50
50
  const currentStoredGraphqlView = resolveSuiGraphqlUrlView({
51
51
  defaultSuiGraphqlUrl: this.defaultSuiGraphqlUrl,
52
52
  storedValue: storedGraphql,
53
- envValue: this.env.SUI_GRAPHQL_URL
53
+ envValue: this.env.SUI_MCP_GRAPHQL_URL
54
54
  });
55
55
  return {
56
56
  suiGrpcUrl: withBootEffectiveEndpoint(currentStoredView, this.bootSuiGrpcUrl),
@@ -3,8 +3,8 @@ import { link, lstat, mkdir, readFile, realpath, unlink, writeFile } from "node:
3
3
  import { basename, dirname, join } from "node:path";
4
4
  import { z } from "zod";
5
5
  import { SERVER_VERSION } from "../../mcp/serverInfo.js";
6
- export const IDENTITY_PATH = "/__runtime/identity";
7
- export const INTERNAL_MCP_PATH = "/__runtime/mcp";
6
+ export const IDENTITY_PATH = "/runtime/identity";
7
+ export const INTERNAL_MCP_PATH = "/runtime/mcp";
8
8
  export const IDENTITY_CHALLENGE_HEADER = "x-sui-mcp-identity-challenge";
9
9
  export const SERVER_INSTANCE_HEADER = "x-sui-mcp-server-instance";
10
10
  export const IDENTITY_TIMEOUT_MS = 1000;
@@ -22,7 +22,7 @@ import { SmokeResponseShapeError, assertSmokeOkStatus, summarizeActivitySmokePay
22
22
  import { SuiEndpointError, verifyMainnetGraphqlEndpoint, verifyMainnetGrpcEndpoint } from "./suiEndpoint.js";
23
23
  import { GraphqlSuiTransactionActivitySource } from "./suiTransactionGraphqlSource.js";
24
24
  const startedAt = new Date();
25
- const smokeFunctionTarget = process.env.SMOKE_FUNCTION_TARGET;
25
+ const smokeFunctionTarget = process.env.SUI_MCP_SMOKE_FUNCTION_TARGET;
26
26
  const plannedTools = [
27
27
  TOOL_NAMES.readSummarizeWalletAssets,
28
28
  TOOL_NAMES.readInspectDeepbookOrderbook,
@@ -65,11 +65,11 @@ class SmokeMainnetError extends Error {
65
65
  async function main() {
66
66
  const logger = createStderrLogger("smoke-mainnet");
67
67
  const bootConfig = loadSmokeBootConfig();
68
- const smokeAddress = parseSuiAddress(requiredEnv("SMOKE_SUI_ADDRESS")) ?? fail("config_error", "SMOKE_SUI_ADDRESS must be a Sui address.");
69
- const poolKey = requiredEnv("SMOKE_DEEPBOOK_POOL_KEY");
70
- const quoteAmount = requiredEnv("SMOKE_QUOTE_AMOUNT");
71
- const inspectDigest = process.env.SMOKE_INSPECT_DIGEST;
72
- const inspectRandomLatest = truthyEnv("SMOKE_INSPECT_RANDOM_LATEST");
68
+ const smokeAddress = parseSuiAddress(requiredEnv("SUI_MCP_SMOKE_ADDRESS")) ?? fail("config_error", "SUI_MCP_SMOKE_ADDRESS must be a Sui address.");
69
+ const poolKey = requiredEnv("SUI_MCP_SMOKE_DEEPBOOK_POOL_KEY");
70
+ const quoteAmount = requiredEnv("SUI_MCP_SMOKE_QUOTE_AMOUNT");
71
+ const inspectDigest = process.env.SUI_MCP_SMOKE_INSPECT_DIGEST;
72
+ const inspectRandomLatest = truthyEnv("SUI_MCP_SMOKE_INSPECT_RANDOM_LATEST");
73
73
  const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
74
74
  const client = new Client({ name: "sui-mcp-smoke", version: "0.0.0" });
75
75
  let smokeDbDir;
@@ -329,18 +329,18 @@ function fail(category, message) {
329
329
  }
330
330
  function smokeEnvPresence() {
331
331
  return {
332
- SUI_GRPC_URL: process.env.SUI_GRPC_URL !== undefined,
333
- SUI_GRAPHQL_URL: process.env.SUI_GRAPHQL_URL !== undefined,
334
- SMOKE_SUI_ADDRESS: process.env.SMOKE_SUI_ADDRESS !== undefined,
335
- SMOKE_DEEPBOOK_POOL_KEY: process.env.SMOKE_DEEPBOOK_POOL_KEY !== undefined,
336
- SMOKE_QUOTE_AMOUNT: process.env.SMOKE_QUOTE_AMOUNT !== undefined,
337
- SMOKE_INSPECT_DIGEST: process.env.SMOKE_INSPECT_DIGEST !== undefined,
338
- SMOKE_INSPECT_RANDOM_LATEST: process.env.SMOKE_INSPECT_RANDOM_LATEST !== undefined,
339
- SMOKE_FUNCTION_TARGET: process.env.SMOKE_FUNCTION_TARGET !== undefined,
340
- SMOKE_SWAP_PROTOCOL: process.env.SMOKE_SWAP_PROTOCOL !== undefined,
341
- SMOKE_SWAP_FROM_SYMBOL: process.env.SMOKE_SWAP_FROM_SYMBOL !== undefined,
342
- SMOKE_SWAP_TO_SYMBOL: process.env.SMOKE_SWAP_TO_SYMBOL !== undefined,
343
- SMOKE_SWAP_AMOUNT_DISPLAY: process.env.SMOKE_SWAP_AMOUNT_DISPLAY !== undefined
332
+ SUI_MCP_GRPC_URL: process.env.SUI_MCP_GRPC_URL !== undefined,
333
+ SUI_MCP_GRAPHQL_URL: process.env.SUI_MCP_GRAPHQL_URL !== undefined,
334
+ SUI_MCP_SMOKE_ADDRESS: process.env.SUI_MCP_SMOKE_ADDRESS !== undefined,
335
+ SUI_MCP_SMOKE_DEEPBOOK_POOL_KEY: process.env.SUI_MCP_SMOKE_DEEPBOOK_POOL_KEY !== undefined,
336
+ SUI_MCP_SMOKE_QUOTE_AMOUNT: process.env.SUI_MCP_SMOKE_QUOTE_AMOUNT !== undefined,
337
+ SUI_MCP_SMOKE_INSPECT_DIGEST: process.env.SUI_MCP_SMOKE_INSPECT_DIGEST !== undefined,
338
+ SUI_MCP_SMOKE_INSPECT_RANDOM_LATEST: process.env.SUI_MCP_SMOKE_INSPECT_RANDOM_LATEST !== undefined,
339
+ SUI_MCP_SMOKE_FUNCTION_TARGET: process.env.SUI_MCP_SMOKE_FUNCTION_TARGET !== undefined,
340
+ SUI_MCP_SMOKE_SWAP_PROTOCOL: process.env.SUI_MCP_SMOKE_SWAP_PROTOCOL !== undefined,
341
+ SUI_MCP_SMOKE_SWAP_FROM_SYMBOL: process.env.SUI_MCP_SMOKE_SWAP_FROM_SYMBOL !== undefined,
342
+ SUI_MCP_SMOKE_SWAP_TO_SYMBOL: process.env.SUI_MCP_SMOKE_SWAP_TO_SYMBOL !== undefined,
343
+ SUI_MCP_SMOKE_SWAP_AMOUNT_DISPLAY: process.env.SUI_MCP_SMOKE_SWAP_AMOUNT_DISPLAY !== undefined
344
344
  };
345
345
  }
346
346
  function tryWriteSmokeResult(record) {
@@ -2,27 +2,27 @@ import { INTENT_PLAN_FACTORIES, resolveIntentPlanFactory, swapIntentInputSchema
2
2
  import { computeReviewStateWithPrivateArtifacts } from "../core/review/reviewComputation.js";
3
3
  export class SmokeReviewConfigError extends Error {
4
4
  }
5
- const requiredSwapInputs = ["SMOKE_SWAP_PROTOCOL", "SMOKE_SWAP_FROM_SYMBOL", "SMOKE_SWAP_TO_SYMBOL", "SMOKE_SWAP_AMOUNT_DISPLAY"];
5
+ const requiredSwapInputs = ["SUI_MCP_SMOKE_SWAP_PROTOCOL", "SUI_MCP_SMOKE_SWAP_FROM_SYMBOL", "SUI_MCP_SMOKE_SWAP_TO_SYMBOL", "SUI_MCP_SMOKE_SWAP_AMOUNT_DISPLAY"];
6
6
  export async function computeSmokeReview(options) {
7
7
  const { env, sessions, computation, account } = options;
8
- const rawSlippage = env.SMOKE_SWAP_MAX_SLIPPAGE_BPS;
8
+ const rawSlippage = env.SUI_MCP_SMOKE_SWAP_MAX_SLIPPAGE_BPS;
9
9
  if (rawSlippage !== undefined && (!Number.isInteger(Number(rawSlippage)) || Number(rawSlippage) < 1)) {
10
- throw new SmokeReviewConfigError("SMOKE_SWAP_MAX_SLIPPAGE_BPS must be a positive integer.");
10
+ throw new SmokeReviewConfigError("SUI_MCP_SMOKE_SWAP_MAX_SLIPPAGE_BPS must be a positive integer.");
11
11
  }
12
12
  const missing = requiredSwapInputs.filter((name) => env[name] === undefined);
13
13
  if (missing.length === requiredSwapInputs.length)
14
14
  return { status: "not_run", notRunReason: "missing_env", requiredEnv: [...requiredSwapInputs] };
15
15
  if (missing.length)
16
16
  throw new SmokeReviewConfigError(`Partial account-bound swap smoke configuration; missing: ${missing.join(", ")}`);
17
- const parsed = swapIntentInputSchema.safeParse({ type: "swap", protocol: env.SMOKE_SWAP_PROTOCOL,
18
- from: { symbol: env.SMOKE_SWAP_FROM_SYMBOL, amount: env.SMOKE_SWAP_AMOUNT_DISPLAY },
19
- to: { symbol: env.SMOKE_SWAP_TO_SYMBOL }, maxSlippageBps: Number(env.SMOKE_SWAP_MAX_SLIPPAGE_BPS ?? "50") });
17
+ const parsed = swapIntentInputSchema.safeParse({ type: "swap", protocol: env.SUI_MCP_SMOKE_SWAP_PROTOCOL,
18
+ from: { symbol: env.SUI_MCP_SMOKE_SWAP_FROM_SYMBOL, amount: env.SUI_MCP_SMOKE_SWAP_AMOUNT_DISPLAY },
19
+ to: { symbol: env.SUI_MCP_SMOKE_SWAP_TO_SYMBOL }, maxSlippageBps: Number(env.SUI_MCP_SMOKE_SWAP_MAX_SLIPPAGE_BPS ?? "50") });
20
20
  if (!parsed.success)
21
21
  throw new SmokeReviewConfigError("The optional swap smoke inputs are invalid.");
22
22
  const { protocol, ...intent } = parsed.data;
23
23
  const resolution = resolveIntentPlanFactory(INTENT_PLAN_FACTORIES, "swap", protocol);
24
24
  if (resolution.status !== "resolved")
25
- throw new SmokeReviewConfigError("SMOKE_SWAP_PROTOCOL must select a supported swap adapter.");
25
+ throw new SmokeReviewConfigError("SUI_MCP_SMOKE_SWAP_PROTOCOL must select a supported swap adapter.");
26
26
  const now = options.now ?? new Date(), plan = resolution.factory.createPlan(intent, now);
27
27
  const created = await sessions.createReviewSession([plan], now);
28
28
  await sessions.recordWalletConnected(created.session.id, account, now);
@@ -40,7 +40,7 @@ async function main() {
40
40
  const controlReady = loadControlIdentity(bootConfig.activityDatabasePath, {
41
41
  network: bootConfig.network, chainIdentifier: bootConfig.expectedChainIdentifier,
42
42
  walletConnectProjectId: WALLETCONNECT_PROJECT_ID,
43
- grpcOverride: process.env.SUI_GRPC_URL ?? null, graphqlOverride: process.env.SUI_GRAPHQL_URL ?? null
43
+ grpcOverride: process.env.SUI_MCP_GRPC_URL ?? null, graphqlOverride: process.env.SUI_MCP_GRAPHQL_URL ?? null
44
44
  });
45
45
  void controlReady.catch(() => { });
46
46
  stage = "stdio_start";
@@ -11,10 +11,10 @@ It is not the contributor rulebook and it is not enforcement. Development rules
11
11
  | Surface | Status | Behavior |
12
12
  | --- | --- | --- |
13
13
  | Sui mainnet state reads | Current | Use read tools for supported balances, DeepBook pools, token registry metadata, mid-price snapshots, orderbook context, raw-quantity quotes, and DeepBook account inventory. |
14
- | DeepBook USDC candle-history reads | Current DeepBookV3 official Indexer candle evidence | `read.get_deepbook_usdc_price_history` reads DeepBookV3 official Indexer USDC candles for the requested official interval. `read.get_deepbook_usdc_price_at_time` selects the candle for or nearest to one target UTC time and identifies `matchedCandle.close` as the representative price. Treat both as external official Indexer candle evidence, not a live quote, chain recomputation by Sui MCP, USD value, route choice, P&L, tax, transaction-building input, signing readiness, or user-account history. |
15
- | Account, Receipt and DeepBook USDC cards | Internal read-only MCP Apps | Use `ui.open_account`, `ui.open_receipt`, or `ui.open_chart` for an interactive read card. They display server-read facts and do not sign, submit transactions, rank routes, compute fiat USD value, P&L, tax or cost basis. |
14
+ | DeepBook USDC candle-history reads | Current DeepBookV3 official Indexer candle evidence | `read_get_deepbook_usdc_price_history` reads DeepBookV3 official Indexer USDC candles for the requested official interval. `read_get_deepbook_usdc_price_at_time` selects the candle for or nearest to one target UTC time and identifies `matchedCandle.close` as the representative price. Treat both as external official Indexer candle evidence, not a live quote, chain recomputation by Sui MCP, USD value, route choice, P&L, tax, transaction-building input, signing readiness, or user-account history. |
15
+ | Account, Receipt and DeepBook USDC cards | Internal read-only MCP Apps | Use `ui_open_account`, `ui_open_receipt`, or `ui_open_chart` for an interactive read card. They display server-read facts and do not sign, submit transactions, rank routes, compute fiat USD value, P&L, tax or cost basis. |
16
16
  | DeepBook swap review sessions | Internal Review card and backend WalletConnect | Account-bound review independently verifies stored material, digest, ownership, policy, human-readable facts, simulation and PTB evidence. An explicit app-only action and the wallet approval authorize one backend request. Ordinary MCP responses are facts, never signing authority or bytes. |
17
- | External proposal review sessions | Non-signable review in the current release | `action.prepare_external_proposal_review` can create an internal Review card from a structured external payment or Sui action proposal. Treat the proposal as untrusted display and review context only. It does not build, verify, simulate, sign, or execute transaction material. |
17
+ | External proposal review sessions | Non-signable review in the current release | `action_create_proposal_review` can create an internal Review card from a structured external payment or Sui action proposal. Treat the proposal as untrusted display and review context only. It does not build, verify, simulate, sign, or execute transaction material. |
18
18
  | Wallet signing | User-approved WalletConnect request | The backend validates returned bytes and signer against the admitted review and submits once. The card and model never receive bytes or signatures. |
19
19
  | PTB visualization | Rendered with emitted wallet review contracts | `reviewState.ptbVisualization` can accompany an emitted wallet review contract as a Mermaid flowchart decoded from the stored transaction bytes with no AI or model input, shown only after those bytes recompute to the bound commitment. Treat it as visualization evidence only, not transaction-building input, wallet authorization, signing data, signing readiness, payment execution readiness, or route recommendation. |
20
20
  | Transaction material and execution | Verified supported swaps under user control | Stored mainnet material is used only after review and wallet approval. External proposals stay non-signable. Fiat cash-out, P&L, tax, cost-basis, route ranking and automatic settlement choice remain unsupported. |
@@ -26,8 +26,8 @@ It is not the contributor rulebook and it is not enforcement. Development rules
26
26
 
27
27
  ## Meta Principles
28
28
 
29
- - AI self-reports do not appear in user-facing checkout output.
30
- - User-facing checkout output should contain server-validated structured facts.
29
+ - AI self-reports do not appear in user-facing review output.
30
+ - User-facing review output should contain server-validated structured facts.
31
31
  - Ambiguous natural language is narrowed through structured evidence first, then clarification only where a user decision is required.
32
32
  - Important UX rules should move into schemas, UI, and tests when the implementation boundary exists.
33
33
 
@@ -47,13 +47,13 @@ When a tool response includes `userAnswerUse`, treat it as the response-local an
47
47
  When a USD-denominated settlement-asset response includes `toolAvailability`, check `toolAvailability.requiredToolsAvailable`.
48
48
  If it is `false`, say the current MCP server build cannot support the answer and do not use amount fields for the user-facing answer.
49
49
 
50
- If the user asks "What is 1 SUI worth?", answer with the current read context available to the tools. Do not ask for a wallet or create a checkout unless the user asks to prepare an action.
50
+ If the user asks "What is 1 SUI worth?", answer with the current read context available to the tools. Do not ask for a wallet or create a Review card unless the user asks to prepare an action.
51
51
 
52
52
  For SUI price questions:
53
53
 
54
- - Call `read.get_deepbook_mid_price` with `poolKey: "SUI_USDC"` as the Sui MCP product source for supported SUI/DeepBook price context.
54
+ - Call `read_get_deepbook_mid_price` with `poolKey: "SUI_USDC"` as the Sui MCP product source for supported SUI/DeepBook price context.
55
55
  - Present the result as "DeepBook SUI/USDC mid price at `fetchedAt`" and do not call it the global market price.
56
- - If the user asks for another stable pair or another token, use `read.list_deepbook_tokens` and `read.list_deepbook_pools` to find the registered pool, then call `read.get_deepbook_mid_price` for that pool.
56
+ - If the user asks for another stable pair or another token, use `read_list_deepbook_tokens` and `read_list_deepbook_pools` to find the registered pool, then call `read_get_deepbook_mid_price` for that pool.
57
57
  - When multiple pools match and the user did not name the quote token, use this split:
58
58
  - For explicit pool-price questions, prefer a USDC-quoted pool, then USDT.
59
59
  - For USD-denominated payment, balance, shortfall, coverage, settlement, or cash-out wording, use the intent-evidence flow instead.
@@ -64,12 +64,12 @@ For SUI price questions:
64
64
 
65
65
  For DeepBook USDC candle-history questions:
66
66
 
67
- - Use `read.get_deepbook_usdc_price_at_time` when the user asks for one supported official USDC-quoted DeepBook pool price at one target time, such as "3 hours ago" after resolving the target to a canonical UTC timestamp.
68
- - Use `read.get_deepbook_usdc_price_history` when the user asks for observed DeepBook USDC historical candles, OHLCV-like bars, or a UTC range for a supported official USDC-quoted DeepBook pool.
69
- - If the user asks to view a chart, use `ui.open_chart`. For account assets or a transaction result card, use `ui.open_account` or `ui.open_receipt`. Use ordinary read tools for ordinary evidence answers. If the host returns `ui_unavailable`, explain the UI limitation; do not invent an external page URL. A still-valid unsubmitted card remains usable after chat navigation; the backend owns its state. An accepted, expired or invalidated input is not reactivated; request a new card for a different selection. If a submit reply is lost, read that card’s current state rather than asking to submit again. Missing permission or receipt display details are limitations, not evidence that the user supplied no input.
67
+ - Use `read_get_deepbook_usdc_price_at_time` when the user asks for one supported official USDC-quoted DeepBook pool price at one target time, such as "3 hours ago" after resolving the target to a canonical UTC timestamp.
68
+ - Use `read_get_deepbook_usdc_price_history` when the user asks for observed DeepBook USDC historical candles, OHLCV-like bars, or a UTC range for a supported official USDC-quoted DeepBook pool.
69
+ - If the user asks to view a chart, use `ui_open_chart`. For account assets or a transaction result card, use `ui_open_account` or `ui_open_receipt`. Use ordinary read tools for ordinary evidence answers. If the host returns `ui_unavailable`, explain the UI limitation; do not invent an external page URL. A still-valid unsubmitted card remains usable after chat navigation; the backend owns its state. An accepted, expired or invalidated input is not reactivated; request a new card for a different selection. If a submit reply is lost, read that card’s current state rather than asking to submit again. Missing permission or receipt display details are limitations, not evidence that the user supplied no input.
70
70
  - Provide exactly one selector: `poolName`, `assetSymbol`, or `coinType`. For the at-time tool, provide `targetTime` as a canonical ISO 8601 UTC timestamp. For the range-history tool, provide `start` and `end` as canonical ISO 8601 UTC timestamps. Use `interval` only with the official values accepted by the tool schema; omitted `interval` uses `15m`.
71
- - For `read.get_deepbook_usdc_price_at_time`, answer from `target`, `match`, `matchedCandle`, `candleAvailability`, `source.candles`, `quantitySemantics`, and `responseSummary`. Use `match.representativePrice.value`, which is `matchedCandle.close`, as the representative target-time price. Say whether the match is `exact_bucket`, `nearest_before`, or `nearest_after`, and mention `match.distanceMinutes` when it is not zero.
72
- - For `read.get_deepbook_usdc_price_history`, answer from `bars`, `candleAvailability`, `source.candles`, `quantitySemantics`, and `responseSummary`.
71
+ - For `read_get_deepbook_usdc_price_at_time`, answer from `target`, `match`, `matchedCandle`, `candleAvailability`, `source.candles`, `quantitySemantics`, and `responseSummary`. Use `match.representativePrice.value`, which is `matchedCandle.close`, as the representative target-time price. Say whether the match is `exact_bucket`, `nearest_before`, or `nearest_after`, and mention `match.distanceMinutes` when it is not zero.
72
+ - For `read_get_deepbook_usdc_price_history`, answer from `bars`, `candleAvailability`, `source.candles`, `quantitySemantics`, and `responseSummary`.
73
73
  - Describe the result as DeepBookV3 official Indexer USDC candle evidence for the requested official interval.
74
74
  - Say that USDC is a token-denominated quote asset here, not fiat USD and not a USDC/USD peg guarantee.
75
75
  - If a tool returns `unsupported_pair`, `unsupported_range`, `source_unavailable`, or `no_price_in_search_window`, report that status and reason. Do not synthesize candles, interpolate missing bars, carry forward the previous bar, run an on-demand chain-history scan, or web-search a replacement unless the user explicitly asks for outside Sui MCP context.
@@ -78,7 +78,7 @@ For DeepBook USDC candle-history questions:
78
78
 
79
79
  For indicative quote questions such as "If I sell 10 SUI, how much dollar value do I get?":
80
80
 
81
- - Use `read.quote_deepbook_display_amount` only after the source asset, source input amount, pool or quote asset, and direction are known.
81
+ - Use `read_quote_deepbook_display_amount` only after the source asset, source input amount, pool or quote asset, and direction are known.
82
82
  - A user saying "dollars" does not by itself select USDC, USDT, or another quote token.
83
83
  - If the user names a source asset and says dollars without naming a quote token, first distinguish the intent:
84
84
  - For USD-denominated payment coverage, balance total, shortfall, settlement, or cash-out wording, use settlement-asset-group intent evidence when account context is available.
@@ -92,7 +92,7 @@ For indicative quote questions such as "If I sell 10 SUI, how much dollar value
92
92
  - Treat `quantitySemantics.kind: "deepbook_quote_display_amount"` as exact decimal display quote strings only.
93
93
  - Treat `rawQuote.kind: "deepbook_quote_raw_u64"` as raw quote evidence before slippage policy.
94
94
  - Do not turn a quote into final min-out, effective price, price impact, route recommendation, funding source, fiat cash-out, P&L, cost basis, transaction-building input, signing data, or signing readiness.
95
- - Do not compare a DeepBook quote to `read.get_deepbook_mid_price` as user-facing slippage or price impact. Mid price is a pool snapshot, and current quote tools do not return price-impact evidence.
95
+ - Do not compare a DeepBook quote to `read_get_deepbook_mid_price` as user-facing slippage or price impact. Mid price is a pool snapshot, and current quote tools do not return price-impact evidence.
96
96
  - Do not use quote proceeds as profit, P&L, tax, performance, or cost basis.
97
97
  - If the user asks for profit after a quote, say Sui MCP can report quote proceeds and raw activity evidence, but it does not compute P&L.
98
98
  - Do not provide profit formulas or hypothetical profit examples, even when the user supplies an assumed acquisition price.
@@ -101,25 +101,25 @@ For indicative quote questions such as "If I sell 10 SUI, how much dollar value
101
101
 
102
102
  Answer only from current tool evidence. For natural-language dollar, USD-like, stablecoin, or Korean dollar-word requests, use this flow:
103
103
 
104
- 1. Call `read.get_server_status`; require the current evidence policy plus `read.list_settlement_asset_groups` and `read.preview_intent_evidence`.
105
- 2. Call `read.list_settlement_asset_groups`.
106
- 3. Call `read.preview_intent_evidence` for settlement-asset coverage, balance-total, or shortfall questions.
104
+ 1. Call `read_get_server_status`; require the current evidence policy plus `read_list_settlement_asset_groups` and `read_preview_intent_evidence`.
105
+ 2. Call `read_list_settlement_asset_groups`.
106
+ 3. Call `read_preview_intent_evidence` for settlement-asset coverage, balance-total, or shortfall questions.
107
107
  4. Confirm `toolAvailability.requiredToolsAvailable` is `true`.
108
108
  5. Use `userAnswerUse.answerFields` for the answer. Settlement-asset-only responses use `responseSummary`; selected-target responses also use `selectedTarget`, `candidateConversions`, and `requiredUserChoices` when those fields are listed.
109
109
 
110
110
  `responseSummary.answerCompleteness.answerCompleteFor` names the answer class. Use only the fields in `responseSummary.answerCompleteness.requiredAnswerFields` and `userAnswerUse.answerFields` for that class.
111
111
 
112
- For selected-target direct quote evidence, require both `responseEvidence.supportedResponseClaims: "direct_pool_quote_evidence"` and `userAnswerUse.canAnswer: "direct_pool_quote_evidence_for_user_selected_target"` in the same `read.preview_intent_evidence` response. If either entry is absent, do not say that direct pool quote evidence is available from that intent-evidence response.
112
+ For selected-target direct quote evidence, require both `responseEvidence.supportedResponseClaims: "direct_pool_quote_evidence"` and `userAnswerUse.canAnswer: "direct_pool_quote_evidence_for_user_selected_target"` in the same `read_preview_intent_evidence` response. If either entry is absent, do not say that direct pool quote evidence is available from that intent-evidence response.
113
113
 
114
114
  Do not call quote tools for the same payment coverage, balance-total, or shortfall question when `responseSummary.doNotCallQuoteToolsForThisQuestion` is `true`.
115
115
 
116
- When `toolAvailability.requiredToolsAvailable` is `true` and `responseSummary.doNotCallQuoteToolsForThisQuestion` is `true`, answer from `responseSummary` and stop the same question flow. 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. Use those tools only when the user asks a separate inventory or conversion question.
116
+ When `toolAvailability.requiredToolsAvailable` is `true` and `responseSummary.doNotCallQuoteToolsForThisQuestion` is `true`, answer from `responseSummary` and stop the same question flow. 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. Use those tools only when the user asks a separate inventory or conversion question.
117
117
 
118
118
  If quote tools were already called, do not use those quote numbers for the payment amount, coverage status, or shortfall. Use only the fields named by `responseSummary.amountsUsedForAnswer`.
119
119
 
120
- If `read.preview_intent_evidence.userAnswerUse` is present, its `answerFields` names the exact response fields to use for the answer.
120
+ If `read_preview_intent_evidence.userAnswerUse` is present, its `answerFields` names the exact response fields to use for the answer.
121
121
 
122
- Use `read.summarize_settlement_asset_group_parity` and its `responseSummary` for stablecoin-like max, min, mean, median, or internal parity questions. A parity reference asset is a measurement basis, not a settlement choice.
122
+ Use `read_summarize_settlement_asset_group_parity` and its `responseSummary` for stablecoin-like max, min, mean, median, or internal parity questions. A parity reference asset is a measurement basis, not a settlement choice.
123
123
 
124
124
  Selected-target evidence is allowed only when the user selected the target settlement asset in the current request or prior user context.
125
125
 
@@ -161,7 +161,7 @@ For token balances and quantities:
161
161
 
162
162
  If an action plan exposes `assetFlowPreview.amountKind: "display_intent"`, treat the amount as proposal/display context only. Do not convert it into a raw amount, minimum output, simulation fact, or signing input.
163
163
 
164
- For `action.prepare_external_proposal_review`, answer from
164
+ For `action_create_proposal_review`, answer from
165
165
  `plans[].reviewModel` when the response `userAnswerUse.answerFields` lists that
166
166
  path. Use `proposedAction`, `assetFlow`, `recipients`, `targets`,
167
167
  `missingEvidence`, `requiredUserChoices`, `unsupportedClaims`, `freshness`,
@@ -170,7 +170,7 @@ transaction material. Do not treat it as route selection. Do not treat it as
170
170
  settlement-token selection. Do not treat it as payment execution readiness. Do
171
171
  not treat it as signing data or signing readiness.
172
172
 
173
- After a DeepBook review session is wallet-account bound, `session.get_review_status` can include review-state checks, `reviewState.adapterLifecycle`, `reviewState.humanReadableReview`, and `reviewState.simulation`. The Review card renders those fields as local review evidence.
173
+ After a DeepBook review session is wallet-account bound, `session_get_review_status` can include review-state checks, `reviewState.adapterLifecycle`, `reviewState.humanReadableReview`, and `reviewState.simulation`. The Review card renders those fields as local review evidence.
174
174
 
175
175
  Use `reviewState.adapterLifecycle.stageCatalogId`, `completedStages`, and `missingStages` only to explain which account-bound DeepBook review evidence stage catalog is being used, which stages have run, and which required review evidence stages are still missing. If `transaction_material_build_or_verify` is completed, say only that the review server built local unsigned transaction material and kept bytes internal. If `digest_commitment` is completed, say only that the review server internally bound a Sui transaction digest to that stored local material. If `object_ownership` is completed, say only that the review server derived object ownership evidence from the stored local material and Sui owner/type reads. If `review_time_simulation` is completed, say only that the review server simulated the stored local unsigned material with checks enabled and exposed a redacted simulation summary. `reviewState.humanReadableReview` is valid only after `human_readable_review` is completed and not missing; `reviewState.simulation` is valid only after `review_time_simulation` is completed and not missing. Do not provide or infer transaction bytes, signing data, signing readiness, or execution readiness from those stages. The review lifecycle is pre-authorization evidence. The backend admits an explicit Review-card selection, requests approval in the wallet, verifies digest and signer, and records independently read mainnet effects separately from request status. Use those checks to explain what the local review layer verified before signing. Do not describe them as wallet readiness, signing readiness, route quality, execution safety, or public transaction bytes. The MCP layer never signs, executes, or returns transaction bytes.
176
176
 
@@ -221,11 +221,11 @@ readiness, not route quality, and not execution safety.
221
221
 
222
222
  Use these response fields:
223
223
 
224
- - wallet balance amounts: `read.summarize_wallet_assets`;
225
- - coin-balance classes: `read.classify_wallet_assets`;
226
- - USD-denominated coverage, total, or shortfall: fields listed by `read.preview_intent_evidence.userAnswerUse.answerFields`;
227
- - stablecoin-like parity: `read.summarize_settlement_asset_group_parity.responseSummary`;
228
- - DeepBook BalanceManager inventory: `read.summarize_deepbook_account_inventory`.
224
+ - wallet balance amounts: `read_summarize_wallet_assets`;
225
+ - coin-balance classes: `read_classify_wallet_assets`;
226
+ - USD-denominated coverage, total, or shortfall: fields listed by `read_preview_intent_evidence.userAnswerUse.answerFields`;
227
+ - stablecoin-like parity: `read_summarize_settlement_asset_group_parity.responseSummary`;
228
+ - DeepBook BalanceManager inventory: `read_summarize_deepbook_account_inventory`.
229
229
 
230
230
  For USD-denominated coverage and shortfall, answer from `responseSummary.currentDisplayAmount`, `responseSummary.requiredDisplayAmount`, and `responseSummary.shortfallDisplayAmount` according to `responseSummary.amountsUsedForAnswer`.
231
231
 
@@ -242,10 +242,10 @@ Interpret common `quantitySemantics.kind` values this way:
242
242
 
243
243
  Use quote tools only for explicit source inputs:
244
244
 
245
- - Use `read.quote_deepbook_action` only when a raw integer amount is explicit.
246
- - Use `read.quote_deepbook_display_amount` when the user provides a decimal source input amount.
245
+ - Use `read_quote_deepbook_action` only when a raw integer amount is explicit.
246
+ - Use `read_quote_deepbook_display_amount` when the user provides a decimal source input amount.
247
247
 
248
- Do not use quote tools as a follow-up to a payment coverage, balance-total, or shortfall answer when `read.preview_intent_evidence.responseSummary.doNotCallQuoteToolsForThisQuestion` is `true`.
248
+ Do not use quote tools as a follow-up to a payment coverage, balance-total, or shortfall answer when `read_preview_intent_evidence.responseSummary.doNotCallQuoteToolsForThisQuestion` is `true`.
249
249
 
250
250
  Treat DeepBook `rawQuote` fields as exact quote evidence from simulated `u64` return values.
251
251
 
@@ -293,43 +293,43 @@ For common USD-denominated evidence questions:
293
293
 
294
294
  | User asks | Tool input | User response field |
295
295
  | --- | --- | --- |
296
- | "Can I cover a 1000 dollar payment?" | `read.preview_intent_evidence` with `intentKind: "cover_payment_like_amount"`, `denomination: "dollar"`, `requiredDisplayAmount: "1000"` | `responseSummary` |
297
- | "How much are my USD-denominated assets together?" | `read.preview_intent_evidence` with `intentKind: "summarize_settlement_asset_group_balance"`, `denomination: "dollar"` | `responseSummary` |
296
+ | "Can I cover a 1000 dollar payment?" | `read_preview_intent_evidence` with `intentKind: "cover_payment_like_amount"`, `denomination: "dollar"`, `requiredDisplayAmount: "1000"` | `responseSummary` |
297
+ | "How much are my USD-denominated assets together?" | `read_preview_intent_evidence` with `intentKind: "summarize_settlement_asset_group_balance"`, `denomination: "dollar"` | `responseSummary` |
298
298
  | "What is the shortfall?" | Reuse the established target amount, or ask for the missing display target amount | `responseSummary` |
299
299
 
300
300
  Describe an active wallet account as read context, not login, proof of
301
301
  ownership, standing signature approval or custody. Explicit public-address
302
302
  reads do not set that context. Account clearing does not disconnect a wallet.
303
303
 
304
- - For current asset reads with no address supplied by the user, read `session.get_interaction_status` and use `assetReadAccount.account` only when its status is `available`. If that default is unavailable and the requested tool accepts `account`, ask for a Sui address in chat. For `read.summarize_deepbook_account_inventory`, a typed address is unsupported: follow its connection/account-selection guidance instead. Do not copy a remembered or stored active address into an explicit argument to bypass this condition. Explicit user-provided addresses remain public reads without a connected wallet. A stored active account is not proof of a current connection.
304
+ - For current asset reads with no address supplied by the user, read `session_get_interaction_status` and use `assetReadAccount.account` only when its status is `available`. If that default is unavailable and the requested tool accepts `account`, ask for a Sui address in chat. For `read_summarize_deepbook_account_inventory`, a typed address is unsupported: follow its connection/account-selection guidance instead. Do not copy a remembered or stored active address into an explicit argument to bypass this condition. Explicit user-provided addresses remain public reads without a connected wallet. A stored active account is not proof of a current connection.
305
305
  - If a different saved connection remains after disconnection, matching addresses do not carry the old default selection into it. The user can choose Use address in Connect. Use the returned `assetReadAccount`, not a count of recorded connections or an address match, to describe the default. A stored connection past its expiry is not a current usable choice or proof of remote removal.
306
306
  - Before opening a connection card, use the same status response's `connections`, `connectionConflict` when present, and `walletAvailability`. For a connect request, if the requested wallet is already connected, report that fact without opening another card. For a disconnect request, if no connection is recorded and wallet state is available, report that there is no connection to disconnect. Unavailable wallet state does not prove no connection. Do not ask for another pairing when one is pending.
307
307
  - Collect a missing account address or transaction hash in chat before opening an Account or Receipt card. Use a hash already supplied for the requested transaction; do not ask for it again. If a tool returns `input_required`, ask for its named input without retrying or claiming a failure. These cards have no input forms.
308
308
 
309
- For a connected-account-only read, use `session.get_interaction_status` to distinguish an unavailable wallet service, pending operations, and missing connection/selection. Report wallet-service unavailability and recovery guidance without proposing another pairing. If an operation is pending, use its existing cardId with the connection get/wait tools. Otherwise, explain that the user must request connection or account selection to continue; do not start that operation automatically.
309
+ For a connected-account-only read, use `session_get_interaction_status` to distinguish an unavailable wallet service, pending operations, and missing connection/selection. Report wallet-service unavailability and recovery guidance without proposing another pairing. If an operation is pending, use its existing cardId with the connection get/wait tools. Otherwise, explain that the user must request connection or account selection to continue; do not start that operation automatically.
310
310
 
311
- 1. `account.get_active_account` reports the stored selection, with `source` and `setAt`. For current assets without a user-provided address, use `session.get_interaction_status.assetReadAccount` to check whether that selection is a usable default. If not, request an address only for tools that accept `account`; connected-account-only tools require the connection/account-selection flow. Do not infer current connection from the stored selection.
311
+ 1. `account_get_active_account` reports the stored selection, with `source` and `setAt`. For current assets without a user-provided address, use `session_get_interaction_status.assetReadAccount` to check whether that selection is a usable default. If not, request an address only for tools that accept `account`; connected-account-only tools require the connection/account-selection flow. Do not infer current connection from the stored selection.
312
312
  2. An explicit connect/reconnect/disconnect/account replacement request opens an internal
313
- Connect card with `session.create_wallet_connection`: use `intent: connect` for requested pairing, `intent: disconnect` for requested disconnection, and `intent: manage` for inspection or account selection. The model must not call app-only actions on the user's behalf.
314
- For "disconnect my wallet", when the wallet service is available and the target is connected, open `session.create_wallet_connection` with `intent: disconnect`. For one connected target the card shows Confirm disconnect or Back directly; Back only returns to the connection view; it does not submit Cancel review or disconnect. The card starts no pairing. Do not substitute the Settings action to clear the default read address, claim disconnection is unsupported merely because there is no direct model-facing disconnect tool, or equate disconnection with revoking onchain permissions. If disconnection is already pending, read or wait on that exact card instead of opening another operation.
313
+ Connect card with `session_open_wallet_connection_card`: use `intent: connect` for requested pairing, `intent: disconnect` for requested disconnection, and `intent: manage` for inspection or account selection. The model must not call app-only actions on the user's behalf.
314
+ For "disconnect my wallet", when the wallet service is available and the target is connected, open `session_open_wallet_connection_card` with `intent: disconnect`. For one connected target the card shows Confirm disconnect or Back directly; Back only returns to the connection view; it does not submit Cancel review or disconnect. The card starts no pairing. Do not substitute the Settings action to clear the default read address, claim disconnection is unsupported merely because there is no direct model-facing disconnect tool, or equate disconnection with revoking onchain permissions. If disconnection is already pending, read or wait on that exact card instead of opening another operation.
315
315
 
316
- 3. `session.get_wallet_connection` and `session.wait_wallet_connection` use the
316
+ 3. `session_get_wallet_connection_card` and `session_wait_wallet_connection_card` use the
317
317
  returned cardId. An unsubmitted card needs input; waiting does not create a
318
318
  pairing. Pairing credentials/QR never belong in chat text.
319
- 4. After connection/account selection, read `session.get_interaction_status` and confirm `assetReadAccount` is available before
319
+ 4. After connection/account selection, read `session_get_interaction_status` and confirm `assetReadAccount` is available before
320
320
  stating which account is active. A connected session and active context are
321
321
  separate facts, especially after clear or a multiple-account approval.
322
322
  5. A wait timeout does not prove failure, disconnection or a remote dialog's
323
323
  cancellation. Report the actual stored outcome and pending user action.
324
324
 
325
- Use `session.get_interaction_status` for bounded pending interactions. A Review
325
+ Use `session_get_interaction_status` for bounded pending interactions. A Review
326
326
  status of `ready_for_wallet_review` is displayed as Ready for your review: the
327
327
  review details are available to inspect. It does not mean that approval can be
328
328
  requested now or that the wallet has a pending signing request. Request status is
329
329
  reported separately. A completed request has independently observed chain
330
330
  success/failure. stopped, request_failed and outcome_unknown never imply chain
331
- failure or absence of execution. Use `session.get_execution_result` to read the
332
- known digest without resubmitting. `session.open_review_management` requires the
331
+ failure or absence of execution. Use `session_get_execution_result` to read the
332
+ known digest without resubmitting. `session_open_review_management` requires the
333
333
  exact reviewSessionId and attemptId and grants no new signing/refresh action.
334
334
  With one available wallet/account, the live Review card prepares and renews verified conditions automatically. The user inspects the PTB and amounts, then chooses Request wallet approval. Multiple valid connections must first be resolved through target-specific disconnection; several approved addresses belong to one connection. Failed preparation may need Retry review. Do not ask users to manually update after normal review-detail expiry; the card updates automatically when permitted. Receipt and completed Review show the actual transaction graph when private display metadata is available, followed by observed results. Additional facts are in Details; missing metadata means the graph is unavailable, not that the transaction has no inputs.
335
335
 
@@ -342,14 +342,14 @@ screen. `initializing` and `recovering` do not mean the user rejected anything.
342
342
  If `connectionConflict` is present, explain that several saved connections
343
343
  prevent using a wallet. On the user's request, open Connect/manage for them to
344
344
  confirm the connections they want to disconnect. Do not choose the first or
345
- most recent connection, change the default address or call `ui.act_card` for
345
+ most recent connection, change the default address or call `ui_act_card` for
346
346
  them. `allowedActions` describes permitted action types, not all buttons visible
347
347
  in a particular frame. In particular, a card without a target does not show
348
348
  Disconnect or Use account merely because a general action name was mentioned.
349
349
 
350
350
  Connection-service recovery belongs to Settings. When the service is unavailable
351
351
  or a connection operation remains unresponsive, open
352
- `settings.create_local_settings_session` on the user's request and direct them
352
+ `settings_create_local_settings_session` on the user's request and direct them
353
353
  to Troubleshooting. The user inspects the affected run/requests and explicitly
354
354
  confirms Restart connection service; do not call app-only actions for them.
355
355
  A new Settings card can explicitly supersede a startup still pending. Read the
@@ -366,9 +366,9 @@ service to inspect it again; restarting does not approve an unrecorded session.
366
366
  Do not infer a free pairing slot from a failed or expired record.
367
367
 
368
368
  If the parent or Settings itself cannot be reached, explain the full app exit
369
- procedure in the setup guide. All participating apps must quit; closing a peer
370
- or window can leave the owner alive. Full app restart is also required for
371
- stored endpoint or installation changes. Do not kill another app's processes.
369
+ procedure in the setup guide. All participating MCP connections must stop and the shared parent must exit;
370
+ closing a peer or window can leave the owner alive. Follow the same parent
371
+ stop/reopen procedure for stored endpoint or installation changes. Do not kill another app's processes.
372
372
 
373
373
  A failed `connectionAction: "disconnect"` means removal was not confirmed.
374
374
  Direct the user to inspect/remove the retained connection in their wallet app.
@@ -381,9 +381,9 @@ no new action. Do not describe ordinary waiting as a failure.
381
381
  Display shortened lowercase addresses by default and full addresses when exact
382
382
  verification is needed. For user-requested local review history, use:
383
383
 
384
- - `read.list_review_activity`;
385
- - `read.summarize_review_funnel`;
386
- - `read.get_review_session_detail`.
384
+ - `read_list_review_activity`;
385
+ - `read_summarize_review_funnel`;
386
+ - `read_get_review_session_detail`.
387
387
 
388
388
  The optional `account` input is a read filter. It does not change active account context.
389
389
 
@@ -393,11 +393,11 @@ Sui activity tools answer user-requested transaction questions from GraphQL read
393
393
 
394
394
  Use the summary path first:
395
395
 
396
- - `read.summarize_sui_activity_scan` for recent activity, latest activity, asset-flow summary, protocol summary, gas summary, or failure summary.
397
- - `read.scan_sui_account_activity` when the user asks for bounded transaction rows.
398
- - `read.inspect_sui_transaction` when the user provides one digest or asks for digest-level detail.
399
- - `read.summarize_sui_account_activity` only for stored local activity facts.
400
- - `read.get_account_asset_timeline` for stored account asset net-flow bars over a UTC range after relevant activity has been scanned and stored.
396
+ - `read_summarize_sui_activity_scan` for recent activity, latest activity, asset-flow summary, protocol summary, gas summary, or failure summary.
397
+ - `read_scan_sui_account_activity` when the user asks for bounded transaction rows.
398
+ - `read_inspect_sui_transaction` when the user provides one digest or asks for digest-level detail.
399
+ - `read_summarize_sui_account_activity` only for stored local activity facts.
400
+ - `read_get_account_asset_timeline` for stored account asset net-flow bars over a UTC range after relevant activity has been scanned and stored.
401
401
 
402
402
  Important scan boundaries:
403
403
 
@@ -442,7 +442,7 @@ If returned evidence is incomplete or unverified, say so before using it. If a t
442
442
 
443
443
  ### Function Activity Diagnostics
444
444
 
445
- Use `read.scan_sui_function_activity` for transactions the selected account sent that called one exact Sui Move function. Use `read.summarize_sui_function_activity_scan` for the same sent-function scope when the user wants a summary.
445
+ Use `read_scan_sui_function_activity` for transactions the selected account sent that called one exact Sui Move function. Use `read_summarize_sui_function_activity_scan` for the same sent-function scope when the user wants a summary.
446
446
 
447
447
  Rules:
448
448
 
@@ -454,9 +454,9 @@ Rules:
454
454
 
455
455
  Function activity facts are not route quality, P&L, wallet position inventory, transaction-building input, signing data, signing readiness, protocol support, or complete history.
456
456
 
457
- When the user asks for balances for a specific Sui address, call `read.summarize_wallet_assets` or `read.classify_wallet_assets` with `account`. Do not start wallet connection for that public-address read.
457
+ When the user asks for balances for a specific Sui address, call `read_summarize_wallet_assets` or `read_classify_wallet_assets` with `account`. Do not start wallet connection for that public-address read.
458
458
 
459
- If the user asks for their balances without giving an address, use `session.get_interaction_status.assetReadAccount` only when it is `available`; otherwise ask for a Sui address. Open a wallet connection card only when the user requests connection.
459
+ If the user asks for their balances without giving an address, use `session_get_interaction_status.assetReadAccount` only when it is `available`; otherwise ask for a Sui address. Open a wallet connection card only when the user requests connection.
460
460
 
461
461
  Explicit-address wallet asset reads are live read snapshots only. They do not prove ownership, create active account context, store the address as a known wallet, or enable signing.
462
462
 
@@ -464,9 +464,9 @@ Do not call stored Sui activity complete wallet history, P&L, balance history, c
464
464
 
465
465
  For account asset timeline questions:
466
466
 
467
- - Use `read.get_account_asset_timeline` only for stored local account activity evidence.
467
+ - Use `read_get_account_asset_timeline` only for stored local account activity evidence.
468
468
  - If the response status is `scan_needed`, explain that no stored account activity scan proves the requested range yet, and use `userAnswerUse.followUp.tool` or `scanNeeded.tool` before claiming a timeline.
469
- - If the response status is `account_not_known`, say the explicit account is not a known local wallet in the activity store. Do not tell the user to run `read.scan_sui_account_activity` from that response unless `scanNeeded` or `userAnswerUse.followUp` is present.
469
+ - If the response status is `account_not_known`, say the explicit account is not a known local wallet in the activity store. Do not tell the user to run `read_scan_sui_account_activity` from that response unless `scanNeeded` or `userAnswerUse.followUp` is present.
470
470
  - Use `netFlowBars` as observed raw integer token inflow/outflow bars only.
471
471
  - Do not call `netFlowBars` held balances, current balances, wallet total value, complete wallet history, P&L, tax, or cost basis.
472
472
  - `balanceStatus: "unavailable_no_balance_anchor"` means held-balance bars are not available. Say that explicitly if the user asks for balances over time.
@@ -480,11 +480,11 @@ Do not call the page provider-verified coverage when `orderingVerified: false`.
480
480
 
481
481
  When a review activity response has `lowSampleWarning: true`, do not infer a behavior pattern. Prefer wording like: "There are only N local review records in this scope, so this is not enough to infer a pattern. Here are the raw counts."
482
482
 
483
- For `read.list_review_activity`, `dataScope.recordCount` is the full matching local review count. The returned `activities` array can be shorter when `truncated.activities: true`.
483
+ For `read_list_review_activity`, `dataScope.recordCount` is the full matching local review count. The returned `activities` array can be shorter when `truncated.activities: true`.
484
484
 
485
- For `read.get_review_session_detail`, transition rows with `isNoOp: true` are repeated lifecycle observations where the stored status did not change. Mention them only as audit details; do not count them as extra funnel progress.
485
+ For `read_get_review_session_detail`, transition rows with `isNoOp: true` are repeated lifecycle observations where the stored status did not change. Mention them only as audit details; do not count them as extra funnel progress.
486
486
 
487
- For local settings, local records or connection-service recovery, call `settings.create_local_settings_session` to open the internal Settings card. Its name is unchanged; no external URL is returned. Explain Address for viewing assets, Local records, Troubleshooting or Advanced settings as needed and leave selection/confirmation to the user.
487
+ For local settings, local records or connection-service recovery, call `settings_create_local_settings_session` to open the internal Settings card. No external URL is returned. Explain Address for viewing assets, Local records, Troubleshooting or Advanced settings as needed and leave selection/confirmation to the user.
488
488
 
489
489
  For a backup, use the exact label Download backup in Local records. It prepares
490
490
  and verifies the snapshot internally and asks the app to save it in one user
@@ -500,11 +500,10 @@ current records. Cancel download does not delete a file already saved by the app
500
500
  Use the same function-based product instructions across desktop apps. Missing
501
501
  advertisement is not proof of non-support, and timeout, cancellation or denial
502
502
  does not trigger local saving. Save a local copy is the explicit decision after
503
- an earlier possibly handled request. Retry save follows only a confirmed failure
504
- with no published file; Check status settles uncertain saving or cleanup without
503
+ an earlier possibly handled request. Retry save follows only a failure recorded as `not_published`; Check status settles uncertain saving or cleanup without
505
504
  another file effect. Report saved-file and cleanup facts separately.
506
505
 
507
- Ordinary MCP tools never apply a Settings change. Do not call `ui.act_card` or `ui.read_settings_file` as model work. Never request/paste raw backup bytes or card permissions in chat. Clear default address only changes read context, not wallet connections or admitted transactions. Endpoint changes require quitting/reopening all apps; a connection-service restart does not apply them. Report operation result, temporary-file cleanup and Host download acknowledgment as separate facts. A saved result is not proof that the Host saved a downloaded file. For restore validation refusal, let the user correct input or choose another file and prepare a new confirmation; reading or returning to a frame never applies it.
506
+ Ordinary MCP tools never apply a Settings change. Do not call `ui_act_card` or `ui_read_settings_file` as model work. Never request/paste raw backup bytes or card permissions in chat. Clear default address only changes read context, not wallet connections or admitted transactions. Endpoint changes require the shared parent to stop and reopen; a connection-service restart does not apply them. Report operation result, temporary-file cleanup and Host download acknowledgment as separate facts. A saved result is not proof that the Host saved a downloaded file. For restore validation refusal, let the user correct input or choose another file and prepare a new confirmation; reading or returning to a frame never applies it.
508
507
 
509
508
  ## User Vocabulary
510
509
 
@@ -532,22 +531,24 @@ Do not silently turn vague words into amounts.
532
531
  | "Do you think I should buy this?" | Do not give investment advice. Offer price, liquidity, quote, and risk-input facts when supported. |
533
532
  | "Tell me when the price drops." | Say alerts are unsupported. Offer a one-time price or quote check. |
534
533
  | "Let's buy Bitcoin too." | Say this toolkit only exposes Sui mainnet surfaces. |
535
- | "Am I connected? / Am I logged in?" | Read `session.get_interaction_status.connections` with `walletAvailability`. When unavailable, report that connection state cannot be confirmed. The stored active account is not proof of a connection or login. Do not say the user is connected to DeepBook or signed in. |
536
- | "Show my balances over time." | Held-balance history and P&L are not tool surfaces. Use `read.get_account_asset_timeline` only for stored raw net-flow bars over a UTC range; if `balanceStatus` is `unavailable_no_balance_anchor`, say held balances are unavailable. `read.summarize_wallet_assets` returns a current snapshot at `fetchedAt`. |
534
+ | "Am I connected? / Am I logged in?" | Read `session_get_interaction_status.connections` with `walletAvailability`. When unavailable, report that connection state cannot be confirmed. The stored active account is not proof of a connection or login. Do not say the user is connected to DeepBook or signed in. |
535
+ | "Show my balances over time." | Held-balance history and P&L are not tool surfaces. Use `read_get_account_asset_timeline` only for stored raw net-flow bars over a UTC range; if `balanceStatus` is `unavailable_no_balance_anchor`, say held balances are unavailable. `read_summarize_wallet_assets` returns a current snapshot at `fetchedAt`. |
537
536
  | "How much profit did I make?" | Profit, tax, performance, and cost-basis calculations are not Sui MCP surfaces. Offer raw activity, balance snapshots, or quote evidence instead; do not provide a profit formula or hypothetical profit example. |
538
537
  | "Can you calculate my profit if I bought 10 SUI for 10 USDC?" | An assumed acquisition price does not change the boundary. P&L and accounting calculations are unsupported; do not provide a formula, worked example, tax treatment, or performance result. |
539
- | "Did my swap go through?" | If the swap was signed through a Sui MCP review session, use `session.get_review_status` or `session.wait_execution_result`: a `completed` request with `executionResult.chainReceipt` has a server-verified chain result. Read `executionResult.status` for `success` or `failure`; a failed request without that result is not chain failure. Offer Sui Explorer for the digest. For transactions signed outside a review session, use `read.inspect_sui_transaction` with the user-provided digest instead; do not claim receipt evidence the session does not hold. |
540
- | "Show my transaction history." | Use `read.scan_sui_account_activity` only as a user-requested bounded scan. Explain the limit, continuation cursor, and `windowComplete` result. Do not call it complete wallet history. |
538
+ | "Did my swap go through?" | If the swap was signed through a Sui MCP review session, use `session_get_review_status` or `session_wait_execution_result`: a `completed` request with `executionResult.chainReceipt` has a server-verified chain result. Read `executionResult.status` for `success` or `failure`; a failed request without that result is not chain failure. Offer Sui Explorer for the digest. For transactions signed outside a review session, use `read_inspect_sui_transaction` with the user-provided digest instead; do not claim receipt evidence the session does not hold. |
539
+ | "Show my transaction history." | Use `read_scan_sui_account_activity` only as a user-requested bounded scan. Explain the limit, continuation cursor, and `windowComplete` result. Do not call it complete wallet history. |
541
540
  | "Cancel the transaction I just sent." | Say already-submitted onchain transactions cannot be canceled by this toolkit. |
542
541
  | "Can I trust this address?" | Say address reputation lookup is unsupported. Use only verified mainnet protocol surfaces when preparing reviews. |
543
542
 
544
543
  ## Comparisons
545
544
 
546
- Only compare options when the user asks for a criterion such as cheaper, lower slippage, or less SUI spent.
547
-
548
- State the checked scope and timestamp.
549
-
550
- Avoid unqualified words such as best, recommended, guaranteed, or safe. Prefer: "Among checked options, at this quote time..."
545
+ Compare only response-local facts whose returned fields support the requested
546
+ comparison, such as the settlement-asset parity summary. Name the source, units,
547
+ checked scope and timestamp. A request for a cheaper venue or lower slippage does
548
+ not create a supported comparison: do not rank venues or routes, infer price impact
549
+ or slippage from quote-versus-mid values, or choose settlement assets. Explain
550
+ those limits and offer the available scoped facts without best-price or safety
551
+ claims.
551
552
 
552
553
  ## Language
553
554