@zktx.io/sui-mcp 0.5.0 → 0.6.1

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 (138) hide show
  1. package/README.md +21 -21
  2. package/dist/adapters/adapterPromptSurfaces.js +0 -20
  3. package/dist/adapters/deepbook/deepbookQuotePolicy.js +0 -4
  4. package/dist/adapters/deepbook/deepbookReviewEvidence.js +0 -9
  5. package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +0 -9
  6. package/dist/adapters/intentPlanFactories.js +0 -6
  7. package/dist/core/action/contractNameRegistry.js +0 -53
  8. package/dist/core/action/forbiddenFields.js +0 -4
  9. package/dist/core/action/ptbVisualizationProducer.js +0 -3
  10. package/dist/core/action/receiptPtbGraph.js +0 -17
  11. package/dist/core/action/reviewTimeSimulationEvidence.js +0 -4
  12. package/dist/core/action/signableAdapterContract.js +0 -5
  13. package/dist/core/action/suiChainReceiptMapping.js +0 -18
  14. package/dist/core/action/suiChainReceiptReader.js +1 -21
  15. package/dist/core/action/suiChainReceiptVerifier.js +0 -10
  16. package/dist/core/action/transactionFunding.js +0 -7
  17. package/dist/core/action/types.js +0 -1
  18. package/dist/core/action/walletReviewContractAssembler.js +0 -2
  19. package/dist/core/activity/localDataService.js +65 -52
  20. package/dist/core/activity/localDataValidation.js +1 -3
  21. package/dist/core/activity/sqliteActivityStore.js +24 -24
  22. package/dist/core/activity/sqliteActivityStoreRows.js +0 -2
  23. package/dist/core/activity/sqliteActivityStoreSchema.js +81 -14
  24. package/dist/core/preferences/sqlitePreferencesRepository.js +5 -3
  25. package/dist/core/read/deepbookReadHelpers.js +0 -2
  26. package/dist/core/read/deepbookRegistry.js +0 -19
  27. package/dist/core/read/deepbookUsdcChartService.js +0 -2
  28. package/dist/core/read/readCardResult.js +0 -2
  29. package/dist/core/read/readService.js +0 -19
  30. package/dist/core/read/readServiceTypes.js +0 -2
  31. package/dist/core/session/cardSession.js +1 -5
  32. package/dist/core/session/cardSessionStore.js +54 -7
  33. package/dist/core/session/reviewValidity.js +0 -3
  34. package/dist/core/session/sessionRecordStore.js +0 -1
  35. package/dist/core/session/sessionStore.js +0 -32
  36. package/dist/core/session/settingsFileIdentity.js +9 -0
  37. package/dist/core/session/settingsFileProtocol.js +20 -0
  38. package/dist/core/session/settingsFileStore.js +337 -0
  39. package/dist/core/session/settingsInputError.js +32 -0
  40. package/dist/core/session/settingsOperation.js +220 -0
  41. package/dist/core/session/settingsPreparationSql.js +13 -0
  42. package/dist/core/session/settingsWorkflow.js +1183 -0
  43. package/dist/core/session/sqliteCardStore.js +0 -2
  44. package/dist/core/session/sqliteSessionStore.js +0 -51
  45. package/dist/core/session/sqliteSettingsWorkflowStore.js +453 -0
  46. package/dist/core/session/sqliteTransactionMaterialStore.js +0 -11
  47. package/dist/core/session/sqliteWalletWorkflowStore.js +160 -66
  48. package/dist/core/session/status.js +2 -4
  49. package/dist/core/session/transactionMaterialStore.js +0 -4
  50. package/dist/core/session/transactionRequest.js +0 -4
  51. package/dist/core/session/walletConnection.js +26 -10
  52. package/dist/core/session/walletWorkflow.js +70 -30
  53. package/dist/core/session/workflowState.js +14 -14
  54. package/dist/core/session/workflowView.js +18 -8
  55. package/dist/core/suiAddress.js +0 -5
  56. package/dist/core/suiEndpoint.js +0 -3
  57. package/dist/mcp/prompts.js +0 -12
  58. package/dist/mcp/responseGuidance.js +10 -5
  59. package/dist/mcp/schemas.js +0 -3
  60. package/dist/mcp/serverInfo.js +3 -4
  61. package/dist/mcp/toolNames.js +2 -2
  62. package/dist/mcp/tools/account/index.js +1 -19
  63. package/dist/mcp/tools/action/prepareSuiActionReview.js +0 -6
  64. package/dist/mcp/tools/read/readToolHelpers.js +5 -4
  65. package/dist/mcp/tools/read/serverStatusTools.js +0 -1
  66. package/dist/mcp/tools/session/executionResultTools.js +2 -2
  67. package/dist/mcp/tools/session/shared.js +1 -2
  68. package/dist/mcp/tools/session/statusTools.js +4 -5
  69. package/dist/mcp/tools/settings/index.js +8 -28
  70. package/dist/mcp-app/account.html +14 -14
  71. package/dist/mcp-app/account.notices.txt +1 -1
  72. package/dist/mcp-app/chart.html +9 -9
  73. package/dist/mcp-app/chart.notices.txt +1 -1
  74. package/dist/mcp-app/connect.html +14 -14
  75. package/dist/mcp-app/connect.notices.txt +1 -1
  76. package/dist/mcp-app/receipt.html +1298 -1463
  77. package/dist/mcp-app/receipt.notices.txt +226 -1204
  78. package/dist/mcp-app/review.html +1298 -1463
  79. package/dist/mcp-app/review.notices.txt +226 -1204
  80. package/dist/mcp-app/settings.html +3133 -0
  81. package/dist/mcp-app/settings.notices.txt +973 -0
  82. package/dist/mcp-ui/contracts.js +8 -2
  83. package/dist/mcp-ui/readCards.js +1 -1
  84. package/dist/mcp-ui/tools.js +34 -4
  85. package/dist/review-server/server.js +3 -51
  86. package/dist/runtime/application.js +41 -14
  87. package/dist/runtime/config.js +0 -2
  88. package/dist/runtime/localSettingsService.js +23 -2
  89. package/dist/runtime/logger.js +0 -2
  90. package/dist/runtime/reviewServerAcquire.js +1 -18
  91. package/dist/runtime/runtimeTermination.js +1 -4
  92. package/dist/runtime/shared/authenticatedFetch.js +2 -4
  93. package/dist/runtime/shared/control.js +4 -7
  94. package/dist/runtime/shared/dataAccess.js +0 -2
  95. package/dist/runtime/shared/http.js +14 -0
  96. package/dist/runtime/shared/mcpHttp.js +6 -6
  97. package/dist/runtime/shared/ownerLease.js +0 -4
  98. package/dist/runtime/shared/server.js +1 -2
  99. package/dist/runtime/shared/stdio.js +2 -5
  100. package/dist/runtime/smokeMainnetRead.js +0 -3
  101. package/dist/runtime/smokeReview.js +0 -4
  102. package/dist/runtime/start.js +0 -2
  103. package/dist/runtime/suiTransactionGraphqlMapping.js +0 -2
  104. package/dist/runtime/suiTransactionGraphqlQueries.js +0 -3
  105. package/dist/runtime/walletConnectConfig.js +0 -2
  106. package/dist/runtime/walletConnectStorage.js +2 -10
  107. package/dist/runtime/walletConnectTransport.js +0 -11
  108. package/dist/runtime/walletSdkChildRuntime.js +2 -6
  109. package/dist/runtime/walletSdkIpc.js +2 -1
  110. package/dist/runtime/walletSdkProcess.js +3 -8
  111. package/docs/AGENT_BEHAVIOR.md +45 -15
  112. package/docs/LOCAL_DB_ARCHITECTURE.md +145 -22
  113. package/docs/MCP_SETUP.md +99 -39
  114. package/docs/MCP_TOOLS.md +288 -24
  115. package/docs/SDK_API.md +63 -10
  116. package/docs/UTILITY_INDEX.md +9 -6
  117. package/docs/WALLET_CONNECTION.md +32 -10
  118. package/package.json +22 -8
  119. package/dist/core/activity/schemaVersion.js +0 -2
  120. package/dist/core/session/keyedRecordStore.js +0 -18
  121. package/dist/core/session/settingsSession.js +0 -1
  122. package/dist/core/session/settingsSessions.js +0 -45
  123. package/dist/review-app/brand-dark.svg +0 -1
  124. package/dist/review-app/brand-light.svg +0 -1
  125. package/dist/review-app/favicon.svg +0 -1
  126. package/dist/review-app/settings.css +0 -1
  127. package/dist/review-app/settings.js +0 -1
  128. package/dist/review-app/ui.css +0 -809
  129. package/dist/review-server/assets.js +0 -48
  130. package/dist/review-server/html.js +0 -45
  131. package/dist/review-server/http.js +0 -47
  132. package/dist/review-server/middleware/reviewToken.js +0 -7
  133. package/dist/review-server/settingsApi.js +0 -158
  134. package/docs/AGENT_DEVELOPMENT_POLICY.md +0 -815
  135. package/docs/FRONTEND_POLICY.md +0 -534
  136. package/docs/golden-scenarios/BEHAVIOR_MATRIX.md +0 -166
  137. package/docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md +0 -161
  138. package/docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md +0 -259
