mppx 0.0.1 → 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/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/BodyDigest.d.ts +42 -0
- package/dist/BodyDigest.d.ts.map +1 -0
- package/dist/BodyDigest.js +40 -0
- package/dist/BodyDigest.js.map +1 -0
- package/dist/Challenge.d.ts +271 -0
- package/dist/Challenge.d.ts.map +1 -0
- package/dist/Challenge.js +291 -0
- package/dist/Challenge.js.map +1 -0
- package/dist/Credential.d.ts +91 -0
- package/dist/Credential.d.ts.map +1 -0
- package/dist/Credential.js +122 -0
- package/dist/Credential.js.map +1 -0
- package/dist/Errors.d.ts +243 -0
- package/dist/Errors.d.ts.map +1 -0
- package/dist/Errors.js +201 -0
- package/dist/Errors.js.map +1 -0
- package/dist/Expires.d.ts +15 -0
- package/dist/Expires.d.ts.map +1 -0
- package/dist/Expires.js +29 -0
- package/dist/Expires.js.map +1 -0
- package/dist/Intent.d.ts +101 -0
- package/dist/Intent.d.ts.map +1 -0
- package/dist/Intent.js +83 -0
- package/dist/Intent.js.map +1 -0
- package/dist/Mcp.d.ts +74 -0
- package/dist/Mcp.d.ts.map +1 -0
- package/dist/Mcp.js +9 -0
- package/dist/Mcp.js.map +1 -0
- package/dist/MethodIntent.d.ts +225 -0
- package/dist/MethodIntent.d.ts.map +1 -0
- package/dist/MethodIntent.js +156 -0
- package/dist/MethodIntent.js.map +1 -0
- package/dist/PaymentRequest.d.ts +88 -0
- package/dist/PaymentRequest.d.ts.map +1 -0
- package/dist/PaymentRequest.js +81 -0
- package/dist/PaymentRequest.js.map +1 -0
- package/dist/Receipt.d.ts +110 -0
- package/dist/Receipt.d.ts.map +1 -0
- package/dist/Receipt.js +105 -0
- package/dist/Receipt.js.map +1 -0
- package/dist/Store.d.ts +28 -0
- package/dist/Store.d.ts.map +1 -0
- package/dist/Store.js +61 -0
- package/dist/Store.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1219 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/Methods.d.ts +4 -0
- package/dist/client/Methods.d.ts.map +1 -0
- package/dist/client/Methods.js +4 -0
- package/dist/client/Methods.js.map +1 -0
- package/dist/client/Mppx.d.ts +84 -0
- package/dist/client/Mppx.d.ts.map +1 -0
- package/dist/client/Mppx.js +64 -0
- package/dist/client/Mppx.js.map +1 -0
- package/dist/client/Transport.d.ts +56 -0
- package/dist/client/Transport.d.ts.map +1 -0
- package/dist/client/Transport.js +81 -0
- package/dist/client/Transport.js.map +1 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/internal/Fetch.d.ts +85 -0
- package/dist/client/internal/Fetch.d.ts.map +1 -0
- package/dist/client/internal/Fetch.js +95 -0
- package/dist/client/internal/Fetch.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/types.d.ts +302 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +2 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/mcp-sdk/client/McpClient.d.ts +78 -0
- package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -0
- package/dist/mcp-sdk/client/McpClient.js +98 -0
- package/dist/mcp-sdk/client/McpClient.js.map +1 -0
- package/dist/mcp-sdk/client/index.d.ts +3 -0
- package/dist/mcp-sdk/client/index.d.ts.map +1 -0
- package/dist/mcp-sdk/client/index.js +3 -0
- package/dist/mcp-sdk/client/index.js.map +1 -0
- package/dist/mcp-sdk/server/Transport.d.ts +43 -0
- package/dist/mcp-sdk/server/Transport.d.ts.map +1 -0
- package/dist/mcp-sdk/server/Transport.js +71 -0
- package/dist/mcp-sdk/server/Transport.js.map +1 -0
- package/dist/mcp-sdk/server/index.d.ts +2 -0
- package/dist/mcp-sdk/server/index.d.ts.map +1 -0
- package/dist/mcp-sdk/server/index.js +2 -0
- package/dist/mcp-sdk/server/index.js.map +1 -0
- package/dist/middlewares/elysia.d.ts +51 -0
- package/dist/middlewares/elysia.d.ts.map +1 -0
- package/dist/middlewares/elysia.js +59 -0
- package/dist/middlewares/elysia.js.map +1 -0
- package/dist/middlewares/express.d.ts +46 -0
- package/dist/middlewares/express.d.ts.map +1 -0
- package/dist/middlewares/express.js +69 -0
- package/dist/middlewares/express.js.map +1 -0
- package/dist/middlewares/hono.d.ts +46 -0
- package/dist/middlewares/hono.d.ts.map +1 -0
- package/dist/middlewares/hono.js +57 -0
- package/dist/middlewares/hono.js.map +1 -0
- package/dist/middlewares/internal/mppx.d.ts +16 -0
- package/dist/middlewares/internal/mppx.d.ts.map +1 -0
- package/dist/middlewares/internal/mppx.js +16 -0
- package/dist/middlewares/internal/mppx.js.map +1 -0
- package/dist/middlewares/nextjs.d.ts +45 -0
- package/dist/middlewares/nextjs.d.ts.map +1 -0
- package/dist/middlewares/nextjs.js +57 -0
- package/dist/middlewares/nextjs.js.map +1 -0
- package/dist/proxy/Proxy.d.ts +47 -0
- package/dist/proxy/Proxy.d.ts.map +1 -0
- package/dist/proxy/Proxy.js +126 -0
- package/dist/proxy/Proxy.js.map +1 -0
- package/dist/proxy/Service.d.ts +100 -0
- package/dist/proxy/Service.d.ts.map +1 -0
- package/dist/proxy/Service.js +147 -0
- package/dist/proxy/Service.js.map +1 -0
- package/dist/proxy/index.d.ts +7 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +7 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/internal/Headers.d.ts +3 -0
- package/dist/proxy/internal/Headers.d.ts.map +1 -0
- package/dist/proxy/internal/Headers.js +41 -0
- package/dist/proxy/internal/Headers.js.map +1 -0
- package/dist/proxy/internal/Route.d.ts +14 -0
- package/dist/proxy/internal/Route.d.ts.map +1 -0
- package/dist/proxy/internal/Route.js +47 -0
- package/dist/proxy/internal/Route.js.map +1 -0
- package/dist/proxy/services/anthropic.d.ts +29 -0
- package/dist/proxy/services/anthropic.d.ts.map +1 -0
- package/dist/proxy/services/anthropic.js +30 -0
- package/dist/proxy/services/anthropic.js.map +1 -0
- package/dist/proxy/services/openai.d.ts +29 -0
- package/dist/proxy/services/openai.d.ts.map +1 -0
- package/dist/proxy/services/openai.js +30 -0
- package/dist/proxy/services/openai.js.map +1 -0
- package/dist/proxy/services/stripe.d.ts +29 -0
- package/dist/proxy/services/stripe.d.ts.map +1 -0
- package/dist/proxy/services/stripe.js +30 -0
- package/dist/proxy/services/stripe.js.map +1 -0
- package/dist/server/Methods.d.ts +3 -0
- package/dist/server/Methods.d.ts.map +1 -0
- package/dist/server/Methods.js +3 -0
- package/dist/server/Methods.js.map +1 -0
- package/dist/server/Mppx.d.ts +116 -0
- package/dist/server/Mppx.d.ts.map +1 -0
- package/dist/server/Mppx.js +207 -0
- package/dist/server/Mppx.js.map +1 -0
- package/dist/server/NodeListener.d.ts +3 -0
- package/dist/server/NodeListener.d.ts.map +1 -0
- package/dist/server/NodeListener.js +3 -0
- package/dist/server/NodeListener.js.map +1 -0
- package/dist/server/Request.d.ts +24 -0
- package/dist/server/Request.d.ts.map +1 -0
- package/dist/server/Request.js +26 -0
- package/dist/server/Request.js.map +1 -0
- package/dist/server/Response.d.ts +10 -0
- package/dist/server/Response.d.ts.map +1 -0
- package/dist/server/Response.js +15 -0
- package/dist/server/Response.js.map +1 -0
- package/dist/server/Transport.d.ts +93 -0
- package/dist/server/Transport.d.ts.map +1 -0
- package/dist/server/Transport.js +132 -0
- package/dist/server/Transport.js.map +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/stripe/Intents.d.ts +54 -0
- package/dist/stripe/Intents.d.ts.map +1 -0
- package/dist/stripe/Intents.js +27 -0
- package/dist/stripe/Intents.js.map +1 -0
- package/dist/stripe/client/Charge.d.ts +114 -0
- package/dist/stripe/client/Charge.d.ts.map +1 -0
- package/dist/stripe/client/Charge.js +77 -0
- package/dist/stripe/client/Charge.js.map +1 -0
- package/dist/stripe/client/MethodIntents.d.ts +80 -0
- package/dist/stripe/client/MethodIntents.d.ts.map +1 -0
- package/dist/stripe/client/MethodIntents.js +34 -0
- package/dist/stripe/client/MethodIntents.js.map +1 -0
- package/dist/stripe/client/index.d.ts +3 -0
- package/dist/stripe/client/index.d.ts.map +1 -0
- package/dist/stripe/client/index.js +3 -0
- package/dist/stripe/client/index.js.map +1 -0
- package/dist/stripe/index.d.ts +2 -0
- package/dist/stripe/index.d.ts.map +1 -0
- package/dist/stripe/index.js +2 -0
- package/dist/stripe/index.js.map +1 -0
- package/dist/stripe/server/Charge.d.ts +74 -0
- package/dist/stripe/server/Charge.d.ts.map +1 -0
- package/dist/stripe/server/Charge.js +79 -0
- package/dist/stripe/server/Charge.js.map +1 -0
- package/dist/stripe/server/MethodIntents.d.ts +65 -0
- package/dist/stripe/server/MethodIntents.d.ts.map +1 -0
- package/dist/stripe/server/MethodIntents.js +21 -0
- package/dist/stripe/server/MethodIntents.js.map +1 -0
- package/dist/stripe/server/index.d.ts +3 -0
- package/dist/stripe/server/index.d.ts.map +1 -0
- package/dist/stripe/server/index.js +3 -0
- package/dist/stripe/server/index.js.map +1 -0
- package/dist/tempo/Attribution.d.ts +101 -0
- package/dist/tempo/Attribution.d.ts.map +1 -0
- package/dist/tempo/Attribution.js +124 -0
- package/dist/tempo/Attribution.js.map +1 -0
- package/dist/tempo/Intents.d.ts +132 -0
- package/dist/tempo/Intents.d.ts.map +1 -0
- package/dist/tempo/Intents.js +81 -0
- package/dist/tempo/Intents.js.map +1 -0
- package/dist/tempo/client/ChannelOps.d.ts +54 -0
- package/dist/tempo/client/ChannelOps.d.ts.map +1 -0
- package/dist/tempo/client/ChannelOps.js +138 -0
- package/dist/tempo/client/ChannelOps.js.map +1 -0
- package/dist/tempo/client/Charge.d.ts +76 -0
- package/dist/tempo/client/Charge.d.ts.map +1 -0
- package/dist/tempo/client/Charge.js +69 -0
- package/dist/tempo/client/Charge.js.map +1 -0
- package/dist/tempo/client/MethodIntents.d.ts +157 -0
- package/dist/tempo/client/MethodIntents.d.ts.map +1 -0
- package/dist/tempo/client/MethodIntents.js +25 -0
- package/dist/tempo/client/MethodIntents.js.map +1 -0
- package/dist/tempo/client/Session.d.ts +159 -0
- package/dist/tempo/client/Session.d.ts.map +1 -0
- package/dist/tempo/client/Session.js +263 -0
- package/dist/tempo/client/Session.js.map +1 -0
- package/dist/tempo/client/SessionManager.d.ts +62 -0
- package/dist/tempo/client/SessionManager.d.ts.map +1 -0
- package/dist/tempo/client/SessionManager.js +196 -0
- package/dist/tempo/client/SessionManager.js.map +1 -0
- package/dist/tempo/client/index.d.ts +6 -0
- package/dist/tempo/client/index.d.ts.map +1 -0
- package/dist/tempo/client/index.js +5 -0
- package/dist/tempo/client/index.js.map +1 -0
- package/dist/tempo/index.d.ts +3 -0
- package/dist/tempo/index.d.ts.map +1 -0
- package/dist/tempo/index.js +3 -0
- package/dist/tempo/index.js.map +1 -0
- package/dist/tempo/internal/account.d.ts +32 -0
- package/dist/tempo/internal/account.d.ts.map +1 -0
- package/dist/tempo/internal/account.js +33 -0
- package/dist/tempo/internal/account.js.map +1 -0
- package/dist/tempo/internal/defaults.d.ts +18 -0
- package/dist/tempo/internal/defaults.d.ts.map +1 -0
- package/dist/tempo/internal/defaults.js +18 -0
- package/dist/tempo/internal/defaults.js.map +1 -0
- package/dist/tempo/internal/types.d.ts +11 -0
- package/dist/tempo/internal/types.d.ts.map +1 -0
- package/dist/tempo/internal/types.js +2 -0
- package/dist/tempo/internal/types.js.map +1 -0
- package/dist/tempo/server/Charge.d.ts +77 -0
- package/dist/tempo/server/Charge.d.ts.map +1 -0
- package/dist/tempo/server/Charge.js +228 -0
- package/dist/tempo/server/Charge.js.map +1 -0
- package/dist/tempo/server/MethodIntents.d.ts +140 -0
- package/dist/tempo/server/MethodIntents.d.ts.map +1 -0
- package/dist/tempo/server/MethodIntents.js +26 -0
- package/dist/tempo/server/MethodIntents.js.map +1 -0
- package/dist/tempo/server/Session.d.ts +148 -0
- package/dist/tempo/server/Session.d.ts.map +1 -0
- package/dist/tempo/server/Session.js +529 -0
- package/dist/tempo/server/Session.js.map +1 -0
- package/dist/tempo/server/internal/transport.d.ts +47 -0
- package/dist/tempo/server/internal/transport.d.ts.map +1 -0
- package/dist/tempo/server/internal/transport.js +118 -0
- package/dist/tempo/server/internal/transport.js.map +1 -0
- package/dist/tempo/stream/Chain.d.ts +52 -0
- package/dist/tempo/stream/Chain.d.ts.map +1 -0
- package/dist/tempo/stream/Chain.js +215 -0
- package/dist/tempo/stream/Chain.js.map +1 -0
- package/dist/tempo/stream/Channel.d.ts +26 -0
- package/dist/tempo/stream/Channel.d.ts.map +1 -0
- package/dist/tempo/stream/Channel.js +27 -0
- package/dist/tempo/stream/Channel.js.map +1 -0
- package/dist/tempo/stream/ChannelStore.d.ts +103 -0
- package/dist/tempo/stream/ChannelStore.d.ts.map +1 -0
- package/dist/tempo/stream/ChannelStore.js +100 -0
- package/dist/tempo/stream/ChannelStore.js.map +1 -0
- package/dist/tempo/stream/Receipt.d.ts +22 -0
- package/dist/tempo/stream/Receipt.d.ts.map +1 -0
- package/dist/tempo/stream/Receipt.js +34 -0
- package/dist/tempo/stream/Receipt.js.map +1 -0
- package/dist/tempo/stream/Sse.d.ts +134 -0
- package/dist/tempo/stream/Sse.d.ts.map +1 -0
- package/dist/tempo/stream/Sse.js +288 -0
- package/dist/tempo/stream/Sse.js.map +1 -0
- package/dist/tempo/stream/Types.d.ts +78 -0
- package/dist/tempo/stream/Types.d.ts.map +1 -0
- package/dist/tempo/stream/Types.js +2 -0
- package/dist/tempo/stream/Types.js.map +1 -0
- package/dist/tempo/stream/Voucher.d.ts +20 -0
- package/dist/tempo/stream/Voucher.d.ts.map +1 -0
- package/dist/tempo/stream/Voucher.js +98 -0
- package/dist/tempo/stream/Voucher.js.map +1 -0
- package/dist/tempo/stream/escrow.abi.d.ts +598 -0
- package/dist/tempo/stream/escrow.abi.d.ts.map +1 -0
- package/dist/tempo/stream/escrow.abi.js +760 -0
- package/dist/tempo/stream/escrow.abi.js.map +1 -0
- package/dist/tempo/stream/index.d.ts +8 -0
- package/dist/tempo/stream/index.d.ts.map +1 -0
- package/dist/tempo/stream/index.js +8 -0
- package/dist/tempo/stream/index.js.map +1 -0
- package/dist/viem/Account.d.ts +12 -0
- package/dist/viem/Account.d.ts.map +1 -0
- package/dist/viem/Account.js +14 -0
- package/dist/viem/Account.js.map +1 -0
- package/dist/viem/Client.d.ts +21 -0
- package/dist/viem/Client.d.ts.map +1 -0
- package/dist/viem/Client.js +19 -0
- package/dist/viem/Client.js.map +1 -0
- package/dist/zod.d.ts +17 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +35 -0
- package/dist/zod.js.map +1 -0
- package/package.json +117 -4
- package/src/BodyDigest.test.ts +43 -0
- package/src/BodyDigest.ts +53 -0
- package/src/Challenge.test-d.ts +81 -0
- package/src/Challenge.test.ts +414 -0
- package/src/Challenge.ts +429 -0
- package/src/Credential.test.ts +227 -0
- package/src/Credential.ts +154 -0
- package/src/Errors.test.ts +402 -0
- package/src/Errors.ts +348 -0
- package/src/Expires.ts +34 -0
- package/src/Intent.test.ts +180 -0
- package/src/Intent.ts +109 -0
- package/src/Mcp.ts +81 -0
- package/src/MethodIntent.test.ts +303 -0
- package/src/MethodIntent.ts +388 -0
- package/src/PaymentRequest.test.ts +152 -0
- package/src/PaymentRequest.ts +107 -0
- package/src/Receipt.test.ts +98 -0
- package/src/Receipt.ts +129 -0
- package/src/Store.ts +84 -0
- package/src/cli.test.ts +542 -0
- package/src/cli.ts +1319 -0
- package/src/client/Methods.ts +3 -0
- package/src/client/Mppx.test-d.ts +90 -0
- package/src/client/Mppx.test.ts +468 -0
- package/src/client/Mppx.ts +149 -0
- package/src/client/Transport.test.ts +283 -0
- package/src/client/Transport.ts +115 -0
- package/src/client/index.ts +4 -0
- package/src/client/internal/Fetch.test-d.ts +57 -0
- package/src/client/internal/Fetch.test.ts +281 -0
- package/src/client/internal/Fetch.ts +157 -0
- package/src/env.d.ts +11 -0
- package/src/index.ts +12 -0
- package/src/internal/types.ts +403 -0
- package/src/mcp-sdk/client/McpClient.test-d.ts +109 -0
- package/src/mcp-sdk/client/McpClient.test.ts +219 -0
- package/src/mcp-sdk/client/McpClient.ts +187 -0
- package/src/mcp-sdk/client/index.ts +2 -0
- package/src/mcp-sdk/server/Transport.ts +94 -0
- package/src/mcp-sdk/server/index.ts +1 -0
- package/src/middlewares/elysia.ts +66 -0
- package/src/middlewares/express.test.ts +155 -0
- package/src/middlewares/express.ts +82 -0
- package/src/middlewares/hono.test.ts +148 -0
- package/src/middlewares/hono.ts +62 -0
- package/src/middlewares/internal/mppx.ts +30 -0
- package/src/middlewares/nextjs.test.ts +164 -0
- package/src/middlewares/nextjs.ts +66 -0
- package/src/proxy/Proxy.test.ts +472 -0
- package/src/proxy/Proxy.ts +175 -0
- package/src/proxy/Service.test.ts +125 -0
- package/src/proxy/Service.ts +227 -0
- package/src/proxy/index.ts +6 -0
- package/src/proxy/internal/Headers.test.ts +100 -0
- package/src/proxy/internal/Headers.ts +40 -0
- package/src/proxy/internal/Route.test.ts +143 -0
- package/src/proxy/internal/Route.ts +54 -0
- package/src/proxy/services/anthropic.ts +45 -0
- package/src/proxy/services/openai.test.ts +97 -0
- package/src/proxy/services/openai.ts +48 -0
- package/src/proxy/services/stripe.ts +49 -0
- package/src/server/Methods.ts +2 -0
- package/src/server/Mppx.test-d.ts +343 -0
- package/src/server/Mppx.test.ts +342 -0
- package/src/server/Mppx.ts +378 -0
- package/src/server/NodeListener.test.ts +188 -0
- package/src/server/NodeListener.ts +3 -0
- package/src/server/Request.test.ts +102 -0
- package/src/server/Request.ts +33 -0
- package/src/server/Response.test.ts +31 -0
- package/src/server/Response.ts +27 -0
- package/src/server/Transport.test.ts +294 -0
- package/src/server/Transport.ts +222 -0
- package/src/server/index.ts +8 -0
- package/src/stripe/Charge.integration.test.ts +326 -0
- package/src/stripe/Intents.test.ts +52 -0
- package/src/stripe/Intents.ts +27 -0
- package/src/stripe/client/Charge.ts +119 -0
- package/src/stripe/client/MethodIntents.ts +37 -0
- package/src/stripe/client/index.ts +2 -0
- package/src/stripe/index.ts +1 -0
- package/src/stripe/server/Charge.ts +121 -0
- package/src/stripe/server/MethodIntents.ts +24 -0
- package/src/stripe/server/index.ts +2 -0
- package/src/tempo/Attribution.test.ts +187 -0
- package/src/tempo/Attribution.ts +156 -0
- package/src/tempo/Intents.test.ts +84 -0
- package/src/tempo/Intents.ts +93 -0
- package/src/tempo/client/ChannelOps.ts +233 -0
- package/src/tempo/client/Charge.ts +84 -0
- package/src/tempo/client/MethodIntents.ts +28 -0
- package/src/tempo/client/Session.ts +369 -0
- package/src/tempo/client/SessionManager.test.ts +223 -0
- package/src/tempo/client/SessionManager.ts +270 -0
- package/src/tempo/client/index.ts +5 -0
- package/src/tempo/index.ts +2 -0
- package/src/tempo/internal/account.ts +47 -0
- package/src/tempo/internal/defaults.ts +20 -0
- package/src/tempo/internal/types.ts +8 -0
- package/src/tempo/server/Charge.test.ts +847 -0
- package/src/tempo/server/Charge.ts +309 -0
- package/src/tempo/server/MethodIntents.ts +29 -0
- package/src/tempo/server/Session.test.ts +1349 -0
- package/src/tempo/server/Session.ts +773 -0
- package/src/tempo/server/Sse.test.ts +289 -0
- package/src/tempo/server/index.ts +5 -0
- package/src/tempo/server/internal/transport.ts +153 -0
- package/src/tempo/stream/Chain.ts +333 -0
- package/src/tempo/stream/Channel.ts +50 -0
- package/src/tempo/stream/ChannelStore.test.ts +473 -0
- package/src/tempo/stream/ChannelStore.ts +202 -0
- package/src/tempo/stream/Receipt.test.ts +84 -0
- package/src/tempo/stream/Receipt.ts +45 -0
- package/src/tempo/stream/Sse.test.ts +401 -0
- package/src/tempo/stream/Sse.ts +375 -0
- package/src/tempo/stream/Types.ts +86 -0
- package/src/tempo/stream/Voucher.test.ts +134 -0
- package/src/tempo/stream/Voucher.ts +123 -0
- package/src/tempo/stream/escrow.abi.ts +759 -0
- package/src/tempo/stream/index.ts +7 -0
- package/src/tsconfig.json +10 -0
- package/src/viem/Account.test.ts +71 -0
- package/src/viem/Account.ts +30 -0
- package/src/viem/Client.test.ts +58 -0
- package/src/viem/Client.ts +33 -0
- package/src/zod.ts +47 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
2
|
+
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
4
|
+
import { McpError } from '@modelcontextprotocol/sdk/types.js'
|
|
5
|
+
import { Challenge, Mcp as core_Mcp } from 'mppx'
|
|
6
|
+
import { tempo as tempo_client } from 'mppx/client'
|
|
7
|
+
import { Mppx as Mppx_server, tempo as tempo_server } from 'mppx/server'
|
|
8
|
+
import { createClient } from 'viem'
|
|
9
|
+
import { afterEach, beforeEach, describe, expect, test } from 'vitest'
|
|
10
|
+
import { accounts, asset, chain, http, client as testClient } from '~test/tempo/viem.js'
|
|
11
|
+
import * as McpServer_transport from '../server/Transport.js'
|
|
12
|
+
import * as McpClient from './McpClient.js'
|
|
13
|
+
|
|
14
|
+
const realm = 'api.example.com'
|
|
15
|
+
const secretKey = 'test-secret-key'
|
|
16
|
+
|
|
17
|
+
describe('McpClient.wrap', () => {
|
|
18
|
+
let client: Client
|
|
19
|
+
let server: McpServer
|
|
20
|
+
let clientTransport: InstanceType<typeof InMemoryTransport>
|
|
21
|
+
let serverTransport: InstanceType<typeof InMemoryTransport>
|
|
22
|
+
|
|
23
|
+
const mppxServer = Mppx_server.create({
|
|
24
|
+
methods: [
|
|
25
|
+
tempo_server.charge({
|
|
26
|
+
getClient: () => testClient,
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
29
|
+
realm,
|
|
30
|
+
secretKey,
|
|
31
|
+
transport: McpServer_transport.mcpSdk(),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
;[clientTransport, serverTransport] = InMemoryTransport.createLinkedPair()
|
|
36
|
+
|
|
37
|
+
client = new Client({ name: 'test-client', version: '1.0.0' })
|
|
38
|
+
server = new McpServer({ name: 'test-server', version: '1.0.0' })
|
|
39
|
+
|
|
40
|
+
server.registerTool(
|
|
41
|
+
'premium_tool',
|
|
42
|
+
{ description: 'A tool that requires payment' },
|
|
43
|
+
async (extra) => {
|
|
44
|
+
const result = await mppxServer.charge({
|
|
45
|
+
amount: '1',
|
|
46
|
+
currency: asset,
|
|
47
|
+
expires: new Date(Date.now() + 60_000).toISOString(),
|
|
48
|
+
recipient: accounts[0].address,
|
|
49
|
+
})(extra)
|
|
50
|
+
|
|
51
|
+
if (result.status === 402) throw result.challenge
|
|
52
|
+
|
|
53
|
+
return result.withReceipt({
|
|
54
|
+
content: [{ type: 'text' as const, text: 'Premium tool executed' }],
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
server.registerTool('free_tool', { description: 'A free tool' }, async () => {
|
|
60
|
+
return { content: [{ type: 'text' as const, text: 'Free tool executed' }] }
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
await Promise.all([client.connect(clientTransport), server.connect(serverTransport)])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
afterEach(async () => {
|
|
67
|
+
await Promise.all([client.close(), server.close()])
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('default: handles payment and returns result with receipt', async () => {
|
|
71
|
+
const mcp = McpClient.wrap(client, {
|
|
72
|
+
methods: [
|
|
73
|
+
tempo_client.charge({
|
|
74
|
+
account: accounts[1],
|
|
75
|
+
getClient: () => testClient,
|
|
76
|
+
}),
|
|
77
|
+
],
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const result = await mcp.callTool({ name: 'premium_tool', arguments: {} })
|
|
81
|
+
|
|
82
|
+
expect(result.content).toEqual([{ type: 'text', text: 'Premium tool executed' }])
|
|
83
|
+
expect(result.isError).toBeUndefined()
|
|
84
|
+
expect(result.receipt).toBeDefined()
|
|
85
|
+
expect(result.receipt?.status).toBe('success')
|
|
86
|
+
expect(result.receipt?.method).toBe('tempo')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('default: account via context', async () => {
|
|
90
|
+
const mcp = McpClient.wrap(client, {
|
|
91
|
+
methods: [
|
|
92
|
+
tempo_client.charge({
|
|
93
|
+
getClient: () => testClient,
|
|
94
|
+
}),
|
|
95
|
+
],
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const result = await mcp.callTool(
|
|
99
|
+
{ name: 'premium_tool', arguments: {} },
|
|
100
|
+
{ context: { account: accounts[1] } },
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
expect(result.content).toEqual([{ type: 'text', text: 'Premium tool executed' }])
|
|
104
|
+
expect(result.receipt?.status).toBe('success')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('behavior: passes through when no payment required', async () => {
|
|
108
|
+
const mcp = McpClient.wrap(client, {
|
|
109
|
+
methods: [
|
|
110
|
+
tempo_client.charge({
|
|
111
|
+
account: accounts[1],
|
|
112
|
+
getClient: () => testClient,
|
|
113
|
+
}),
|
|
114
|
+
],
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const result = await mcp.callTool({ name: 'free_tool', arguments: {} })
|
|
118
|
+
|
|
119
|
+
expect(result.content).toEqual([{ type: 'text', text: 'Free tool executed' }])
|
|
120
|
+
expect(result.receipt).toBeUndefined()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('behavior: throws when no account provided', async () => {
|
|
124
|
+
const mcp = McpClient.wrap(client, {
|
|
125
|
+
methods: [
|
|
126
|
+
tempo_client.charge({
|
|
127
|
+
getClient: () => createClient({ chain, transport: http() }),
|
|
128
|
+
}),
|
|
129
|
+
],
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
await expect(mcp.callTool({ name: 'premium_tool', arguments: {} })).rejects.toThrow(
|
|
133
|
+
'No `account` provided',
|
|
134
|
+
)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
test('error: returns isError for non-payment errors', async () => {
|
|
138
|
+
server.registerTool('broken_tool', { description: 'Broken' }, async () => {
|
|
139
|
+
throw new Error('Internal server error')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const mcp = McpClient.wrap(client, {
|
|
143
|
+
methods: [
|
|
144
|
+
tempo_client.charge({
|
|
145
|
+
account: accounts[1],
|
|
146
|
+
getClient: () => testClient,
|
|
147
|
+
}),
|
|
148
|
+
],
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const result = await mcp.callTool({ name: 'broken_tool', arguments: {} })
|
|
152
|
+
expect(result.isError).toBe(true)
|
|
153
|
+
expect(result.content).toEqual([{ type: 'text', text: 'Internal server error' }])
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
test('error: throws when method not found', async () => {
|
|
157
|
+
const challenge = Challenge.fromIntent(tempo_server.charge({ getClient: () => testClient }), {
|
|
158
|
+
realm,
|
|
159
|
+
secretKey,
|
|
160
|
+
request: {
|
|
161
|
+
amount: '1',
|
|
162
|
+
currency: asset,
|
|
163
|
+
decimals: 6,
|
|
164
|
+
expires: new Date(Date.now() + 60_000).toISOString(),
|
|
165
|
+
recipient: accounts[0].address,
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
server.registerTool('tool_unknown_method', { description: 'Tool' }, async () => {
|
|
170
|
+
throw new McpError(core_Mcp.paymentRequiredCode, 'Payment Required', {
|
|
171
|
+
httpStatus: 402,
|
|
172
|
+
challenges: [{ ...challenge, method: 'unknown_method' }],
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
const mcp = McpClient.wrap(client, {
|
|
177
|
+
methods: [
|
|
178
|
+
tempo_client.charge({
|
|
179
|
+
account: accounts[1],
|
|
180
|
+
getClient: () => testClient,
|
|
181
|
+
}),
|
|
182
|
+
],
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
await expect(mcp.callTool({ name: 'tool_unknown_method', arguments: {} })).rejects.toThrow(
|
|
186
|
+
'No compatible payment method. Server offers: unknown_method.charge. Client has: tempo.charge',
|
|
187
|
+
)
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
describe('isPaymentRequiredError', () => {
|
|
192
|
+
test('returns true for McpError with payment code and challenges', () => {
|
|
193
|
+
const error = new McpError(core_Mcp.paymentRequiredCode, 'Payment Required', {
|
|
194
|
+
httpStatus: 402,
|
|
195
|
+
challenges: [{ id: 'test', method: 'tempo', intent: 'charge', realm: 'test', request: {} }],
|
|
196
|
+
})
|
|
197
|
+
expect(McpClient.isPaymentRequiredError(error)).toBe(true)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
test('returns false for McpError with wrong code', () => {
|
|
201
|
+
const error = new McpError(-32600, 'Invalid Request', {
|
|
202
|
+
challenges: [{ id: 'test', method: 'tempo' }],
|
|
203
|
+
})
|
|
204
|
+
expect(McpClient.isPaymentRequiredError(error)).toBe(false)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('returns false for McpError without challenges', () => {
|
|
208
|
+
const error = new McpError(core_Mcp.paymentRequiredCode, 'Payment Required', {
|
|
209
|
+
httpStatus: 402,
|
|
210
|
+
})
|
|
211
|
+
expect(McpClient.isPaymentRequiredError(error)).toBe(false)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('returns false for non-McpError', () => {
|
|
215
|
+
expect(McpClient.isPaymentRequiredError(null)).toBe(false)
|
|
216
|
+
expect(McpClient.isPaymentRequiredError(new Error('test'))).toBe(false)
|
|
217
|
+
expect(McpClient.isPaymentRequiredError('error')).toBe(false)
|
|
218
|
+
})
|
|
219
|
+
})
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
2
|
+
import type { McpError } from '@modelcontextprotocol/sdk/types.js'
|
|
3
|
+
import type * as Challenge from '../../Challenge.js'
|
|
4
|
+
import * as Credential from '../../Credential.js'
|
|
5
|
+
import * as core_Mcp from '../../Mcp.js'
|
|
6
|
+
import type * as MethodIntent from '../../MethodIntent.js'
|
|
7
|
+
import type * as z from '../../zod.js'
|
|
8
|
+
|
|
9
|
+
type AnyClient = MethodIntent.Client<any, any>
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Result of a tool call with payment handling.
|
|
13
|
+
* Extends the SDK's callTool return type with an optional payment receipt.
|
|
14
|
+
*/
|
|
15
|
+
export type CallToolResult = Awaited<ReturnType<Client['callTool']>> & {
|
|
16
|
+
/** Payment receipt if payment was made. */
|
|
17
|
+
receipt: core_Mcp.Receipt | undefined
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a payment-aware wrapper around an MCP SDK client.
|
|
22
|
+
*
|
|
23
|
+
* Similar to `Fetch.from()` for HTTP, this wraps an MCP client's `callTool`
|
|
24
|
+
* method to automatically handle payment challenges.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { Client } from '@modelcontextprotocol/sdk/client'
|
|
29
|
+
* import { McpClient, tempo } from 'mppx/mcp-sdk/client'
|
|
30
|
+
* import { privateKeyToAccount } from 'viem/accounts'
|
|
31
|
+
*
|
|
32
|
+
* const client = new Client({ name: 'my-client', version: '1.0.0' })
|
|
33
|
+
* await client.connect(transport)
|
|
34
|
+
*
|
|
35
|
+
* const mcp = McpClient.wrap(client, {
|
|
36
|
+
* methods: [
|
|
37
|
+
* tempo({
|
|
38
|
+
* account: privateKeyToAccount('0x...'),
|
|
39
|
+
* }),
|
|
40
|
+
* ],
|
|
41
|
+
* })
|
|
42
|
+
*
|
|
43
|
+
* // Automatically handles payment challenges
|
|
44
|
+
* const result = await mcp.callTool({ name: 'premium_tool', arguments: {} })
|
|
45
|
+
* console.log(result.content, result.receipt)
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function wrap<
|
|
49
|
+
const client extends Pick<Client, 'callTool'>,
|
|
50
|
+
const methods extends readonly MethodIntent.AnyClient[],
|
|
51
|
+
>(client: client, config: wrap.Config<methods>): wrap.McpClient<client, methods> {
|
|
52
|
+
const { methods } = config
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
...client,
|
|
56
|
+
async callTool(params, options) {
|
|
57
|
+
const context = options?.context
|
|
58
|
+
const timeout = options?.timeout
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const result = await client.callTool(
|
|
62
|
+
params,
|
|
63
|
+
undefined,
|
|
64
|
+
timeout !== undefined ? { timeout } : undefined,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
...result,
|
|
69
|
+
receipt: result._meta?.[core_Mcp.receiptMetaKey] as core_Mcp.Receipt | undefined,
|
|
70
|
+
}
|
|
71
|
+
} catch (error) {
|
|
72
|
+
// Check if this is a payment required error
|
|
73
|
+
if (!isPaymentRequiredError(error)) throw error
|
|
74
|
+
|
|
75
|
+
const challenges = (error.data as { challenges?: Challenge.Challenge[] })?.challenges
|
|
76
|
+
if (!challenges?.length) throw error
|
|
77
|
+
|
|
78
|
+
// Select first challenge that matches an installed method intent
|
|
79
|
+
const challenge = challenges.find((c) =>
|
|
80
|
+
methods.some((m) => m.method === c.method && m.name === c.intent),
|
|
81
|
+
)
|
|
82
|
+
if (!challenge) {
|
|
83
|
+
const available = challenges.map((c) => `${c.method}.${c.intent}`).join(', ')
|
|
84
|
+
const installed = methods.map((m) => `${m.method}.${m.name}`).join(', ')
|
|
85
|
+
throw new Error(
|
|
86
|
+
`No compatible payment method. Server offers: ${available}. Client has: ${installed}`,
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const credential = await createCredential(challenge, { context, methods })
|
|
91
|
+
const parsed = Credential.deserialize(credential)
|
|
92
|
+
|
|
93
|
+
const retryResult = await client.callTool(
|
|
94
|
+
{
|
|
95
|
+
...params,
|
|
96
|
+
_meta: {
|
|
97
|
+
...params._meta,
|
|
98
|
+
[core_Mcp.credentialMetaKey]: parsed,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
undefined,
|
|
102
|
+
timeout !== undefined ? { timeout } : undefined,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
...retryResult,
|
|
107
|
+
receipt: retryResult._meta?.[core_Mcp.receiptMetaKey] as core_Mcp.Receipt | undefined,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Union of all context types from all methods that have context schemas. */
|
|
115
|
+
type AnyContextFor<methods extends readonly AnyClient[]> = {
|
|
116
|
+
[key in keyof methods]: methods[key] extends MethodIntent.Client<any, infer context>
|
|
117
|
+
? context extends z.ZodMiniType
|
|
118
|
+
? z.input<context>
|
|
119
|
+
: undefined
|
|
120
|
+
: undefined
|
|
121
|
+
}[number]
|
|
122
|
+
|
|
123
|
+
export declare namespace wrap {
|
|
124
|
+
type Config<
|
|
125
|
+
methods extends readonly MethodIntent.AnyClient[] = readonly MethodIntent.AnyClient[],
|
|
126
|
+
> = {
|
|
127
|
+
/** Array of method intents to use. */
|
|
128
|
+
methods: methods
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type McpClient<
|
|
132
|
+
client extends Pick<Client, 'callTool'> = Pick<Client, 'callTool'>,
|
|
133
|
+
methods extends readonly AnyClient[] = readonly AnyClient[],
|
|
134
|
+
> = Omit<client, 'callTool'> & {
|
|
135
|
+
/** Call a tool with automatic payment handling. */
|
|
136
|
+
callTool: (
|
|
137
|
+
params: {
|
|
138
|
+
name: string
|
|
139
|
+
arguments?: Record<string, unknown>
|
|
140
|
+
_meta?: Record<string, unknown>
|
|
141
|
+
},
|
|
142
|
+
options?: CallToolOptions<methods>,
|
|
143
|
+
) => Promise<CallToolResult>
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
type CallToolOptions<methods extends readonly AnyClient[] = readonly AnyClient[]> = {
|
|
147
|
+
/** Context to pass to the method intent's createCredential. */
|
|
148
|
+
context?: AnyContextFor<methods>
|
|
149
|
+
/** Request timeout in milliseconds. */
|
|
150
|
+
timeout?: number
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Checks if an error is a payment required error.
|
|
156
|
+
*/
|
|
157
|
+
export function isPaymentRequiredError(
|
|
158
|
+
error: unknown,
|
|
159
|
+
): error is McpError & { data: { challenges: Challenge.Challenge[] } } {
|
|
160
|
+
if (typeof error !== 'object' || error === null) return false
|
|
161
|
+
if (!('code' in error) || !('message' in error)) return false
|
|
162
|
+
if ((error as { code: unknown }).code !== core_Mcp.paymentRequiredCode) return false
|
|
163
|
+
const data = (error as { data?: { challenges?: unknown } }).data
|
|
164
|
+
return Array.isArray(data?.challenges) && data.challenges.length > 0
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** @internal */
|
|
168
|
+
async function createCredential<methods extends readonly MethodIntent.AnyClient[]>(
|
|
169
|
+
challenge: Challenge.Challenge,
|
|
170
|
+
config: {
|
|
171
|
+
context?: unknown
|
|
172
|
+
methods: methods
|
|
173
|
+
},
|
|
174
|
+
): Promise<string> {
|
|
175
|
+
const { context, methods } = config
|
|
176
|
+
|
|
177
|
+
const mi = methods.find((m) => m.method === challenge.method && m.name === challenge.intent)
|
|
178
|
+
if (!mi)
|
|
179
|
+
throw new Error(
|
|
180
|
+
`No method intent found for "${challenge.method}.${challenge.intent}". Available: ${methods.map((m) => `${m.method}.${m.name}`).join(', ')}`,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
const parsedContext = mi.context && context !== undefined ? mi.context.parse(context) : undefined
|
|
184
|
+
return mi.createCredential(
|
|
185
|
+
parsedContext !== undefined ? { challenge, context: parsedContext } : ({ challenge } as never),
|
|
186
|
+
)
|
|
187
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { CallToolResult, McpError } from '@modelcontextprotocol/sdk/types.js'
|
|
2
|
+
import type * as Credential from '../../Credential.js'
|
|
3
|
+
import * as core_Mcp from '../../Mcp.js'
|
|
4
|
+
import * as Transport from '../../server/Transport.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MCP SDK tool handler "extra" parameter.
|
|
8
|
+
* Compatible with `@modelcontextprotocol/sdk` RequestHandlerExtra.
|
|
9
|
+
*/
|
|
10
|
+
export type Extra = {
|
|
11
|
+
_meta?:
|
|
12
|
+
| {
|
|
13
|
+
[core_Mcp.credentialMetaKey]?: Credential.Credential
|
|
14
|
+
[key: string]: unknown
|
|
15
|
+
}
|
|
16
|
+
| undefined
|
|
17
|
+
[key: string]: unknown
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type McpSdk = Transport.Transport<Extra, McpError, CallToolResult>
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* MCP SDK transport for server-side payment handling with `@modelcontextprotocol/sdk`.
|
|
24
|
+
*
|
|
25
|
+
* - Reads credentials from `_meta["org.paymentauth/credential"]`
|
|
26
|
+
* - Issues challenges as `McpError` with code `-32042` and challenge in `error.data`
|
|
27
|
+
* - Attaches receipts via `_meta["org.paymentauth/receipt"]` on tool results
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { McpServer } from '@modelcontextprotocol/sdk/server/mcp'
|
|
32
|
+
* import { Mppx, Transport } from 'mppx/server'
|
|
33
|
+
*
|
|
34
|
+
* const payment = Mppx.create({
|
|
35
|
+
* method: tempo(),
|
|
36
|
+
* secretKey: process.env.SECRET_KEY,
|
|
37
|
+
* transport: Transport.mcpSdk(),
|
|
38
|
+
* })
|
|
39
|
+
*
|
|
40
|
+
* server.registerTool('premium', { description: '...' }, async (extra) => {
|
|
41
|
+
* const result = await payment.charge({ request: { ... } })(extra)
|
|
42
|
+
* if (result.status === 402) throw result.challenge
|
|
43
|
+
* return result.withReceipt({ content: [...] })
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function mcpSdk(): McpSdk {
|
|
48
|
+
let McpErrorClass: typeof McpError | undefined
|
|
49
|
+
|
|
50
|
+
return Transport.from<Extra, McpError, CallToolResult>({
|
|
51
|
+
name: 'mcp-sdk',
|
|
52
|
+
|
|
53
|
+
getCredential(extra) {
|
|
54
|
+
const credential = extra._meta?.[core_Mcp.credentialMetaKey]
|
|
55
|
+
if (!credential) return null
|
|
56
|
+
return credential
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async respondChallenge({ challenge, error }) {
|
|
60
|
+
if (!McpErrorClass) {
|
|
61
|
+
try {
|
|
62
|
+
const mod = await import('@modelcontextprotocol/sdk/types.js')
|
|
63
|
+
McpErrorClass = mod.McpError
|
|
64
|
+
} catch (error) {
|
|
65
|
+
const err = new Error(
|
|
66
|
+
'Missing optional dependency "@modelcontextprotocol/sdk". Install it to use mppx MCP SDK transports.',
|
|
67
|
+
)
|
|
68
|
+
;(err as Error & { cause?: unknown }).cause = error
|
|
69
|
+
throw err
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return new McpErrorClass(core_Mcp.paymentRequiredCode, error?.message ?? 'Payment Required', {
|
|
73
|
+
httpStatus: 402,
|
|
74
|
+
challenges: [challenge],
|
|
75
|
+
...(error && { problem: error.toProblemDetails(challenge.id) }),
|
|
76
|
+
})
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
respondReceipt({ receipt, response, challengeId }) {
|
|
80
|
+
const mcpReceipt: core_Mcp.Receipt = {
|
|
81
|
+
...receipt,
|
|
82
|
+
challengeId,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
...response,
|
|
87
|
+
_meta: {
|
|
88
|
+
...response._meta,
|
|
89
|
+
[core_Mcp.receiptMetaKey]: mcpReceipt,
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Transport from './Transport.js'
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Context } from 'elysia'
|
|
2
|
+
import * as Mppx_core from '../server/Mppx.js'
|
|
3
|
+
import * as Mppx_internal from './internal/mppx.js'
|
|
4
|
+
|
|
5
|
+
export * from '../server/Methods.js'
|
|
6
|
+
|
|
7
|
+
type ElysiaHook = (context: Context) => Promise<Response | undefined>
|
|
8
|
+
|
|
9
|
+
export namespace Mppx {
|
|
10
|
+
/**
|
|
11
|
+
* Creates an Elysia-aware payment handler where each intent
|
|
12
|
+
* returns an Elysia `beforeHandle` hook.
|
|
13
|
+
*
|
|
14
|
+
* Use with `.guard()` to scope payment to specific routes,
|
|
15
|
+
* or `.onBeforeHandle()` to apply globally.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { Elysia } from 'elysia'
|
|
20
|
+
* import { Mppx, tempo } from 'mppx/elysia'
|
|
21
|
+
*
|
|
22
|
+
* const mppx = Mppx.create({ methods: [tempo()] })
|
|
23
|
+
*
|
|
24
|
+
* const app = new Elysia()
|
|
25
|
+
* .guard(
|
|
26
|
+
* { beforeHandle: mppx.charge({ amount: '1' }) },
|
|
27
|
+
* (app) => app.get('/premium', () => ({ data: 'paid content' })),
|
|
28
|
+
* )
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function create<const methods extends Mppx_core.Methods>(
|
|
32
|
+
config: Mppx_core.create.Config<methods>,
|
|
33
|
+
): Mppx_internal.Wrap<Mppx_core.Mppx<methods>, ElysiaHook> {
|
|
34
|
+
return Mppx_internal.wrap(Mppx_core.create(config), payment)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Elysia `beforeHandle` hook that gates a route behind a payment intent.
|
|
40
|
+
*
|
|
41
|
+
* Returns a 402 challenge if no valid credential is provided.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* import { Elysia } from 'elysia'
|
|
46
|
+
* import { Mppx } from 'mppx/server'
|
|
47
|
+
* import { payment } from 'mppx/elysia'
|
|
48
|
+
*
|
|
49
|
+
* const mppx = Mppx.create({ methods: [tempo()] })
|
|
50
|
+
*
|
|
51
|
+
* const app = new Elysia()
|
|
52
|
+
* .guard(
|
|
53
|
+
* { beforeHandle: payment(mppx.charge, { amount: '1' }) },
|
|
54
|
+
* (app) => app.get('/premium', () => ({ data: 'paid content' })),
|
|
55
|
+
* )
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function payment<const intent extends Mppx_internal.AnyIntentFn>(
|
|
59
|
+
intent: intent,
|
|
60
|
+
options: intent extends (options: infer options) => any ? options : never,
|
|
61
|
+
): ElysiaHook {
|
|
62
|
+
return async ({ request }) => {
|
|
63
|
+
const result = await intent(options)(request)
|
|
64
|
+
if (result.status === 402) return result.challenge
|
|
65
|
+
}
|
|
66
|
+
}
|