@metamask/client-mcp-core 0.1.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.
- package/CHANGELOG.md +17 -0
- package/LICENSE +6 -0
- package/LICENSE.APACHE2 +201 -0
- package/LICENSE.MIT +21 -0
- package/README.md +1459 -0
- package/dist/capabilities/context.cjs +34 -0
- package/dist/capabilities/context.cjs.map +1 -0
- package/dist/capabilities/context.d.cts +101 -0
- package/dist/capabilities/context.d.cts.map +1 -0
- package/dist/capabilities/context.d.mts +101 -0
- package/dist/capabilities/context.d.mts.map +1 -0
- package/dist/capabilities/context.mjs +29 -0
- package/dist/capabilities/context.mjs.map +1 -0
- package/dist/capabilities/index.cjs +18 -0
- package/dist/capabilities/index.cjs.map +1 -0
- package/dist/capabilities/index.d.cts +3 -0
- package/dist/capabilities/index.d.cts.map +1 -0
- package/dist/capabilities/index.d.mts +3 -0
- package/dist/capabilities/index.d.mts.map +1 -0
- package/dist/capabilities/index.mjs +2 -0
- package/dist/capabilities/index.mjs.map +1 -0
- package/dist/capabilities/types.cjs +3 -0
- package/dist/capabilities/types.cjs.map +1 -0
- package/dist/capabilities/types.d.cts +152 -0
- package/dist/capabilities/types.d.cts.map +1 -0
- package/dist/capabilities/types.d.mts +152 -0
- package/dist/capabilities/types.d.mts.map +1 -0
- package/dist/capabilities/types.mjs +2 -0
- package/dist/capabilities/types.mjs.map +1 -0
- package/dist/index.cjs +59 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +33 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +43 -0
- package/dist/index.mjs.map +1 -0
- package/dist/launcher/console-error-buffer.cjs +72 -0
- package/dist/launcher/console-error-buffer.cjs.map +1 -0
- package/dist/launcher/console-error-buffer.d.cts +43 -0
- package/dist/launcher/console-error-buffer.d.cts.map +1 -0
- package/dist/launcher/console-error-buffer.d.mts +43 -0
- package/dist/launcher/console-error-buffer.d.mts.map +1 -0
- package/dist/launcher/console-error-buffer.mjs +68 -0
- package/dist/launcher/console-error-buffer.mjs.map +1 -0
- package/dist/launcher/extension-id-resolver.cjs +177 -0
- package/dist/launcher/extension-id-resolver.cjs.map +1 -0
- package/dist/launcher/extension-id-resolver.d.cts +32 -0
- package/dist/launcher/extension-id-resolver.d.cts.map +1 -0
- package/dist/launcher/extension-id-resolver.d.mts +32 -0
- package/dist/launcher/extension-id-resolver.d.mts.map +1 -0
- package/dist/launcher/extension-id-resolver.mjs +173 -0
- package/dist/launcher/extension-id-resolver.mjs.map +1 -0
- package/dist/launcher/extension-readiness.cjs +50 -0
- package/dist/launcher/extension-readiness.cjs.map +1 -0
- package/dist/launcher/extension-readiness.d.cts +37 -0
- package/dist/launcher/extension-readiness.d.cts.map +1 -0
- package/dist/launcher/extension-readiness.d.mts +37 -0
- package/dist/launcher/extension-readiness.d.mts.map +1 -0
- package/dist/launcher/extension-readiness.mjs +43 -0
- package/dist/launcher/extension-readiness.mjs.map +1 -0
- package/dist/launcher/index.cjs +21 -0
- package/dist/launcher/index.cjs.map +1 -0
- package/dist/launcher/index.d.cts +5 -0
- package/dist/launcher/index.d.cts.map +1 -0
- package/dist/launcher/index.d.mts +5 -0
- package/dist/launcher/index.d.mts.map +1 -0
- package/dist/launcher/index.mjs +5 -0
- package/dist/launcher/index.mjs.map +1 -0
- package/dist/launcher/retry.cjs +35 -0
- package/dist/launcher/retry.cjs.map +1 -0
- package/dist/launcher/retry.d.cts +20 -0
- package/dist/launcher/retry.d.cts.map +1 -0
- package/dist/launcher/retry.d.mts +20 -0
- package/dist/launcher/retry.d.mts.map +1 -0
- package/dist/launcher/retry.mjs +31 -0
- package/dist/launcher/retry.mjs.map +1 -0
- package/dist/mcp-server/constants.cjs +22 -0
- package/dist/mcp-server/constants.cjs.map +1 -0
- package/dist/mcp-server/constants.d.cts +13 -0
- package/dist/mcp-server/constants.d.cts.map +1 -0
- package/dist/mcp-server/constants.d.mts +13 -0
- package/dist/mcp-server/constants.d.mts.map +1 -0
- package/dist/mcp-server/constants.mjs +19 -0
- package/dist/mcp-server/constants.mjs.map +1 -0
- package/dist/mcp-server/discovery.cjs +299 -0
- package/dist/mcp-server/discovery.cjs.map +1 -0
- package/dist/mcp-server/discovery.d.cts +56 -0
- package/dist/mcp-server/discovery.d.cts.map +1 -0
- package/dist/mcp-server/discovery.d.mts +56 -0
- package/dist/mcp-server/discovery.d.mts.map +1 -0
- package/dist/mcp-server/discovery.mjs +292 -0
- package/dist/mcp-server/discovery.mjs.map +1 -0
- package/dist/mcp-server/knowledge-store.cjs +1196 -0
- package/dist/mcp-server/knowledge-store.cjs.map +1 -0
- package/dist/mcp-server/knowledge-store.d.cts +249 -0
- package/dist/mcp-server/knowledge-store.d.cts.map +1 -0
- package/dist/mcp-server/knowledge-store.d.mts +249 -0
- package/dist/mcp-server/knowledge-store.d.mts.map +1 -0
- package/dist/mcp-server/knowledge-store.mjs +1154 -0
- package/dist/mcp-server/knowledge-store.mjs.map +1 -0
- package/dist/mcp-server/schemas.cjs +433 -0
- package/dist/mcp-server/schemas.cjs.map +1 -0
- package/dist/mcp-server/schemas.d.cts +557 -0
- package/dist/mcp-server/schemas.d.cts.map +1 -0
- package/dist/mcp-server/schemas.d.mts +557 -0
- package/dist/mcp-server/schemas.d.mts.map +1 -0
- package/dist/mcp-server/schemas.mjs +430 -0
- package/dist/mcp-server/schemas.mjs.map +1 -0
- package/dist/mcp-server/server.cjs +161 -0
- package/dist/mcp-server/server.cjs.map +1 -0
- package/dist/mcp-server/server.d.cts +24 -0
- package/dist/mcp-server/server.d.cts.map +1 -0
- package/dist/mcp-server/server.d.mts +24 -0
- package/dist/mcp-server/server.d.mts.map +1 -0
- package/dist/mcp-server/server.mjs +158 -0
- package/dist/mcp-server/server.mjs.map +1 -0
- package/dist/mcp-server/session-manager.cjs +53 -0
- package/dist/mcp-server/session-manager.cjs.map +1 -0
- package/dist/mcp-server/session-manager.d.cts +240 -0
- package/dist/mcp-server/session-manager.d.cts.map +1 -0
- package/dist/mcp-server/session-manager.d.mts +240 -0
- package/dist/mcp-server/session-manager.d.mts.map +1 -0
- package/dist/mcp-server/session-manager.mjs +48 -0
- package/dist/mcp-server/session-manager.mjs.map +1 -0
- package/dist/mcp-server/test-utils/flush-promises.cjs +10 -0
- package/dist/mcp-server/test-utils/flush-promises.cjs.map +1 -0
- package/dist/mcp-server/test-utils/flush-promises.d.cts +2 -0
- package/dist/mcp-server/test-utils/flush-promises.d.cts.map +1 -0
- package/dist/mcp-server/test-utils/flush-promises.d.mts +2 -0
- package/dist/mcp-server/test-utils/flush-promises.d.mts.map +1 -0
- package/dist/mcp-server/test-utils/flush-promises.mjs +7 -0
- package/dist/mcp-server/test-utils/flush-promises.mjs.map +1 -0
- package/dist/mcp-server/test-utils/index.cjs +13 -0
- package/dist/mcp-server/test-utils/index.cjs.map +1 -0
- package/dist/mcp-server/test-utils/index.d.cts +4 -0
- package/dist/mcp-server/test-utils/index.d.cts.map +1 -0
- package/dist/mcp-server/test-utils/index.d.mts +4 -0
- package/dist/mcp-server/test-utils/index.d.mts.map +1 -0
- package/dist/mcp-server/test-utils/index.mjs +4 -0
- package/dist/mcp-server/test-utils/index.mjs.map +1 -0
- package/dist/mcp-server/test-utils/mock-factories.cjs +129 -0
- package/dist/mcp-server/test-utils/mock-factories.cjs.map +1 -0
- package/dist/mcp-server/test-utils/mock-factories.d.cts +89 -0
- package/dist/mcp-server/test-utils/mock-factories.d.cts.map +1 -0
- package/dist/mcp-server/test-utils/mock-factories.d.mts +89 -0
- package/dist/mcp-server/test-utils/mock-factories.d.mts.map +1 -0
- package/dist/mcp-server/test-utils/mock-factories.mjs +125 -0
- package/dist/mcp-server/test-utils/mock-factories.mjs.map +1 -0
- package/dist/mcp-server/test-utils/mock-playwright.cjs +205 -0
- package/dist/mcp-server/test-utils/mock-playwright.cjs.map +1 -0
- package/dist/mcp-server/test-utils/mock-playwright.d.cts +69 -0
- package/dist/mcp-server/test-utils/mock-playwright.d.cts.map +1 -0
- package/dist/mcp-server/test-utils/mock-playwright.d.mts +69 -0
- package/dist/mcp-server/test-utils/mock-playwright.d.mts.map +1 -0
- package/dist/mcp-server/test-utils/mock-playwright.mjs +200 -0
- package/dist/mcp-server/test-utils/mock-playwright.mjs.map +1 -0
- package/dist/mcp-server/tokenization.cjs +117 -0
- package/dist/mcp-server/tokenization.cjs.map +1 -0
- package/dist/mcp-server/tokenization.d.cts +22 -0
- package/dist/mcp-server/tokenization.d.cts.map +1 -0
- package/dist/mcp-server/tokenization.d.mts +22 -0
- package/dist/mcp-server/tokenization.d.mts.map +1 -0
- package/dist/mcp-server/tokenization.mjs +112 -0
- package/dist/mcp-server/tokenization.mjs.map +1 -0
- package/dist/mcp-server/tools/batch.cjs +199 -0
- package/dist/mcp-server/tools/batch.cjs.map +1 -0
- package/dist/mcp-server/tools/batch.d.cts +81 -0
- package/dist/mcp-server/tools/batch.d.cts.map +1 -0
- package/dist/mcp-server/tools/batch.d.mts +81 -0
- package/dist/mcp-server/tools/batch.d.mts.map +1 -0
- package/dist/mcp-server/tools/batch.mjs +191 -0
- package/dist/mcp-server/tools/batch.mjs.map +1 -0
- package/dist/mcp-server/tools/build.cjs +47 -0
- package/dist/mcp-server/tools/build.cjs.map +1 -0
- package/dist/mcp-server/tools/build.d.cts +22 -0
- package/dist/mcp-server/tools/build.d.cts.map +1 -0
- package/dist/mcp-server/tools/build.d.mts +22 -0
- package/dist/mcp-server/tools/build.d.mts.map +1 -0
- package/dist/mcp-server/tools/build.mjs +44 -0
- package/dist/mcp-server/tools/build.mjs.map +1 -0
- package/dist/mcp-server/tools/cleanup.cjs +20 -0
- package/dist/mcp-server/tools/cleanup.cjs.map +1 -0
- package/dist/mcp-server/tools/cleanup.d.cts +10 -0
- package/dist/mcp-server/tools/cleanup.d.cts.map +1 -0
- package/dist/mcp-server/tools/cleanup.d.mts +10 -0
- package/dist/mcp-server/tools/cleanup.d.mts.map +1 -0
- package/dist/mcp-server/tools/cleanup.mjs +17 -0
- package/dist/mcp-server/tools/cleanup.mjs.map +1 -0
- package/dist/mcp-server/tools/clipboard.cjs +100 -0
- package/dist/mcp-server/tools/clipboard.cjs.map +1 -0
- package/dist/mcp-server/tools/clipboard.d.cts +16 -0
- package/dist/mcp-server/tools/clipboard.d.cts.map +1 -0
- package/dist/mcp-server/tools/clipboard.d.mts +16 -0
- package/dist/mcp-server/tools/clipboard.d.mts.map +1 -0
- package/dist/mcp-server/tools/clipboard.mjs +97 -0
- package/dist/mcp-server/tools/clipboard.mjs.map +1 -0
- package/dist/mcp-server/tools/context.cjs +66 -0
- package/dist/mcp-server/tools/context.cjs.map +1 -0
- package/dist/mcp-server/tools/context.d.cts +35 -0
- package/dist/mcp-server/tools/context.d.cts.map +1 -0
- package/dist/mcp-server/tools/context.d.mts +35 -0
- package/dist/mcp-server/tools/context.d.mts.map +1 -0
- package/dist/mcp-server/tools/context.mjs +62 -0
- package/dist/mcp-server/tools/context.mjs.map +1 -0
- package/dist/mcp-server/tools/definitions.cjs +463 -0
- package/dist/mcp-server/tools/definitions.cjs.map +1 -0
- package/dist/mcp-server/tools/definitions.d.cts +97 -0
- package/dist/mcp-server/tools/definitions.d.cts.map +1 -0
- package/dist/mcp-server/tools/definitions.d.mts +97 -0
- package/dist/mcp-server/tools/definitions.d.mts.map +1 -0
- package/dist/mcp-server/tools/definitions.mjs +451 -0
- package/dist/mcp-server/tools/definitions.mjs.map +1 -0
- package/dist/mcp-server/tools/discovery-tools.cjs +162 -0
- package/dist/mcp-server/tools/discovery-tools.cjs.map +1 -0
- package/dist/mcp-server/tools/discovery-tools.d.cts +26 -0
- package/dist/mcp-server/tools/discovery-tools.d.cts.map +1 -0
- package/dist/mcp-server/tools/discovery-tools.d.mts +26 -0
- package/dist/mcp-server/tools/discovery-tools.d.mts.map +1 -0
- package/dist/mcp-server/tools/discovery-tools.mjs +157 -0
- package/dist/mcp-server/tools/discovery-tools.mjs.map +1 -0
- package/dist/mcp-server/tools/error-classification.cjs +296 -0
- package/dist/mcp-server/tools/error-classification.cjs.map +1 -0
- package/dist/mcp-server/tools/error-classification.d.cts +135 -0
- package/dist/mcp-server/tools/error-classification.d.cts.map +1 -0
- package/dist/mcp-server/tools/error-classification.d.mts +135 -0
- package/dist/mcp-server/tools/error-classification.d.mts.map +1 -0
- package/dist/mcp-server/tools/error-classification.mjs +281 -0
- package/dist/mcp-server/tools/error-classification.mjs.map +1 -0
- package/dist/mcp-server/tools/helpers.cjs +149 -0
- package/dist/mcp-server/tools/helpers.cjs.map +1 -0
- package/dist/mcp-server/tools/helpers.d.cts +149 -0
- package/dist/mcp-server/tools/helpers.d.cts.map +1 -0
- package/dist/mcp-server/tools/helpers.d.mts +149 -0
- package/dist/mcp-server/tools/helpers.d.mts.map +1 -0
- package/dist/mcp-server/tools/helpers.mjs +141 -0
- package/dist/mcp-server/tools/helpers.mjs.map +1 -0
- package/dist/mcp-server/tools/index.cjs +27 -0
- package/dist/mcp-server/tools/index.cjs.map +1 -0
- package/dist/mcp-server/tools/index.d.cts +11 -0
- package/dist/mcp-server/tools/index.d.cts.map +1 -0
- package/dist/mcp-server/tools/index.d.mts +11 -0
- package/dist/mcp-server/tools/index.d.mts.map +1 -0
- package/dist/mcp-server/tools/index.mjs +11 -0
- package/dist/mcp-server/tools/index.mjs.map +1 -0
- package/dist/mcp-server/tools/interaction.cjs +190 -0
- package/dist/mcp-server/tools/interaction.cjs.map +1 -0
- package/dist/mcp-server/tools/interaction.d.cts +26 -0
- package/dist/mcp-server/tools/interaction.d.cts.map +1 -0
- package/dist/mcp-server/tools/interaction.d.mts +26 -0
- package/dist/mcp-server/tools/interaction.d.mts.map +1 -0
- package/dist/mcp-server/tools/interaction.mjs +185 -0
- package/dist/mcp-server/tools/interaction.mjs.map +1 -0
- package/dist/mcp-server/tools/knowledge.cjs +120 -0
- package/dist/mcp-server/tools/knowledge.cjs.map +1 -0
- package/dist/mcp-server/tools/knowledge.d.cts +34 -0
- package/dist/mcp-server/tools/knowledge.d.cts.map +1 -0
- package/dist/mcp-server/tools/knowledge.d.mts +34 -0
- package/dist/mcp-server/tools/knowledge.d.mts.map +1 -0
- package/dist/mcp-server/tools/knowledge.mjs +114 -0
- package/dist/mcp-server/tools/knowledge.mjs.map +1 -0
- package/dist/mcp-server/tools/launch.cjs +51 -0
- package/dist/mcp-server/tools/launch.cjs.map +1 -0
- package/dist/mcp-server/tools/launch.d.cts +10 -0
- package/dist/mcp-server/tools/launch.d.cts.map +1 -0
- package/dist/mcp-server/tools/launch.d.mts +10 -0
- package/dist/mcp-server/tools/launch.d.mts.map +1 -0
- package/dist/mcp-server/tools/launch.mjs +48 -0
- package/dist/mcp-server/tools/launch.mjs.map +1 -0
- package/dist/mcp-server/tools/navigation.cjs +242 -0
- package/dist/mcp-server/tools/navigation.cjs.map +1 -0
- package/dist/mcp-server/tools/navigation.d.cts +34 -0
- package/dist/mcp-server/tools/navigation.d.cts.map +1 -0
- package/dist/mcp-server/tools/navigation.d.mts +34 -0
- package/dist/mcp-server/tools/navigation.d.mts.map +1 -0
- package/dist/mcp-server/tools/navigation.mjs +236 -0
- package/dist/mcp-server/tools/navigation.mjs.map +1 -0
- package/dist/mcp-server/tools/registry.cjs +10 -0
- package/dist/mcp-server/tools/registry.cjs.map +1 -0
- package/dist/mcp-server/tools/registry.d.cts +4 -0
- package/dist/mcp-server/tools/registry.d.cts.map +1 -0
- package/dist/mcp-server/tools/registry.d.mts +4 -0
- package/dist/mcp-server/tools/registry.d.mts.map +1 -0
- package/dist/mcp-server/tools/registry.mjs +4 -0
- package/dist/mcp-server/tools/registry.mjs.map +1 -0
- package/dist/mcp-server/tools/run-tool.cjs +140 -0
- package/dist/mcp-server/tools/run-tool.cjs.map +1 -0
- package/dist/mcp-server/tools/run-tool.d.cts +39 -0
- package/dist/mcp-server/tools/run-tool.d.cts.map +1 -0
- package/dist/mcp-server/tools/run-tool.d.mts +39 -0
- package/dist/mcp-server/tools/run-tool.d.mts.map +1 -0
- package/dist/mcp-server/tools/run-tool.mjs +137 -0
- package/dist/mcp-server/tools/run-tool.mjs.map +1 -0
- package/dist/mcp-server/tools/screenshot.cjs +55 -0
- package/dist/mcp-server/tools/screenshot.cjs.map +1 -0
- package/dist/mcp-server/tools/screenshot.d.cts +10 -0
- package/dist/mcp-server/tools/screenshot.d.cts.map +1 -0
- package/dist/mcp-server/tools/screenshot.d.mts +10 -0
- package/dist/mcp-server/tools/screenshot.d.mts.map +1 -0
- package/dist/mcp-server/tools/screenshot.mjs +52 -0
- package/dist/mcp-server/tools/screenshot.mjs.map +1 -0
- package/dist/mcp-server/tools/seeding.cjs +214 -0
- package/dist/mcp-server/tools/seeding.cjs.map +1 -0
- package/dist/mcp-server/tools/seeding.d.cts +38 -0
- package/dist/mcp-server/tools/seeding.d.cts.map +1 -0
- package/dist/mcp-server/tools/seeding.d.mts +38 -0
- package/dist/mcp-server/tools/seeding.d.mts.map +1 -0
- package/dist/mcp-server/tools/seeding.mjs +208 -0
- package/dist/mcp-server/tools/seeding.mjs.map +1 -0
- package/dist/mcp-server/tools/state.cjs +69 -0
- package/dist/mcp-server/tools/state.cjs.map +1 -0
- package/dist/mcp-server/tools/state.d.cts +19 -0
- package/dist/mcp-server/tools/state.d.cts.map +1 -0
- package/dist/mcp-server/tools/state.d.mts +19 -0
- package/dist/mcp-server/tools/state.d.mts.map +1 -0
- package/dist/mcp-server/tools/state.mjs +66 -0
- package/dist/mcp-server/tools/state.mjs.map +1 -0
- package/dist/mcp-server/types/discovery.cjs +24 -0
- package/dist/mcp-server/types/discovery.cjs.map +1 -0
- package/dist/mcp-server/types/discovery.d.cts +30 -0
- package/dist/mcp-server/types/discovery.d.cts.map +1 -0
- package/dist/mcp-server/types/discovery.d.mts +30 -0
- package/dist/mcp-server/types/discovery.d.mts.map +1 -0
- package/dist/mcp-server/types/discovery.mjs +21 -0
- package/dist/mcp-server/types/discovery.mjs.map +1 -0
- package/dist/mcp-server/types/errors.cjs +33 -0
- package/dist/mcp-server/types/errors.cjs.map +1 -0
- package/dist/mcp-server/types/errors.d.cts +31 -0
- package/dist/mcp-server/types/errors.d.cts.map +1 -0
- package/dist/mcp-server/types/errors.d.mts +31 -0
- package/dist/mcp-server/types/errors.d.mts.map +1 -0
- package/dist/mcp-server/types/errors.mjs +30 -0
- package/dist/mcp-server/types/errors.mjs.map +1 -0
- package/dist/mcp-server/types/index.cjs +21 -0
- package/dist/mcp-server/types/index.cjs.map +1 -0
- package/dist/mcp-server/types/index.d.cts +10 -0
- package/dist/mcp-server/types/index.d.cts.map +1 -0
- package/dist/mcp-server/types/index.d.mts +10 -0
- package/dist/mcp-server/types/index.d.mts.map +1 -0
- package/dist/mcp-server/types/index.mjs +5 -0
- package/dist/mcp-server/types/index.mjs.map +1 -0
- package/dist/mcp-server/types/knowledge.cjs +3 -0
- package/dist/mcp-server/types/knowledge.cjs.map +1 -0
- package/dist/mcp-server/types/knowledge.d.cts +116 -0
- package/dist/mcp-server/types/knowledge.d.cts.map +1 -0
- package/dist/mcp-server/types/knowledge.d.mts +116 -0
- package/dist/mcp-server/types/knowledge.d.mts.map +1 -0
- package/dist/mcp-server/types/knowledge.mjs +2 -0
- package/dist/mcp-server/types/knowledge.mjs.map +1 -0
- package/dist/mcp-server/types/responses.cjs +3 -0
- package/dist/mcp-server/types/responses.cjs.map +1 -0
- package/dist/mcp-server/types/responses.d.cts +22 -0
- package/dist/mcp-server/types/responses.d.cts.map +1 -0
- package/dist/mcp-server/types/responses.d.mts +22 -0
- package/dist/mcp-server/types/responses.d.mts.map +1 -0
- package/dist/mcp-server/types/responses.mjs +2 -0
- package/dist/mcp-server/types/responses.mjs.map +1 -0
- package/dist/mcp-server/types/seeding.cjs +34 -0
- package/dist/mcp-server/types/seeding.cjs.map +1 -0
- package/dist/mcp-server/types/seeding.d.cts +40 -0
- package/dist/mcp-server/types/seeding.d.cts.map +1 -0
- package/dist/mcp-server/types/seeding.d.mts +40 -0
- package/dist/mcp-server/types/seeding.d.mts.map +1 -0
- package/dist/mcp-server/types/seeding.mjs +31 -0
- package/dist/mcp-server/types/seeding.mjs.map +1 -0
- package/dist/mcp-server/types/session.cjs +3 -0
- package/dist/mcp-server/types/session.cjs.map +1 -0
- package/dist/mcp-server/types/session.d.cts +11 -0
- package/dist/mcp-server/types/session.d.cts.map +1 -0
- package/dist/mcp-server/types/session.d.mts +11 -0
- package/dist/mcp-server/types/session.d.mts.map +1 -0
- package/dist/mcp-server/types/session.mjs +2 -0
- package/dist/mcp-server/types/session.mjs.map +1 -0
- package/dist/mcp-server/types/step-record.cjs +20 -0
- package/dist/mcp-server/types/step-record.cjs.map +1 -0
- package/dist/mcp-server/types/step-record.d.cts +86 -0
- package/dist/mcp-server/types/step-record.d.cts.map +1 -0
- package/dist/mcp-server/types/step-record.d.mts +86 -0
- package/dist/mcp-server/types/step-record.d.mts.map +1 -0
- package/dist/mcp-server/types/step-record.mjs +17 -0
- package/dist/mcp-server/types/step-record.mjs.map +1 -0
- package/dist/mcp-server/types/tool-inputs.cjs +3 -0
- package/dist/mcp-server/types/tool-inputs.cjs.map +1 -0
- package/dist/mcp-server/types/tool-inputs.d.cts +118 -0
- package/dist/mcp-server/types/tool-inputs.d.cts.map +1 -0
- package/dist/mcp-server/types/tool-inputs.d.mts +118 -0
- package/dist/mcp-server/types/tool-inputs.d.mts.map +1 -0
- package/dist/mcp-server/types/tool-inputs.mjs +2 -0
- package/dist/mcp-server/types/tool-inputs.mjs.map +1 -0
- package/dist/mcp-server/types/tool-outputs.cjs +3 -0
- package/dist/mcp-server/types/tool-outputs.cjs.map +1 -0
- package/dist/mcp-server/types/tool-outputs.d.cts +121 -0
- package/dist/mcp-server/types/tool-outputs.d.cts.map +1 -0
- package/dist/mcp-server/types/tool-outputs.d.mts +121 -0
- package/dist/mcp-server/types/tool-outputs.d.mts.map +1 -0
- package/dist/mcp-server/types/tool-outputs.mjs +2 -0
- package/dist/mcp-server/types/tool-outputs.mjs.map +1 -0
- package/dist/mcp-server/utils/errors.cjs +14 -0
- package/dist/mcp-server/utils/errors.cjs.map +1 -0
- package/dist/mcp-server/utils/errors.d.cts +9 -0
- package/dist/mcp-server/utils/errors.d.cts.map +1 -0
- package/dist/mcp-server/utils/errors.d.mts +9 -0
- package/dist/mcp-server/utils/errors.d.mts.map +1 -0
- package/dist/mcp-server/utils/errors.mjs +11 -0
- package/dist/mcp-server/utils/errors.mjs.map +1 -0
- package/dist/mcp-server/utils/index.cjs +22 -0
- package/dist/mcp-server/utils/index.cjs.map +1 -0
- package/dist/mcp-server/utils/index.d.cts +8 -0
- package/dist/mcp-server/utils/index.d.cts.map +1 -0
- package/dist/mcp-server/utils/index.d.mts +8 -0
- package/dist/mcp-server/utils/index.d.mts.map +1 -0
- package/dist/mcp-server/utils/index.mjs +8 -0
- package/dist/mcp-server/utils/index.mjs.map +1 -0
- package/dist/mcp-server/utils/logger.cjs +25 -0
- package/dist/mcp-server/utils/logger.cjs.map +1 -0
- package/dist/mcp-server/utils/logger.d.cts +9 -0
- package/dist/mcp-server/utils/logger.d.cts.map +1 -0
- package/dist/mcp-server/utils/logger.d.mts +9 -0
- package/dist/mcp-server/utils/logger.d.mts.map +1 -0
- package/dist/mcp-server/utils/logger.mjs +22 -0
- package/dist/mcp-server/utils/logger.mjs.map +1 -0
- package/dist/mcp-server/utils/redaction.cjs +24 -0
- package/dist/mcp-server/utils/redaction.cjs.map +1 -0
- package/dist/mcp-server/utils/redaction.d.cts +9 -0
- package/dist/mcp-server/utils/redaction.d.cts.map +1 -0
- package/dist/mcp-server/utils/redaction.d.mts +9 -0
- package/dist/mcp-server/utils/redaction.d.mts.map +1 -0
- package/dist/mcp-server/utils/redaction.mjs +20 -0
- package/dist/mcp-server/utils/redaction.mjs.map +1 -0
- package/dist/mcp-server/utils/response.cjs +49 -0
- package/dist/mcp-server/utils/response.cjs.map +1 -0
- package/dist/mcp-server/utils/response.d.cts +22 -0
- package/dist/mcp-server/utils/response.d.cts.map +1 -0
- package/dist/mcp-server/utils/response.d.mts +22 -0
- package/dist/mcp-server/utils/response.d.mts.map +1 -0
- package/dist/mcp-server/utils/response.mjs +45 -0
- package/dist/mcp-server/utils/response.mjs.map +1 -0
- package/dist/mcp-server/utils/targets.cjs +32 -0
- package/dist/mcp-server/utils/targets.cjs.map +1 -0
- package/dist/mcp-server/utils/targets.d.cts +25 -0
- package/dist/mcp-server/utils/targets.d.cts.map +1 -0
- package/dist/mcp-server/utils/targets.d.mts +25 -0
- package/dist/mcp-server/utils/targets.d.mts.map +1 -0
- package/dist/mcp-server/utils/targets.mjs +29 -0
- package/dist/mcp-server/utils/targets.mjs.map +1 -0
- package/dist/mcp-server/utils/time.cjs +39 -0
- package/dist/mcp-server/utils/time.cjs.map +1 -0
- package/dist/mcp-server/utils/time.d.cts +15 -0
- package/dist/mcp-server/utils/time.d.cts.map +1 -0
- package/dist/mcp-server/utils/time.d.mts +15 -0
- package/dist/mcp-server/utils/time.d.mts.map +1 -0
- package/dist/mcp-server/utils/time.mjs +35 -0
- package/dist/mcp-server/utils/time.mjs.map +1 -0
- package/dist/mcp-server/utils/type-guards.cjs +42 -0
- package/dist/mcp-server/utils/type-guards.cjs.map +1 -0
- package/dist/mcp-server/utils/type-guards.d.cts +30 -0
- package/dist/mcp-server/utils/type-guards.d.cts.map +1 -0
- package/dist/mcp-server/utils/type-guards.d.mts +30 -0
- package/dist/mcp-server/utils/type-guards.d.mts.map +1 -0
- package/dist/mcp-server/utils/type-guards.mjs +38 -0
- package/dist/mcp-server/utils/type-guards.mjs.map +1 -0
- package/dist/utils/fetch.cjs +36 -0
- package/dist/utils/fetch.cjs.map +1 -0
- package/dist/utils/fetch.d.cts +20 -0
- package/dist/utils/fetch.d.cts.map +1 -0
- package/dist/utils/fetch.d.mts +20 -0
- package/dist/utils/fetch.d.mts.map +1 -0
- package/dist/utils/fetch.mjs +33 -0
- package/dist/utils/fetch.mjs.map +1 -0
- package/dist/utils/index.cjs +11 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +6 -0
- package/dist/utils/index.d.cts.map +1 -0
- package/dist/utils/index.d.mts +6 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +6 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/service-readiness.cjs +75 -0
- package/dist/utils/service-readiness.cjs.map +1 -0
- package/dist/utils/service-readiness.d.cts +61 -0
- package/dist/utils/service-readiness.d.cts.map +1 -0
- package/dist/utils/service-readiness.d.mts +61 -0
- package/dist/utils/service-readiness.d.mts.map +1 -0
- package/dist/utils/service-readiness.mjs +72 -0
- package/dist/utils/service-readiness.mjs.map +1 -0
- package/package.json +119 -0
package/README.md
ADDED
|
@@ -0,0 +1,1459 @@
|
|
|
1
|
+
# @metamask/client-mcp-core
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for MetaMask Extension visual testing with LLM agents.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides the core MCP server infrastructure for enabling LLM agents to interact with the MetaMask browser extension through Playwright.
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- **Node.js ^20 || ^22 || >=24** (required)
|
|
12
|
+
- **TypeScript >=5.0** (for consumer type definitions)
|
|
13
|
+
- Playwright `^1.49.0` (peer dependency)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
yarn add @metamask/client-mcp-core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Architecture
|
|
22
|
+
|
|
23
|
+
### High-Level Overview
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
27
|
+
│ LLM Agent │
|
|
28
|
+
│ (Claude, GPT, etc.) │
|
|
29
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
30
|
+
│
|
|
31
|
+
│ MCP Protocol (stdio)
|
|
32
|
+
▼
|
|
33
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
34
|
+
│ @metamask/client-mcp-core │
|
|
35
|
+
│ │
|
|
36
|
+
│ Core MCP Server + Generic Tools │
|
|
37
|
+
│ - Session management │
|
|
38
|
+
│ - Element interaction (click, type, wait) │
|
|
39
|
+
│ - Discovery (testIds, accessibility tree) │
|
|
40
|
+
│ - Screenshots │
|
|
41
|
+
│ - Knowledge store (cross-session learning) │
|
|
42
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
43
|
+
│
|
|
44
|
+
│ Capability Injection
|
|
45
|
+
▼
|
|
46
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
47
|
+
│ MetaMask Extension Provider │
|
|
48
|
+
│ │
|
|
49
|
+
│ - Build capability (yarn build:test) │
|
|
50
|
+
│ - Fixture/state management │
|
|
51
|
+
│ - Anvil blockchain integration │
|
|
52
|
+
│ - Contract seeding │
|
|
53
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
54
|
+
│
|
|
55
|
+
│ Playwright
|
|
56
|
+
▼
|
|
57
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
58
|
+
│ Headed Chrome Browser │
|
|
59
|
+
│ + MetaMask Extension │
|
|
60
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Detailed Architecture
|
|
64
|
+
|
|
65
|
+
The package follows a **capability-based dependency injection** pattern that separates concerns between:
|
|
66
|
+
|
|
67
|
+
1. **Core MCP Server** - Protocol handling, tool routing, and generic browser interactions
|
|
68
|
+
2. **Session Manager Interface** - Abstract contract for extension-specific session management
|
|
69
|
+
3. **Capabilities** - Optional features injected by consumer implementations
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
73
|
+
│ createMcpServer() │
|
|
74
|
+
│ │
|
|
75
|
+
│ ┌─────────────────────┐ ┌─────────────────────────────────────┐ │
|
|
76
|
+
│ │ Tool Definitions │───▶│ Tool Handlers │ │
|
|
77
|
+
│ │ (mm_click, etc.) │ │ (registry.ts + individual tools) │ │
|
|
78
|
+
│ └─────────────────────┘ └──────────────┬──────────────────────┘ │
|
|
79
|
+
│ │ │
|
|
80
|
+
│ ▼ │
|
|
81
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
82
|
+
│ │ ISessionManager Interface │ │
|
|
83
|
+
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ │
|
|
84
|
+
│ │ │ Page Mgmt │ │ Navigation │ │ Screenshots │ │ A11y Refs │ │ │
|
|
85
|
+
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │ │
|
|
86
|
+
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
|
|
87
|
+
│ │ │ Optional Capabilities │ │ │
|
|
88
|
+
│ │ │ • BuildCapability • FixtureCapability │ │ │
|
|
89
|
+
│ │ │ • ChainCapability • ContractSeedingCapability │ │ │
|
|
90
|
+
│ │ │ • StateSnapshotCapability │ │ │
|
|
91
|
+
│ │ └──────────────────────────────────────────────────────────┘ │ │
|
|
92
|
+
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
93
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
94
|
+
│
|
|
95
|
+
│ setSessionManager()
|
|
96
|
+
▼
|
|
97
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
98
|
+
│ Consumer Implementation (e.g., MetaMask) │
|
|
99
|
+
│ │
|
|
100
|
+
│ class MetaMaskSessionManager implements ISessionManager { │
|
|
101
|
+
│ // Browser context, page tracking, extension-specific logic │
|
|
102
|
+
│ // Capability implementations for build, fixtures, chain, etc. │
|
|
103
|
+
│ } │
|
|
104
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Core Components
|
|
108
|
+
|
|
109
|
+
| Component | Description |
|
|
110
|
+
| --------------------- | -------------------------------------------------------------- |
|
|
111
|
+
| `createMcpServer()` | Factory function that creates the MCP server instance |
|
|
112
|
+
| `ISessionManager` | Interface that consumers must implement for session management |
|
|
113
|
+
| `setSessionManager()` | Injects the consumer's session manager into the core |
|
|
114
|
+
| `WorkflowContext` | Container for browser capability and optional capabilities |
|
|
115
|
+
| `EnvironmentConfig` | Configuration discriminated by `'e2e'` or `'prod'` mode |
|
|
116
|
+
|
|
117
|
+
### Capability System
|
|
118
|
+
|
|
119
|
+
The package defines several capabilities that consumers can provide.
|
|
120
|
+
|
|
121
|
+
#### BuildCapability (Optional)
|
|
122
|
+
|
|
123
|
+
Enables the `mm_build` tool. Implement this to allow LLM agents to build the extension from source.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
type BuildCapability = {
|
|
127
|
+
// Build the extension (e.g., yarn build:test)
|
|
128
|
+
build(options?: BuildOptions): Promise<BuildResult>;
|
|
129
|
+
|
|
130
|
+
// Get path to built extension directory
|
|
131
|
+
getExtensionPath(): string;
|
|
132
|
+
|
|
133
|
+
// Check if extension is already built
|
|
134
|
+
isBuilt(): Promise<boolean>;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
type BuildOptions = {
|
|
138
|
+
buildType?: string; // e.g., "build:test"
|
|
139
|
+
force?: boolean; // Force rebuild even if exists
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
type BuildResult = {
|
|
143
|
+
success: boolean;
|
|
144
|
+
extensionPath: string;
|
|
145
|
+
durationMs: number;
|
|
146
|
+
error?: string;
|
|
147
|
+
};
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
#### FixtureCapability (Optional)
|
|
153
|
+
|
|
154
|
+
Enables wallet state management through fixtures. Essential for E2E testing where you need reproducible wallet states.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
type FixtureCapability = {
|
|
158
|
+
// Start fixture server with given wallet state
|
|
159
|
+
start(state: WalletState): Promise<void>;
|
|
160
|
+
|
|
161
|
+
// Stop fixture server
|
|
162
|
+
stop(): Promise<void>;
|
|
163
|
+
|
|
164
|
+
// Get default pre-onboarded wallet state (25 ETH, unlocked)
|
|
165
|
+
getDefaultState(): WalletState;
|
|
166
|
+
|
|
167
|
+
// Get fresh onboarding state (no wallet configured)
|
|
168
|
+
getOnboardingState(): WalletState;
|
|
169
|
+
|
|
170
|
+
// Resolve a named preset to fixture data
|
|
171
|
+
resolvePreset(presetName: string): WalletState;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
type WalletState = {
|
|
175
|
+
data: Record<string, unknown>; // Extension storage state
|
|
176
|
+
meta?: { version: number };
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
#### ChainCapability (Optional)
|
|
183
|
+
|
|
184
|
+
Manages local blockchain (Anvil) for E2E testing. Required for contract interactions.
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
type ChainCapability = {
|
|
188
|
+
// Start the local Anvil node
|
|
189
|
+
start(): Promise<void>;
|
|
190
|
+
|
|
191
|
+
// Stop the Anvil node
|
|
192
|
+
stop(): Promise<void>;
|
|
193
|
+
|
|
194
|
+
// Check if Anvil is running
|
|
195
|
+
isRunning(): boolean;
|
|
196
|
+
|
|
197
|
+
// Set the port for the Anvil node
|
|
198
|
+
setPort(port: number): void;
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
#### ContractSeedingCapability (Optional)
|
|
205
|
+
|
|
206
|
+
Enables smart contract deployment tools (`mm_seed_contract`, `mm_seed_contracts`, etc.).
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
type ContractSeedingCapability = {
|
|
210
|
+
// Deploy a single contract
|
|
211
|
+
deployContract(
|
|
212
|
+
name: string,
|
|
213
|
+
options?: DeployOptions,
|
|
214
|
+
): Promise<ContractDeployment>;
|
|
215
|
+
|
|
216
|
+
// Deploy multiple contracts in sequence
|
|
217
|
+
deployContracts(
|
|
218
|
+
names: string[],
|
|
219
|
+
options?: DeployOptions,
|
|
220
|
+
): Promise<{
|
|
221
|
+
deployed: ContractDeployment[];
|
|
222
|
+
failed: { name: string; error: string }[];
|
|
223
|
+
}>;
|
|
224
|
+
|
|
225
|
+
// Get deployed contract address by name
|
|
226
|
+
getContractAddress(name: string): string | null;
|
|
227
|
+
|
|
228
|
+
// List all deployed contracts in this session
|
|
229
|
+
listDeployedContracts(): ContractInfo[];
|
|
230
|
+
|
|
231
|
+
// Get available contract names
|
|
232
|
+
getAvailableContracts(): string[];
|
|
233
|
+
|
|
234
|
+
// Clear the deployment registry
|
|
235
|
+
clearRegistry(): void;
|
|
236
|
+
|
|
237
|
+
// Initialize the capability (called during session launch)
|
|
238
|
+
initialize(): void;
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
type DeployOptions = {
|
|
242
|
+
hardfork?: string; // EVM hardfork (default: "prague")
|
|
243
|
+
deployerOptions?: {
|
|
244
|
+
fromAddress?: string; // Impersonate address
|
|
245
|
+
fromPrivateKey?: string; // Deploy from specific key
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
#### StateSnapshotCapability (Optional)
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
type StateSnapshotCapability = {
|
|
256
|
+
// Get detailed state snapshot
|
|
257
|
+
getState(page: Page, options: StateOptions): Promise<StateSnapshot>;
|
|
258
|
+
|
|
259
|
+
// Detect current screen from page content
|
|
260
|
+
detectCurrentScreen(page: Page): Promise<string>;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
type StateOptions = {
|
|
264
|
+
extensionId?: string;
|
|
265
|
+
chainId?: number;
|
|
266
|
+
};
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
#### MockServerCapability (Optional)
|
|
272
|
+
|
|
273
|
+
Enables mock server for API testing scenarios.
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
type MockServerCapability = {
|
|
277
|
+
// Start the mock server
|
|
278
|
+
start(): Promise<void>;
|
|
279
|
+
|
|
280
|
+
// Stop the mock server
|
|
281
|
+
stop(): Promise<void>;
|
|
282
|
+
|
|
283
|
+
// Check if mock server is running
|
|
284
|
+
isRunning(): boolean;
|
|
285
|
+
|
|
286
|
+
// Get the server instance
|
|
287
|
+
getServer(): unknown;
|
|
288
|
+
|
|
289
|
+
// Get the port the server is running on
|
|
290
|
+
getPort(): number;
|
|
291
|
+
};
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Client Integration
|
|
295
|
+
|
|
296
|
+
### How to Consume the Package
|
|
297
|
+
|
|
298
|
+
Consumers must:
|
|
299
|
+
|
|
300
|
+
1. **Implement `ISessionManager`** - The core interface for session management
|
|
301
|
+
2. **Inject the session manager** - Call `setSessionManager()` before starting the server
|
|
302
|
+
3. **Start the MCP server** - Call `server.start()`
|
|
303
|
+
|
|
304
|
+
### McpServerConfig
|
|
305
|
+
|
|
306
|
+
The `createMcpServer()` function accepts a configuration object:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
export type McpServerConfig = {
|
|
310
|
+
name: string;
|
|
311
|
+
version: string;
|
|
312
|
+
onCleanup?: () => Promise<void>;
|
|
313
|
+
logger?: (message: string) => void;
|
|
314
|
+
};
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Minimal Integration Example
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import {
|
|
321
|
+
createMcpServer,
|
|
322
|
+
setSessionManager,
|
|
323
|
+
ISessionManager,
|
|
324
|
+
type McpServerConfig,
|
|
325
|
+
} from '@metamask/client-mcp-core';
|
|
326
|
+
|
|
327
|
+
// 1. Implement the ISessionManager interface
|
|
328
|
+
class MyExtensionSessionManager implements ISessionManager {
|
|
329
|
+
// ... implement all required methods
|
|
330
|
+
// See ISessionManager interface for full contract
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// 2. Create and inject your session manager
|
|
334
|
+
const sessionManager = new MyExtensionSessionManager();
|
|
335
|
+
setSessionManager(sessionManager);
|
|
336
|
+
|
|
337
|
+
// 3. Create and start the MCP server
|
|
338
|
+
const config: McpServerConfig = {
|
|
339
|
+
name: 'my-extension-mcp',
|
|
340
|
+
version: '1.0.0',
|
|
341
|
+
onCleanup: async () => {
|
|
342
|
+
// Optional cleanup logic
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const server = createMcpServer(config);
|
|
347
|
+
await server.start();
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Full Integration Example
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import {
|
|
354
|
+
createMcpServer,
|
|
355
|
+
setSessionManager,
|
|
356
|
+
ISessionManager,
|
|
357
|
+
SessionLaunchInput,
|
|
358
|
+
SessionLaunchResult,
|
|
359
|
+
TrackedPage,
|
|
360
|
+
type ExtensionState,
|
|
361
|
+
type BuildCapability,
|
|
362
|
+
type FixtureCapability,
|
|
363
|
+
type ChainCapability,
|
|
364
|
+
type ContractSeedingCapability,
|
|
365
|
+
type EnvironmentMode,
|
|
366
|
+
} from '@metamask/client-mcp-core';
|
|
367
|
+
import type { Page, BrowserContext } from '@playwright/test';
|
|
368
|
+
|
|
369
|
+
class MetaMaskSessionManager implements ISessionManager {
|
|
370
|
+
private context?: BrowserContext;
|
|
371
|
+
private activePage?: Page;
|
|
372
|
+
private extensionId?: string;
|
|
373
|
+
private sessionId?: string;
|
|
374
|
+
private refMap = new Map<string, string>();
|
|
375
|
+
|
|
376
|
+
// Capabilities (inject via constructor or lazy-load)
|
|
377
|
+
private buildCapability?: BuildCapability;
|
|
378
|
+
private fixtureCapability?: FixtureCapability;
|
|
379
|
+
private chainCapability?: ChainCapability;
|
|
380
|
+
private contractSeedingCapability?: ContractSeedingCapability;
|
|
381
|
+
|
|
382
|
+
// Session Lifecycle
|
|
383
|
+
hasActiveSession(): boolean {
|
|
384
|
+
return this.context !== undefined;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
getSessionId(): string | undefined {
|
|
388
|
+
return this.sessionId;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
async launch(input: SessionLaunchInput): Promise<SessionLaunchResult> {
|
|
392
|
+
// 1. Start local chain if needed
|
|
393
|
+
if (this.chainCapability) {
|
|
394
|
+
await this.chainCapability.start();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// 2. Start fixture server if needed
|
|
398
|
+
if (this.fixtureCapability && input.stateMode !== 'onboarding') {
|
|
399
|
+
const fixture = input.fixture ?? this.fixtureCapability.getDefaultState();
|
|
400
|
+
await this.fixtureCapability.start(fixture);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// 3. Launch browser with extension
|
|
404
|
+
// ... Playwright browser launch logic
|
|
405
|
+
|
|
406
|
+
// 4. Return session info
|
|
407
|
+
return {
|
|
408
|
+
sessionId: this.sessionId!,
|
|
409
|
+
extensionId: this.extensionId!,
|
|
410
|
+
state: await this.getExtensionState(),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async cleanup(): Promise<boolean> {
|
|
415
|
+
if (!this.hasActiveSession()) return false;
|
|
416
|
+
|
|
417
|
+
// Close browser, stop services
|
|
418
|
+
await this.context?.close();
|
|
419
|
+
await this.chainCapability?.stop();
|
|
420
|
+
await this.fixtureCapability?.stop();
|
|
421
|
+
|
|
422
|
+
this.context = undefined;
|
|
423
|
+
this.activePage = undefined;
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Page Management
|
|
428
|
+
getPage(): Page {
|
|
429
|
+
if (!this.activePage) throw new Error('No active session');
|
|
430
|
+
return this.activePage;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
setActivePage(page: Page): void {
|
|
434
|
+
this.activePage = page;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
getTrackedPages(): TrackedPage[] {
|
|
438
|
+
// Return all tracked pages with roles
|
|
439
|
+
return [];
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
getContext(): BrowserContext {
|
|
443
|
+
if (!this.context) throw new Error('No active session');
|
|
444
|
+
return this.context;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Extension State
|
|
448
|
+
async getExtensionState(): Promise<ExtensionState> {
|
|
449
|
+
// Query extension for current state
|
|
450
|
+
return {
|
|
451
|
+
isLoaded: true,
|
|
452
|
+
currentUrl: this.activePage?.url() ?? '',
|
|
453
|
+
extensionId: this.extensionId ?? '',
|
|
454
|
+
isUnlocked: false,
|
|
455
|
+
currentScreen: 'unknown',
|
|
456
|
+
accountAddress: null,
|
|
457
|
+
networkName: null,
|
|
458
|
+
chainId: null,
|
|
459
|
+
balance: null,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// A11y Reference Map
|
|
464
|
+
setRefMap(map: Map<string, string>): void {
|
|
465
|
+
this.refMap = map;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
getRefMap(): Map<string, string> {
|
|
469
|
+
return this.refMap;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
clearRefMap(): void {
|
|
473
|
+
this.refMap.clear();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
resolveA11yRef(ref: string): string | undefined {
|
|
477
|
+
return this.refMap.get(ref);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Navigation
|
|
481
|
+
async navigateToHome(): Promise<void> {
|
|
482
|
+
// Navigate to extension home page
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async navigateToSettings(): Promise<void> {
|
|
486
|
+
// Navigate to extension settings page
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
async navigateToUrl(url: string): Promise<Page> {
|
|
490
|
+
// Open URL in new tab and return the page
|
|
491
|
+
return this.activePage!;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
async navigateToNotification(): Promise<Page> {
|
|
495
|
+
// Navigate to notification page
|
|
496
|
+
return this.activePage!;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
async waitForNotificationPage(timeoutMs: number): Promise<Page> {
|
|
500
|
+
// Wait for notification popup to appear
|
|
501
|
+
return this.activePage!;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Screenshots
|
|
505
|
+
async screenshot(options: { name: string; fullPage?: boolean }) {
|
|
506
|
+
// ... screenshot logic
|
|
507
|
+
return { path: '', base64: '', width: 0, height: 0 };
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Capabilities
|
|
511
|
+
getBuildCapability() {
|
|
512
|
+
return this.buildCapability;
|
|
513
|
+
}
|
|
514
|
+
getFixtureCapability() {
|
|
515
|
+
return this.fixtureCapability;
|
|
516
|
+
}
|
|
517
|
+
getChainCapability() {
|
|
518
|
+
return this.chainCapability;
|
|
519
|
+
}
|
|
520
|
+
getContractSeedingCapability() {
|
|
521
|
+
return this.contractSeedingCapability;
|
|
522
|
+
}
|
|
523
|
+
getStateSnapshotCapability() {
|
|
524
|
+
return undefined;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Environment
|
|
528
|
+
getEnvironmentMode(): EnvironmentMode {
|
|
529
|
+
return 'e2e';
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Required by interface but implementation-specific
|
|
533
|
+
classifyPageRole(
|
|
534
|
+
page: Page,
|
|
535
|
+
): 'extension' | 'notification' | 'dapp' | 'other' {
|
|
536
|
+
return 'extension';
|
|
537
|
+
}
|
|
538
|
+
getSessionState() {
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
541
|
+
getSessionMetadata() {
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Context Management
|
|
546
|
+
setContext(context: 'e2e' | 'prod'): void {
|
|
547
|
+
if (this.hasActiveSession()) {
|
|
548
|
+
throw new Error('Cannot switch context while session is active');
|
|
549
|
+
}
|
|
550
|
+
// Switch environment context
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
getContextInfo() {
|
|
554
|
+
return {
|
|
555
|
+
currentContext: this.getEnvironmentMode(),
|
|
556
|
+
hasActiveSession: this.hasActiveSession(),
|
|
557
|
+
sessionId: this.sessionId ?? null,
|
|
558
|
+
capabilities: {
|
|
559
|
+
available: [
|
|
560
|
+
this.buildCapability && 'build',
|
|
561
|
+
this.fixtureCapability && 'fixture',
|
|
562
|
+
this.chainCapability && 'chain',
|
|
563
|
+
this.contractSeedingCapability && 'contractSeeding',
|
|
564
|
+
].filter(Boolean) as string[],
|
|
565
|
+
},
|
|
566
|
+
canSwitchContext: !this.hasActiveSession(),
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Bootstrap the server
|
|
572
|
+
async function main() {
|
|
573
|
+
const sessionManager = new MetaMaskSessionManager();
|
|
574
|
+
setSessionManager(sessionManager);
|
|
575
|
+
|
|
576
|
+
const server = createMcpServer({
|
|
577
|
+
name: 'metamask-mcp',
|
|
578
|
+
version: '1.0.0',
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
await server.start();
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
main().catch(console.error);
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Environment Configuration
|
|
588
|
+
|
|
589
|
+
The package supports two environment modes:
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
// E2E Testing Environment
|
|
593
|
+
const e2eConfig: E2EEnvironmentConfig = {
|
|
594
|
+
environment: 'e2e',
|
|
595
|
+
extensionName: 'MetaMask',
|
|
596
|
+
defaultPassword: 'password123',
|
|
597
|
+
toolPrefix: 'mm',
|
|
598
|
+
artifactsDir: './test-artifacts',
|
|
599
|
+
defaultChainId: 1337,
|
|
600
|
+
ports: {
|
|
601
|
+
anvil: 8545,
|
|
602
|
+
fixtureServer: 12345,
|
|
603
|
+
},
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// Production-like Environment
|
|
607
|
+
const prodConfig: ProdEnvironmentConfig = {
|
|
608
|
+
environment: 'prod',
|
|
609
|
+
extensionName: 'MetaMask',
|
|
610
|
+
toolPrefix: 'mm',
|
|
611
|
+
};
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Custom Tool Definitions
|
|
615
|
+
|
|
616
|
+
The package provides a fixed set of tools prefixed with `mm_`. Custom tool injection is currently not supported. You can inspect the available tool definitions using `getToolDefinitions()`:
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
import { getToolDefinitions } from '@metamask/client-mcp-core';
|
|
620
|
+
|
|
621
|
+
const tools = getToolDefinitions();
|
|
622
|
+
console.log(`Available tools: ${tools.map((t) => t.name).join(', ')}`);
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### Registering Custom Tool Handlers
|
|
626
|
+
|
|
627
|
+
Custom tool handlers are not supported. The server uses a fixed set of handlers for the provided tools.
|
|
628
|
+
|
|
629
|
+
## Available Tools
|
|
630
|
+
|
|
631
|
+
All tools are prefixed with `mm_` and return a standardized response format:
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
type ToolResponse<Result> =
|
|
635
|
+
| {
|
|
636
|
+
ok: true;
|
|
637
|
+
meta: {
|
|
638
|
+
timestamp: string; // ISO timestamp
|
|
639
|
+
sessionId?: string; // Current session ID
|
|
640
|
+
durationMs: number; // Operation duration
|
|
641
|
+
};
|
|
642
|
+
result: Result; // Success payload
|
|
643
|
+
}
|
|
644
|
+
| {
|
|
645
|
+
ok: false;
|
|
646
|
+
meta: {
|
|
647
|
+
timestamp: string;
|
|
648
|
+
sessionId?: string;
|
|
649
|
+
durationMs: number;
|
|
650
|
+
};
|
|
651
|
+
error: {
|
|
652
|
+
code: string;
|
|
653
|
+
message: string;
|
|
654
|
+
details?: Record<string, unknown>;
|
|
655
|
+
};
|
|
656
|
+
};
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
### Session Management Tools
|
|
662
|
+
|
|
663
|
+
#### `mm_build`
|
|
664
|
+
|
|
665
|
+
Build the extension from source. Requires `BuildCapability`.
|
|
666
|
+
|
|
667
|
+
**Input:**
|
|
668
|
+
| Parameter | Type | Default | Description |
|
|
669
|
+
|-----------|------|---------|-------------|
|
|
670
|
+
| `buildType` | `"build:test"` | `"build:test"` | Build script to run |
|
|
671
|
+
| `force` | `boolean` | `false` | Force rebuild even if build exists |
|
|
672
|
+
|
|
673
|
+
**Output:**
|
|
674
|
+
|
|
675
|
+
```typescript
|
|
676
|
+
{
|
|
677
|
+
buildType: 'build:test';
|
|
678
|
+
extensionPathResolved: string; // Absolute path to built extension
|
|
679
|
+
}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
**Example:**
|
|
683
|
+
|
|
684
|
+
```json
|
|
685
|
+
{ "buildType": "build:test", "force": true }
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
#### `mm_launch`
|
|
691
|
+
|
|
692
|
+
Launch a headed Chrome browser with the extension loaded. This is typically the first tool called.
|
|
693
|
+
|
|
694
|
+
**Input:**
|
|
695
|
+
| Parameter | Type | Default | Description |
|
|
696
|
+
|-----------|------|---------|-------------|
|
|
697
|
+
| `autoBuild` | `boolean` | `true` | Auto-build if extension not found |
|
|
698
|
+
| `stateMode` | `"default" \| "onboarding" \| "custom"` | `"default"` | Wallet initialization mode |
|
|
699
|
+
| `fixturePreset` | `string` | - | Named preset when `stateMode="custom"` |
|
|
700
|
+
| `fixture` | `object` | - | Direct fixture object when `stateMode="custom"` |
|
|
701
|
+
| `ports.anvil` | `number` | `8545` | Anvil RPC port |
|
|
702
|
+
| `ports.fixtureServer` | `number` | `12345` | Fixture server port |
|
|
703
|
+
| `slowMo` | `number` | `0` | Slow down actions (ms) for debugging |
|
|
704
|
+
| `extensionPath` | `string` | - | Custom extension directory path |
|
|
705
|
+
| `goal` | `string` | - | Session goal for knowledge store |
|
|
706
|
+
| `flowTags` | `string[]` | - | Flow categorization tags |
|
|
707
|
+
| `tags` | `string[]` | - | Free-form tags |
|
|
708
|
+
| `seedContracts` | `string[]` | - | Contracts to deploy on launch |
|
|
709
|
+
|
|
710
|
+
**State Modes:**
|
|
711
|
+
|
|
712
|
+
- `default` - Pre-onboarded wallet with 25 ETH, ready to use
|
|
713
|
+
- `onboarding` - Fresh state, requires wallet setup flow
|
|
714
|
+
- `custom` - Use provided fixture or preset
|
|
715
|
+
|
|
716
|
+
**Output:**
|
|
717
|
+
|
|
718
|
+
```typescript
|
|
719
|
+
{
|
|
720
|
+
sessionId: string; // Unique session identifier
|
|
721
|
+
extensionId: string; // Extension's Chrome ID
|
|
722
|
+
state: ExtensionState; // Initial extension state
|
|
723
|
+
prerequisites?: [{ // Steps taken before launch
|
|
724
|
+
step: string;
|
|
725
|
+
description: string;
|
|
726
|
+
}];
|
|
727
|
+
}
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
**Example:**
|
|
731
|
+
|
|
732
|
+
```json
|
|
733
|
+
{
|
|
734
|
+
"stateMode": "default",
|
|
735
|
+
"goal": "Test send flow",
|
|
736
|
+
"flowTags": ["send"],
|
|
737
|
+
"seedContracts": ["hst"]
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
---
|
|
742
|
+
|
|
743
|
+
#### `mm_cleanup`
|
|
744
|
+
|
|
745
|
+
Stop the browser and all services (Anvil, fixture server). Always call when done.
|
|
746
|
+
|
|
747
|
+
**Input:**
|
|
748
|
+
| Parameter | Type | Default | Description |
|
|
749
|
+
|-----------|------|---------|-------------|
|
|
750
|
+
| `sessionId` | `string` | - | Optional session ID to clean up |
|
|
751
|
+
|
|
752
|
+
**Output:**
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
{
|
|
756
|
+
cleanedUp: boolean; // Whether cleanup was performed
|
|
757
|
+
}
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
762
|
+
### Discovery Tools
|
|
763
|
+
|
|
764
|
+
#### `mm_get_state`
|
|
765
|
+
|
|
766
|
+
Get current extension state including screen, balance, network, and account.
|
|
767
|
+
|
|
768
|
+
**Input:** None
|
|
769
|
+
|
|
770
|
+
**Output:**
|
|
771
|
+
|
|
772
|
+
```typescript
|
|
773
|
+
{
|
|
774
|
+
state: {
|
|
775
|
+
isLoaded: boolean;
|
|
776
|
+
currentUrl: string;
|
|
777
|
+
extensionId: string;
|
|
778
|
+
isUnlocked: boolean;
|
|
779
|
+
currentScreen: ScreenName;
|
|
780
|
+
accountAddress: string | null;
|
|
781
|
+
networkName: string | null;
|
|
782
|
+
chainId: number | null;
|
|
783
|
+
balance: string | null;
|
|
784
|
+
};
|
|
785
|
+
tabs?: {
|
|
786
|
+
active: { role: TabRole; url: string };
|
|
787
|
+
tracked: { role: TabRole; url: string }[];
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
#### `mm_list_testids`
|
|
795
|
+
|
|
796
|
+
List all visible `data-testid` attributes on the current page. Use to discover interaction targets.
|
|
797
|
+
|
|
798
|
+
**Input:**
|
|
799
|
+
| Parameter | Type | Default | Description |
|
|
800
|
+
|-----------|------|---------|-------------|
|
|
801
|
+
| `limit` | `number` | `150` | Maximum items to return (1-500) |
|
|
802
|
+
|
|
803
|
+
**Output:**
|
|
804
|
+
|
|
805
|
+
```typescript
|
|
806
|
+
{
|
|
807
|
+
items: [{
|
|
808
|
+
testId: string; // The data-testid value
|
|
809
|
+
tag: string; // HTML tag (button, input, div, etc.)
|
|
810
|
+
text?: string; // Visible text content
|
|
811
|
+
visible: boolean; // Whether element is visible
|
|
812
|
+
}];
|
|
813
|
+
}
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
**Example Output:**
|
|
817
|
+
|
|
818
|
+
```json
|
|
819
|
+
{
|
|
820
|
+
"items": [
|
|
821
|
+
{
|
|
822
|
+
"testId": "account-menu-icon",
|
|
823
|
+
"tag": "button",
|
|
824
|
+
"text": "",
|
|
825
|
+
"visible": true
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
"testId": "eth-overview-send",
|
|
829
|
+
"tag": "button",
|
|
830
|
+
"text": "Send",
|
|
831
|
+
"visible": true
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
"testId": "token-balance",
|
|
835
|
+
"tag": "span",
|
|
836
|
+
"text": "25 ETH",
|
|
837
|
+
"visible": true
|
|
838
|
+
}
|
|
839
|
+
]
|
|
840
|
+
}
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
---
|
|
844
|
+
|
|
845
|
+
#### `mm_accessibility_snapshot`
|
|
846
|
+
|
|
847
|
+
Get a trimmed accessibility tree with deterministic refs (e1, e2, ...). Refs can be used with `mm_click` and `mm_type`.
|
|
848
|
+
|
|
849
|
+
**Input:**
|
|
850
|
+
| Parameter | Type | Default | Description |
|
|
851
|
+
|-----------|------|---------|-------------|
|
|
852
|
+
| `rootSelector` | `string` | - | CSS selector to scope the snapshot |
|
|
853
|
+
|
|
854
|
+
**Included Roles:**
|
|
855
|
+
|
|
856
|
+
- **Actionable:** button, link, checkbox, radio, switch, textbox, combobox, menuitem
|
|
857
|
+
- **Important:** dialog, alert, status, heading
|
|
858
|
+
|
|
859
|
+
**Output:**
|
|
860
|
+
|
|
861
|
+
```typescript
|
|
862
|
+
{
|
|
863
|
+
nodes: [{
|
|
864
|
+
ref: string; // Deterministic ref (e1, e2, e3, ...)
|
|
865
|
+
role: string; // ARIA role
|
|
866
|
+
name: string; // Accessible name
|
|
867
|
+
disabled?: boolean;
|
|
868
|
+
checked?: boolean;
|
|
869
|
+
expanded?: boolean;
|
|
870
|
+
path: string[]; // Ancestor path for context
|
|
871
|
+
}];
|
|
872
|
+
}
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
**Example Output:**
|
|
876
|
+
|
|
877
|
+
```json
|
|
878
|
+
{
|
|
879
|
+
"nodes": [
|
|
880
|
+
{ "ref": "e1", "role": "button", "name": "Send", "path": ["main", "div"] },
|
|
881
|
+
{ "ref": "e2", "role": "button", "name": "Swap", "path": ["main", "div"] },
|
|
882
|
+
{ "ref": "e3", "role": "textbox", "name": "Amount", "path": ["form"] }
|
|
883
|
+
]
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
---
|
|
888
|
+
|
|
889
|
+
#### `mm_describe_screen`
|
|
890
|
+
|
|
891
|
+
Comprehensive screen state combining extension state, testIds, and accessibility snapshot. Optionally includes screenshot.
|
|
892
|
+
|
|
893
|
+
**Input:**
|
|
894
|
+
| Parameter | Type | Default | Description |
|
|
895
|
+
|-----------|------|---------|-------------|
|
|
896
|
+
| `includeScreenshot` | `boolean` | `false` | Capture screenshot |
|
|
897
|
+
| `screenshotName` | `string` | - | Screenshot filename |
|
|
898
|
+
| `includeScreenshotBase64` | `boolean` | `false` | Include base64 in response |
|
|
899
|
+
|
|
900
|
+
**Output:**
|
|
901
|
+
|
|
902
|
+
```typescript
|
|
903
|
+
{
|
|
904
|
+
state: ExtensionState;
|
|
905
|
+
testIds: { items: TestIdItem[] };
|
|
906
|
+
a11y: { nodes: A11yNodeTrimmed[] };
|
|
907
|
+
screenshot: {
|
|
908
|
+
path: string;
|
|
909
|
+
width: number;
|
|
910
|
+
height: number;
|
|
911
|
+
base64?: string;
|
|
912
|
+
} | null;
|
|
913
|
+
priorKnowledge?: PriorKnowledgeV1; // Past session hints
|
|
914
|
+
}
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
### Interaction Tools
|
|
920
|
+
|
|
921
|
+
#### `mm_click`
|
|
922
|
+
|
|
923
|
+
Click an element. Specify exactly ONE of: `a11yRef`, `testId`, or `selector`.
|
|
924
|
+
|
|
925
|
+
**Input:**
|
|
926
|
+
| Parameter | Type | Default | Description |
|
|
927
|
+
|-----------|------|---------|-------------|
|
|
928
|
+
| `a11yRef` | `string` | - | Accessibility ref from `mm_accessibility_snapshot` (e.g., "e5") |
|
|
929
|
+
| `testId` | `string` | - | `data-testid` attribute value |
|
|
930
|
+
| `selector` | `string` | - | CSS selector |
|
|
931
|
+
| `timeoutMs` | `number` | `15000` | Max wait time (0-60000) |
|
|
932
|
+
|
|
933
|
+
**Output:**
|
|
934
|
+
|
|
935
|
+
```typescript
|
|
936
|
+
{
|
|
937
|
+
clicked: boolean;
|
|
938
|
+
target: string; // Resolved selector
|
|
939
|
+
pageClosedAfterClick?: boolean; // True if click caused page close
|
|
940
|
+
}
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
**Examples:**
|
|
944
|
+
|
|
945
|
+
```json
|
|
946
|
+
{ "a11yRef": "e5" }
|
|
947
|
+
{ "testId": "confirm-btn" }
|
|
948
|
+
{ "selector": "button.primary" }
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
---
|
|
952
|
+
|
|
953
|
+
#### `mm_type`
|
|
954
|
+
|
|
955
|
+
Type text into an input element. Specify exactly ONE of: `a11yRef`, `testId`, or `selector`.
|
|
956
|
+
|
|
957
|
+
**Input:**
|
|
958
|
+
| Parameter | Type | Default | Description |
|
|
959
|
+
|-----------|------|---------|-------------|
|
|
960
|
+
| `a11yRef` | `string` | - | Accessibility ref |
|
|
961
|
+
| `testId` | `string` | - | `data-testid` value |
|
|
962
|
+
| `selector` | `string` | - | CSS selector |
|
|
963
|
+
| `text` | `string` | **required** | Text to type |
|
|
964
|
+
| `timeoutMs` | `number` | `15000` | Max wait time |
|
|
965
|
+
|
|
966
|
+
**Output:**
|
|
967
|
+
|
|
968
|
+
```typescript
|
|
969
|
+
{
|
|
970
|
+
typed: boolean;
|
|
971
|
+
target: string;
|
|
972
|
+
textLength: number;
|
|
973
|
+
}
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
**Example:**
|
|
977
|
+
|
|
978
|
+
```json
|
|
979
|
+
{ "testId": "amount-input", "text": "0.5" }
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
---
|
|
983
|
+
|
|
984
|
+
#### `mm_wait_for`
|
|
985
|
+
|
|
986
|
+
Wait for an element to become visible. Specify exactly ONE of: `a11yRef`, `testId`, or `selector`.
|
|
987
|
+
|
|
988
|
+
**Input:**
|
|
989
|
+
| Parameter | Type | Default | Description |
|
|
990
|
+
|-----------|------|---------|-------------|
|
|
991
|
+
| `a11yRef` | `string` | - | Accessibility ref |
|
|
992
|
+
| `testId` | `string` | - | `data-testid` value |
|
|
993
|
+
| `selector` | `string` | - | CSS selector |
|
|
994
|
+
| `timeoutMs` | `number` | `15000` | Max wait time (100-120000) |
|
|
995
|
+
|
|
996
|
+
**Output:**
|
|
997
|
+
|
|
998
|
+
```typescript
|
|
999
|
+
{
|
|
1000
|
+
found: boolean;
|
|
1001
|
+
target: string;
|
|
1002
|
+
}
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
---
|
|
1006
|
+
|
|
1007
|
+
#### `mm_clipboard`
|
|
1008
|
+
|
|
1009
|
+
Read from or write to the browser clipboard. Useful for pasting content (e.g., Secret Recovery Phrase) into components that support paste functionality.
|
|
1010
|
+
|
|
1011
|
+
**Input:**
|
|
1012
|
+
| Parameter | Type | Default | Description |
|
|
1013
|
+
|-----------|------|---------|-------------|
|
|
1014
|
+
| `action` | `"write" \| "read"` | **required** | Clipboard action |
|
|
1015
|
+
| `text` | `string` | - | Text to write (required when `action="write"`) |
|
|
1016
|
+
|
|
1017
|
+
**Output:**
|
|
1018
|
+
|
|
1019
|
+
```typescript
|
|
1020
|
+
{
|
|
1021
|
+
action: "write" | "read";
|
|
1022
|
+
success: boolean;
|
|
1023
|
+
text?: string; // Present when action="read" and successful
|
|
1024
|
+
}
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
**Examples:**
|
|
1028
|
+
|
|
1029
|
+
```json
|
|
1030
|
+
{ "action": "write", "text": "word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12" }
|
|
1031
|
+
{ "action": "read" }
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
**Use Case - Fast SRP Entry:**
|
|
1035
|
+
|
|
1036
|
+
```
|
|
1037
|
+
1. mm_clipboard { "action": "write", "text": "abandon abandon ... about" }
|
|
1038
|
+
2. mm_click { "testId": "srp-input-import__paste-button" }
|
|
1039
|
+
→ All 12 words populated instantly via paste
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
#### `mm_navigate`
|
|
1045
|
+
|
|
1046
|
+
Navigate to a specific screen in the extension.
|
|
1047
|
+
|
|
1048
|
+
**Input:**
|
|
1049
|
+
| Parameter | Type | Default | Description |
|
|
1050
|
+
|-----------|------|---------|-------------|
|
|
1051
|
+
| `screen` | `"home" \| "settings" \| "notification" \| "url"` | **required** | Target screen |
|
|
1052
|
+
| `url` | `string` | - | Required when `screen="url"` |
|
|
1053
|
+
|
|
1054
|
+
**Output:**
|
|
1055
|
+
|
|
1056
|
+
```typescript
|
|
1057
|
+
{
|
|
1058
|
+
navigated: boolean;
|
|
1059
|
+
currentUrl: string;
|
|
1060
|
+
}
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
**Examples:**
|
|
1064
|
+
|
|
1065
|
+
```json
|
|
1066
|
+
{ "screen": "home" }
|
|
1067
|
+
{ "screen": "settings" }
|
|
1068
|
+
{ "screen": "url", "url": "https://app.uniswap.org" }
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
---
|
|
1072
|
+
|
|
1073
|
+
### Multi-Tab Tools
|
|
1074
|
+
|
|
1075
|
+
#### `mm_wait_for_notification`
|
|
1076
|
+
|
|
1077
|
+
Wait for a notification popup to appear (e.g., after dApp interaction). Sets the notification page as active.
|
|
1078
|
+
|
|
1079
|
+
**Input:**
|
|
1080
|
+
| Parameter | Type | Default | Description |
|
|
1081
|
+
|-----------|------|---------|-------------|
|
|
1082
|
+
| `timeoutMs` | `number` | `15000` | Max wait time (1000-60000) |
|
|
1083
|
+
|
|
1084
|
+
**Output:**
|
|
1085
|
+
|
|
1086
|
+
```typescript
|
|
1087
|
+
{
|
|
1088
|
+
found: boolean;
|
|
1089
|
+
pageUrl: string;
|
|
1090
|
+
}
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
---
|
|
1094
|
+
|
|
1095
|
+
#### `mm_switch_to_tab`
|
|
1096
|
+
|
|
1097
|
+
Switch the active page for subsequent interactions.
|
|
1098
|
+
|
|
1099
|
+
**Input:**
|
|
1100
|
+
| Parameter | Type | Default | Description |
|
|
1101
|
+
|-----------|------|---------|-------------|
|
|
1102
|
+
| `role` | `"extension" \| "notification" \| "dapp" \| "other"` | - | Tab role to switch to |
|
|
1103
|
+
| `url` | `string` | - | URL prefix to match |
|
|
1104
|
+
|
|
1105
|
+
**Output:**
|
|
1106
|
+
|
|
1107
|
+
```typescript
|
|
1108
|
+
{
|
|
1109
|
+
switched: boolean;
|
|
1110
|
+
activeTab: {
|
|
1111
|
+
role: TabRole;
|
|
1112
|
+
url: string;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
**Example:**
|
|
1118
|
+
|
|
1119
|
+
```json
|
|
1120
|
+
{ "role": "dapp" }
|
|
1121
|
+
{ "url": "https://app.uniswap.org" }
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
---
|
|
1125
|
+
|
|
1126
|
+
#### `mm_close_tab`
|
|
1127
|
+
|
|
1128
|
+
Close a specific tab. Cannot close the extension home page.
|
|
1129
|
+
|
|
1130
|
+
**Input:**
|
|
1131
|
+
| Parameter | Type | Default | Description |
|
|
1132
|
+
|-----------|------|---------|-------------|
|
|
1133
|
+
| `role` | `"notification" \| "dapp" \| "other"` | - | Tab role to close |
|
|
1134
|
+
| `url` | `string` | - | URL prefix to match |
|
|
1135
|
+
|
|
1136
|
+
**Output:**
|
|
1137
|
+
|
|
1138
|
+
```typescript
|
|
1139
|
+
{
|
|
1140
|
+
closed: boolean;
|
|
1141
|
+
closedUrl: string;
|
|
1142
|
+
}
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
---
|
|
1146
|
+
|
|
1147
|
+
### Screenshot Tools
|
|
1148
|
+
|
|
1149
|
+
#### `mm_screenshot`
|
|
1150
|
+
|
|
1151
|
+
Capture a screenshot and save to `test-artifacts/screenshots/`.
|
|
1152
|
+
|
|
1153
|
+
**Input:**
|
|
1154
|
+
| Parameter | Type | Default | Description |
|
|
1155
|
+
|-----------|------|---------|-------------|
|
|
1156
|
+
| `name` | `string` | **required** | Filename (without extension) |
|
|
1157
|
+
| `fullPage` | `boolean` | `true` | Capture full page |
|
|
1158
|
+
| `selector` | `string` | - | Capture specific element only |
|
|
1159
|
+
| `includeBase64` | `boolean` | `false` | Include base64 in response |
|
|
1160
|
+
|
|
1161
|
+
**Output:**
|
|
1162
|
+
|
|
1163
|
+
```typescript
|
|
1164
|
+
{
|
|
1165
|
+
path: string; // File path
|
|
1166
|
+
width: number;
|
|
1167
|
+
height: number;
|
|
1168
|
+
base64?: string; // If includeBase64=true
|
|
1169
|
+
}
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
---
|
|
1173
|
+
|
|
1174
|
+
### Smart Contract Tools
|
|
1175
|
+
|
|
1176
|
+
#### `mm_seed_contract`
|
|
1177
|
+
|
|
1178
|
+
Deploy a smart contract to the local Anvil node. Requires `ContractSeedingCapability`.
|
|
1179
|
+
|
|
1180
|
+
**Input:**
|
|
1181
|
+
| Parameter | Type | Default | Description |
|
|
1182
|
+
|-----------|------|---------|-------------|
|
|
1183
|
+
| `contractName` | `string` | **required** | Contract to deploy (see list below) |
|
|
1184
|
+
| `hardfork` | `string` | `"prague"` | EVM hardfork |
|
|
1185
|
+
| `deployerOptions.fromAddress` | `string` | - | Impersonate address |
|
|
1186
|
+
| `deployerOptions.fromPrivateKey` | `string` | - | Deploy from specific key |
|
|
1187
|
+
|
|
1188
|
+
**Available Contracts:**
|
|
1189
|
+
| Name | Description |
|
|
1190
|
+
|------|-------------|
|
|
1191
|
+
| `hst` | ERC-20 TST token |
|
|
1192
|
+
| `nfts` | ERC-721 NFT collection |
|
|
1193
|
+
| `erc1155` | ERC-1155 multi-token |
|
|
1194
|
+
| `piggybank` | Simple ETH storage |
|
|
1195
|
+
| `failing` | Always reverts (error testing) |
|
|
1196
|
+
| `multisig` | Multi-signature wallet |
|
|
1197
|
+
| `entrypoint` | ERC-4337 EntryPoint |
|
|
1198
|
+
| `simpleAccountFactory` | ERC-4337 account factory |
|
|
1199
|
+
| `verifyingPaymaster` | ERC-4337 paymaster |
|
|
1200
|
+
|
|
1201
|
+
**Output:**
|
|
1202
|
+
|
|
1203
|
+
```typescript
|
|
1204
|
+
{
|
|
1205
|
+
contractName: string;
|
|
1206
|
+
contractAddress: string;
|
|
1207
|
+
deployedAt: string; // ISO timestamp
|
|
1208
|
+
}
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
---
|
|
1212
|
+
|
|
1213
|
+
#### `mm_seed_contracts`
|
|
1214
|
+
|
|
1215
|
+
Deploy multiple contracts in sequence.
|
|
1216
|
+
|
|
1217
|
+
**Input:**
|
|
1218
|
+
| Parameter | Type | Default | Description |
|
|
1219
|
+
|-----------|------|---------|-------------|
|
|
1220
|
+
| `contracts` | `string[]` | **required** | Contracts to deploy (1-9) |
|
|
1221
|
+
| `hardfork` | `string` | `"prague"` | EVM hardfork |
|
|
1222
|
+
|
|
1223
|
+
**Output:**
|
|
1224
|
+
|
|
1225
|
+
```typescript
|
|
1226
|
+
{
|
|
1227
|
+
deployed: [{ contractName, contractAddress, deployedAt }];
|
|
1228
|
+
failed: [{ contractName, error }];
|
|
1229
|
+
}
|
|
1230
|
+
```
|
|
1231
|
+
|
|
1232
|
+
---
|
|
1233
|
+
|
|
1234
|
+
#### `mm_get_contract_address`
|
|
1235
|
+
|
|
1236
|
+
Get the deployed address of a contract.
|
|
1237
|
+
|
|
1238
|
+
**Input:**
|
|
1239
|
+
| Parameter | Type | Description |
|
|
1240
|
+
|-----------|------|-------------|
|
|
1241
|
+
| `contractName` | `string` | Contract name to look up |
|
|
1242
|
+
|
|
1243
|
+
**Output:**
|
|
1244
|
+
|
|
1245
|
+
```typescript
|
|
1246
|
+
{
|
|
1247
|
+
contractName: string;
|
|
1248
|
+
contractAddress: string | null;
|
|
1249
|
+
}
|
|
1250
|
+
```
|
|
1251
|
+
|
|
1252
|
+
---
|
|
1253
|
+
|
|
1254
|
+
#### `mm_list_contracts`
|
|
1255
|
+
|
|
1256
|
+
List all contracts deployed in this session.
|
|
1257
|
+
|
|
1258
|
+
**Input:** None
|
|
1259
|
+
|
|
1260
|
+
**Output:**
|
|
1261
|
+
|
|
1262
|
+
```typescript
|
|
1263
|
+
{
|
|
1264
|
+
contracts: [{
|
|
1265
|
+
contractName: string;
|
|
1266
|
+
contractAddress: string;
|
|
1267
|
+
deployedAt: string;
|
|
1268
|
+
}];
|
|
1269
|
+
}
|
|
1270
|
+
```
|
|
1271
|
+
|
|
1272
|
+
---
|
|
1273
|
+
|
|
1274
|
+
### Knowledge Store Tools
|
|
1275
|
+
|
|
1276
|
+
The knowledge store enables cross-session learning by recording tool invocations and their context.
|
|
1277
|
+
|
|
1278
|
+
#### `mm_knowledge_last`
|
|
1279
|
+
|
|
1280
|
+
Get the last N step records from the knowledge store.
|
|
1281
|
+
|
|
1282
|
+
**Input:**
|
|
1283
|
+
| Parameter | Type | Default | Description |
|
|
1284
|
+
|-----------|------|---------|-------------|
|
|
1285
|
+
| `n` | `number` | `20` | Number of steps (1-200) |
|
|
1286
|
+
| `scope` | `"current" \| "all" \| { sessionId }` | `"current"` | Which sessions to query |
|
|
1287
|
+
| `filters.flowTag` | `string` | - | Filter by flow tag |
|
|
1288
|
+
| `filters.tag` | `string` | - | Filter by tag |
|
|
1289
|
+
| `filters.screen` | `string` | - | Filter by screen |
|
|
1290
|
+
| `filters.sinceHours` | `number` | - | Only steps from last N hours |
|
|
1291
|
+
|
|
1292
|
+
**Output:**
|
|
1293
|
+
|
|
1294
|
+
```typescript
|
|
1295
|
+
{
|
|
1296
|
+
steps: [{
|
|
1297
|
+
timestamp: string;
|
|
1298
|
+
tool: string;
|
|
1299
|
+
screen: ScreenName;
|
|
1300
|
+
snippet: string; // Human-readable summary
|
|
1301
|
+
sessionId?: string;
|
|
1302
|
+
matchedFields?: string[];
|
|
1303
|
+
sessionGoal?: string;
|
|
1304
|
+
}];
|
|
1305
|
+
}
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
---
|
|
1309
|
+
|
|
1310
|
+
#### `mm_knowledge_search`
|
|
1311
|
+
|
|
1312
|
+
Search step records by tool name, screen, testId, or accessibility names.
|
|
1313
|
+
|
|
1314
|
+
**Input:**
|
|
1315
|
+
| Parameter | Type | Default | Description |
|
|
1316
|
+
|-----------|------|---------|-------------|
|
|
1317
|
+
| `query` | `string` | **required** | Search query (1-200 chars) |
|
|
1318
|
+
| `limit` | `number` | `20` | Max results (1-100) |
|
|
1319
|
+
| `scope` | `"current" \| "all" \| { sessionId }` | `"all"` | Which sessions to search |
|
|
1320
|
+
| `filters` | `KnowledgeFilters` | - | Additional filters |
|
|
1321
|
+
|
|
1322
|
+
**Output:**
|
|
1323
|
+
|
|
1324
|
+
```typescript
|
|
1325
|
+
{
|
|
1326
|
+
matches: KnowledgeStepSummary[];
|
|
1327
|
+
query: string;
|
|
1328
|
+
}
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
---
|
|
1332
|
+
|
|
1333
|
+
#### `mm_knowledge_summarize`
|
|
1334
|
+
|
|
1335
|
+
Generate a recipe-like summary of steps taken in a session.
|
|
1336
|
+
|
|
1337
|
+
**Input:**
|
|
1338
|
+
| Parameter | Type | Default | Description |
|
|
1339
|
+
|-----------|------|---------|-------------|
|
|
1340
|
+
| `scope` | `"current" \| { sessionId }` | `"current"` | Session to summarize |
|
|
1341
|
+
|
|
1342
|
+
**Output:**
|
|
1343
|
+
|
|
1344
|
+
```typescript
|
|
1345
|
+
{
|
|
1346
|
+
sessionId: string;
|
|
1347
|
+
stepCount: number;
|
|
1348
|
+
recipe: [{
|
|
1349
|
+
stepNumber: number;
|
|
1350
|
+
tool: string;
|
|
1351
|
+
notes: string;
|
|
1352
|
+
}];
|
|
1353
|
+
}
|
|
1354
|
+
```
|
|
1355
|
+
|
|
1356
|
+
---
|
|
1357
|
+
|
|
1358
|
+
#### `mm_knowledge_sessions`
|
|
1359
|
+
|
|
1360
|
+
List recent sessions with metadata.
|
|
1361
|
+
|
|
1362
|
+
**Input:**
|
|
1363
|
+
| Parameter | Type | Default | Description |
|
|
1364
|
+
|-----------|------|---------|-------------|
|
|
1365
|
+
| `limit` | `number` | `10` | Max sessions (1-50) |
|
|
1366
|
+
| `filters` | `KnowledgeFilters` | - | Filter options |
|
|
1367
|
+
|
|
1368
|
+
**Output:**
|
|
1369
|
+
|
|
1370
|
+
```typescript
|
|
1371
|
+
{
|
|
1372
|
+
sessions: [{
|
|
1373
|
+
sessionId: string;
|
|
1374
|
+
createdAt: string;
|
|
1375
|
+
goal?: string;
|
|
1376
|
+
flowTags: string[];
|
|
1377
|
+
tags: string[];
|
|
1378
|
+
}];
|
|
1379
|
+
}
|
|
1380
|
+
```
|
|
1381
|
+
|
|
1382
|
+
---
|
|
1383
|
+
|
|
1384
|
+
### Batching Tools
|
|
1385
|
+
|
|
1386
|
+
#### `mm_run_steps`
|
|
1387
|
+
|
|
1388
|
+
Execute multiple tools in sequence. Reduces round trips for multi-step flows.
|
|
1389
|
+
|
|
1390
|
+
**Input:**
|
|
1391
|
+
| Parameter | Type | Default | Description |
|
|
1392
|
+
|-----------|------|---------|-------------|
|
|
1393
|
+
| `steps` | `array` | **required** | Tool calls to execute (1-50) |
|
|
1394
|
+
| `steps[].tool` | `string` | **required** | Tool name (e.g., `mm_click`) |
|
|
1395
|
+
| `steps[].args` | `object` | `{}` | Tool arguments |
|
|
1396
|
+
| `stopOnError` | `boolean` | `false` | Stop on first error |
|
|
1397
|
+
| `includeObservations` | `"none" \| "failures" \| "all"` | `"all"` | When to include state observations |
|
|
1398
|
+
|
|
1399
|
+
**Output:**
|
|
1400
|
+
|
|
1401
|
+
```typescript
|
|
1402
|
+
{
|
|
1403
|
+
steps: [{
|
|
1404
|
+
tool: string;
|
|
1405
|
+
ok: boolean;
|
|
1406
|
+
result?: unknown;
|
|
1407
|
+
error?: { code: string; message: string; details?: unknown };
|
|
1408
|
+
meta: { durationMs: number; timestamp: string };
|
|
1409
|
+
}];
|
|
1410
|
+
summary: {
|
|
1411
|
+
ok: boolean; // All steps succeeded
|
|
1412
|
+
total: number;
|
|
1413
|
+
succeeded: number;
|
|
1414
|
+
failed: number;
|
|
1415
|
+
durationMs: number;
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
```
|
|
1419
|
+
|
|
1420
|
+
**Example:**
|
|
1421
|
+
|
|
1422
|
+
```json
|
|
1423
|
+
{
|
|
1424
|
+
"steps": [
|
|
1425
|
+
{ "tool": "mm_click", "args": { "testId": "send-button" } },
|
|
1426
|
+
{ "tool": "mm_type", "args": { "testId": "amount-input", "text": "0.1" } },
|
|
1427
|
+
{ "tool": "mm_click", "args": { "testId": "confirm-button" } }
|
|
1428
|
+
],
|
|
1429
|
+
"stopOnError": true
|
|
1430
|
+
}
|
|
1431
|
+
```
|
|
1432
|
+
|
|
1433
|
+
## Development
|
|
1434
|
+
|
|
1435
|
+
### Building
|
|
1436
|
+
|
|
1437
|
+
```bash
|
|
1438
|
+
yarn build
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
### Testing
|
|
1442
|
+
|
|
1443
|
+
```bash
|
|
1444
|
+
yarn test
|
|
1445
|
+
```
|
|
1446
|
+
|
|
1447
|
+
### Local Development with yalc
|
|
1448
|
+
|
|
1449
|
+
```bash
|
|
1450
|
+
# In this repo
|
|
1451
|
+
yarn build && yalc publish
|
|
1452
|
+
|
|
1453
|
+
# In consumer repo
|
|
1454
|
+
yalc add @metamask/client-mcp-core
|
|
1455
|
+
```
|
|
1456
|
+
|
|
1457
|
+
## License
|
|
1458
|
+
|
|
1459
|
+
MIT
|