@@ -1,4 +1,4 @@
1
- import { CONNECTION_CONFLICT_MESSAGE } from "../../../core/session/walletConnection.js";
1
+ import { CONNECTION_CONFLICT_MESSAGE, CONNECTION_RECONCILIATION_MESSAGE } from "../../../core/session/walletConnection.js";
2
2
  import { ReadServiceCacheError, ReadServiceInputError } from "../../../core/read/readService.js";
3
3
  import { parseSuiAddress } from "../../../core/suiAddress.js";
4
4
  import { errorToolResult } from "../../result.js";
@@ -41,7 +41,7 @@ export async function resolveExplicitOrActiveAccount(input, deps) {
41
41
  };
42
42
  }
43
43
  try {
44
- const context = deps.workflow?.readConnectionContext();
44
+ const context = deps.workflow?.reconcileConnectionContext();
45
45
  if (context?.assetReadAccount.status === "available")
46
46
  return { status: "ok", account: context.assetReadAccount.account };
47
47
  const availability = context?.walletAvailability ?? walletUnavailable("initialization_failed");
@@ -51,13 +51,14 @@ export async function resolveExplicitOrActiveAccount(input, deps) {
51
51
  details: { ...(availability.status === "unavailable" ? { reason: availability.reason } : {}), message: availability.message, walletAvailability: availability } }) };
52
52
  return { status: "error", result: errorToolResult({ kind: active ? "input_invalid" : "active_account_not_set",
53
53
  details: { reason: "connected_account_required",
54
- message: context?.connectionConflict ? CONNECTION_CONFLICT_MESSAGE : "This tool requires a selected account with a usable wallet connection. An address alone cannot be used.",
54
+ message: context?.connectionReconciliationRequired ? CONNECTION_RECONCILIATION_MESSAGE : context?.connectionConflict ? CONNECTION_CONFLICT_MESSAGE : "This tool requires a selected account with a usable wallet connection. An address alone cannot be used.",
55
55
  ...(context?.connectionConflict ? { connectionConflict: context.connectionConflict } : {}),
56
+ ...(context?.connectionReconciliationRequired ? { connectionReconciliationRequired: true } : {}),
56
57
  followUp: { tool: TOOL_NAMES.sessionGetInteractionStatus,
57
58
  answerFields: ["walletAvailability", "connections", "pendingWalletConnections", "assetReadAccount"],
58
59
  reason: `Check current connections and pending operations. Use pendingWalletConnections.items[].cardId with ${TOOL_NAMES.sessionGetWalletConnection} or ${TOOL_NAMES.sessionWaitWalletConnection}. If no operation is pending and the user requests connection or account selection, open ${TOOL_NAMES.sessionCreateWalletConnection}. Only the user may act in that card.` } } }) };
59
60
  }
60
- const message = context?.connectionConflict ? CONNECTION_CONFLICT_MESSAGE + " Provide a Sui address in chat for this public read." : availability.status !== "available"
61
+ const message = context?.connectionReconciliationRequired ? CONNECTION_RECONCILIATION_MESSAGE + " Provide a Sui address in chat for this public read." : context?.connectionConflict ? CONNECTION_CONFLICT_MESSAGE + " Provide a Sui address in chat for this public read." : availability.status !== "available"
61
62
  ? "The wallet connection cannot be checked. Please provide a Sui address in chat to view its assets."
62
63
  : "No connected wallet is available for the selected account. Please provide a Sui address in chat.";
63
64
  return { status: "address_required", message, result: errorToolResult({ kind: "input_invalid",
@@ -5,7 +5,6 @@ import { MCP_PROMPTS } from "../../prompts.js";
5
5
  import { MCP_RESOURCES } from "../../resources.js";
6
6
  import { EVIDENCE_POLICY, FAIL_CLOSED_TOOLS, IMPLEMENTED_TOOLS, PACKAGE_NAME, SERVER_LIMITATIONS, SERVER_NAME, SERVER_NETWORK, SERVER_RUNTIME, SERVER_TRANSPORT, SERVER_VERSION } from "../../serverInfo.js";
7
7
  import { TOOL_NAMES } from "../../toolNames.js";
8
- // Executable swap adapters precede protocol-notes-only entries.
9
8
  export const SUPPORTED_PROTOCOLS = [
10
9
  { id: "deepbook-v3", status: "mainnet", support: "read_and_local_review" },
11
10
  { id: "deepbook-margin", status: "mainnet", support: "protocol_notes_only" }
@@ -20,7 +20,7 @@ export function registerExecutionResultTools(server, deps) {
20
20
  if (!state)
21
21
  return errorToolResult({ kind: "session_not_found", details: { reviewSessionId } });
22
22
  const request = state.request;
23
- return okToolResult({ ...reviewStatusResponse(state), userAnswerUse: executionResultUserAnswerUse({ hasConnectionConflict: !!state.connectionConflict, hasRequest: !!request, hasExecutionResult: !!request?.execution }) });
23
+ return okToolResult({ ...reviewStatusResponse(state), userAnswerUse: executionResultUserAnswerUse({ hasConnectionConflict: !!state.connectionConflict, reconciliationRequired: !!state.connectionReconciliationRequired, hasRequest: !!request, hasExecutionResult: !!request?.execution }) });
24
24
  }
25
25
  catch (error) {
26
26
  return sessionStoreToolError(error, deps.logger);
@@ -35,7 +35,7 @@ export function registerExecutionResultTools(server, deps) {
35
35
  try {
36
36
  const result = await waitForExecutionResult((id) => readCurrentReview(deps, id), reviewSessionId, { timeoutMs, signal: extra.signal });
37
37
  return okToolResult({ waitOutcome: result.waitOutcome, ...reviewStatusResponse(result),
38
- userAnswerUse: executionResultUserAnswerUse({ hasConnectionConflict: !!result.connectionConflict, hasRequest: !!result.request, hasExecutionResult: !!result.request?.execution, hasWaitOutcome: true }) });
38
+ userAnswerUse: executionResultUserAnswerUse({ hasConnectionConflict: !!result.connectionConflict, reconciliationRequired: !!result.connectionReconciliationRequired, hasRequest: !!result.request, hasExecutionResult: !!result.request?.execution, hasWaitOutcome: true }) });
39
39
  }
40
40
  catch (error) {
41
41
  return sessionStoreToolError(error, deps.logger);
@@ -15,6 +15,7 @@ export function executionStatusCategorySchema() { return z.enum(EXECUTION_STATUS
15
15
  export const timeoutInputSchema = z.number().int().min(1).max(MAX_WAIT_TIMEOUT_MS).default(DEFAULT_WAIT_TIMEOUT_MS).optional();
16
16
  export function waitExecutionInputSchema() { return { reviewSessionId: z.string().min(1), timeoutMs: timeoutInputSchema }; }
17
17
  export const reviewStatusResponseShape = {
18
+ connectionReconciliationRequired: z.literal(true).optional(),
18
19
  connectionConflict: connectionConflictSchema.optional(), walletAvailability: walletAvailabilitySchema, walletObservation: walletObservationSchema.optional(), progress: workflowProgressSchema,
19
20
  reviewSessionId: z.string(), status: internalSessionStatusSchema, reviewRevision: z.number().int().nonnegative(),
20
21
  account: z.string().optional(), plans: z.array(actionPlanSchema), reviewState: reviewStateOutputSchema.optional(),
@@ -26,8 +27,6 @@ export function latest(items) {
26
27
  const sorted = [...items].sort((left, right) => right.lastActivityAt.localeCompare(left.lastActivityAt));
27
28
  return { limit: INTERACTION_STATUS_LIMIT, items: sorted.slice(0, INTERACTION_STATUS_LIMIT), truncated: sorted.length > INTERACTION_STATUS_LIMIT };
28
29
  }
29
- // Runtime workflows own reconciliation/observation. A server without a wallet
30
- // workflow can still expose ordinary preparation facts, with explicit absence.
31
30
  export async function readCurrentReview(deps, id, explicitResult = false) {
32
31
  if (deps.workflow)
33
32
  return deps.workflow.readReview(id, explicitResult);
@@ -18,6 +18,7 @@ export function registerSessionStatusTools(server, deps) {
18
18
  outputSchema: successOutputSchema({ walletAvailability: walletAvailabilitySchema, walletObservation: walletObservationSchema.optional(), activeAccount: activeAccountResponseSchema,
19
19
  connections: z.array(connectionViewSchema), assetReadAccount: assetReadAccountSchema,
20
20
  connectionConflict: connectionConflictSchema.optional(),
21
+ manageableConnectionIds: z.array(z.string().min(1)), connectionReconciliationRequired: z.literal(true).optional(),
21
22
  pendingWalletConnections: z.object({ limit: z.number().int().positive(), truncated: z.boolean(),
22
23
  items: z.array(z.object({ cardId: z.string(), connectionId: z.string().optional(),
23
24
  status: pendingConnectionStatusSchema, progress: workflowProgressSchema, lastActivityAt: z.string() })) }),
@@ -33,16 +34,14 @@ export function registerSessionStatusTools(server, deps) {
33
34
  return activityStoreToolError(error, deps.logger);
34
35
  }
35
36
  try {
36
- // Connection reconciliation can invalidate reviews and interrupt requests.
37
- // Complete that maintenance before projecting its dependent review facts.
38
- const context = deps.workflow?.readConnectionContext() ?? { connections: [],
37
+ const context = deps.workflow?.reconcileConnectionContext() ?? { connections: [], manageableConnectionIds: [],
39
38
  assetReadAccount: { status: "address_required" }, walletAvailability: walletUnavailable("initialization_failed") };
40
39
  const connections = deps.workflow?.pendingConnections() ?? [];
41
40
  const states = await Promise.all(deps.sessions.reviewSessionIds().map((id) => readCurrentReview(deps, id)));
42
41
  const reviews = states.flatMap((state) => state && isReviewInteractionPending(state) ? [reviewStatusResponse(state)] : []);
43
42
  return okToolResult({ activeAccount: activeAccountResponse(active), pendingWalletConnections: latest(connections),
44
43
  pendingReviewSessions: latest(reviews), ...context,
45
- userAnswerUse: interactionStatusUserAnswerUse("walletObservation" in context && context.walletObservation !== undefined, "connectionConflict" in context && !!context.connectionConflict) });
44
+ userAnswerUse: interactionStatusUserAnswerUse("walletObservation" in context && context.walletObservation !== undefined, "connectionConflict" in context && !!context.connectionConflict, "connectionReconciliationRequired" in context && !!context.connectionReconciliationRequired) });
46
45
  }
47
46
  catch (error) {
48
47
  return sessionStoreToolError(error, deps.logger);
@@ -60,7 +59,7 @@ export function registerSessionStatusTools(server, deps) {
60
59
  return errorToolResult({ kind: "session_not_found", details: { reviewSessionId } });
61
60
  const session = state.session;
62
61
  return okToolResult({ ...reviewStatusResponse(state),
63
- userAnswerUse: reviewStatusUserAnswerUse(!!session.reviewState, !!session.reviewState?.adapterLifecycle, !!session.reviewState?.humanReadableReview, !!session.reviewState?.simulation, !!state.connectionConflict) });
62
+ userAnswerUse: reviewStatusUserAnswerUse(!!session.reviewState, !!session.reviewState?.adapterLifecycle, !!session.reviewState?.humanReadableReview, !!session.reviewState?.simulation, !!state.connectionConflict, !!state.connectionReconciliationRequired) });
64
63
  }
65
64
  catch (error) {
66
65
  return sessionStoreToolError(error, deps.logger);
@@ -1,10 +1,13 @@
1
1
  import { z } from "zod";
2
2
  import { SETTINGS_APPLIES_AFTER_RESTART } from "../../../core/preferences/preferencesStore.js";
3
3
  import { registerSuiMcpTool } from "../../registerTool.js";
4
- import { errorToolResult, okToolResult } from "../../result.js";
4
+ import { okToolResult } from "../../result.js";
5
5
  import { noParamsInputSchema, successOutputSchema } from "../../schemas.js";
6
6
  import { localSettingsToolError, sessionStoreToolError } from "../../toolErrors.js";
7
7
  import { TOOL_NAMES } from "../../toolNames.js";
8
+ import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
9
+ import { cardMetadata, createWorkflowCard } from "../../../mcp-ui/tools.js";
10
+ import { cardSnapshotSchema } from "../../../mcp-ui/contracts.js";
8
11
  const endpointSettingSchema = z.object({
9
12
  storedValue: z.string(),
10
13
  effectiveValue: z.string(),
@@ -13,34 +16,11 @@ const endpointSettingSchema = z.object({
13
16
  appliesAfter: z.literal(SETTINGS_APPLIES_AFTER_RESTART).optional()
14
17
  });
15
18
  export function registerSettingsTools(server, deps) {
16
- server.registerTool(TOOL_NAMES.settingsCreateLocalSettingsSession, {
17
- title: "Create local settings session",
18
- description: "Create a local settings page session.",
19
- inputSchema: noParamsInputSchema,
20
- outputSchema: successOutputSchema({
21
- settingsSessionId: z.string(),
22
- settingsUrl: z.string(),
23
- status: z.literal("created"),
24
- openTarget: z.literal("system_browser"),
25
- accessScope: z.literal("same_machine_loopback"),
26
- expiresAt: z.string(),
27
- lastActivityAt: z.string()
28
- }),
29
- annotations: { readOnlyHint: false, openWorldHint: false }
30
- }, async () => {
19
+ registerAppTool(server, TOOL_NAMES.settingsCreateLocalSettingsSession, { title: "Settings", description: "Open a local settings card.", inputSchema: noParamsInputSchema,
20
+ outputSchema: successOutputSchema(cardSnapshotSchema.shape), _meta: cardMetadata("settings"),
21
+ annotations: { readOnlyHint: false, openWorldHint: false } }, async () => {
31
22
  try {
32
- if (!deps.reviewBaseUrl)
33
- return errorToolResult({ kind: "ui_unavailable", details: { reason: "Settings UI is unavailable in this runtime." } });
34
- const created = await deps.sessions.createSettingsSession();
35
- return okToolResult({
36
- settingsSessionId: created.session.id,
37
- settingsUrl: `${deps.reviewBaseUrl}/settings/${created.session.id}#${created.token}`,
38
- status: "created",
39
- openTarget: "system_browser",
40
- accessScope: "same_machine_loopback",
41
- expiresAt: created.session.expiresAt,
42
- lastActivityAt: created.session.lastActivityAt
43
- });
23
+ return await createWorkflowCard(server, deps, "settings", {});
44
24
  }
45
25
  catch (error) {
46
26
  return sessionStoreToolError(error, deps.logger);