Download the PHP package sandermuller/laravel-x402-mcp without Composer

On this page you can find all versions of the php package sandermuller/laravel-x402-mcp. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-x402-mcp

laravel-x402-mcp

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Gate laravel/mcp tools behind x402 stablecoin payments. Conformant with the x402 v2 MCP transport spec (specs/transports-v2/mcp.md).

Bridge between sandermuller/laravel-x402 (^0.5) and laravel/mcp (^0.6 || ^0.7). Annotate paid tools with the #[X402Price] attribute. Agents include the signed payment payload in params._meta["x402/payment"] (JSON-RPC level — not an HTTP header). The advertised price travels back on tools/list / resources/list / prompts/list via _meta["x402/price"].

Install

The bridge inherits its facilitator wiring, recipient address, and asset config from laravel-x402. Run that package's installer first:

This sets X402_RECIPIENT and (optionally) X402_PRIVATE_KEY in .env and publishes the config/x402.php file. Verify with php artisan x402:verify-config.

Usage

1. Annotate a paid tool

payTo overrides the global x402.recipient for a specific tool:

2. Wire the gating method handlers on your Server

The WithX402Payment trait registers six method handlers when the server starts:

The trait hooks on start(), not boot(), so any subclass overriding boot() still gets x402 gating without having to know about this trait. If you want to opt out of trait defaults — for example to register your own tools/call handler — use addMethod() inside boot(); explicit registrations made there win over the trait. If you also override start(), call parent::start() so the trait runs.

Gating resources and prompts

The same #[X402Price] attribute applies to Resource and Prompt subclasses:

Differences from tool gating:

3. What X402CallTool does

  1. Looks up the invoked tool, checks for #[X402Price].
  2. If unpriced — passes through to the standard CallTool.
  3. If priced — reads params._meta["x402/payment"] for the signed payload, verifies + settles via the bound FacilitatorClient, then runs the tool.
  4. On success, injects result._meta["x402/payment-response"] with the settlement receipt.
  5. On any failure, returns a tool result with isError: true + structuredContent: PaymentRequired + content[0].text (JSON-stringified).

The replay store from laravel-x402 is reused — concurrent requests with the same authorization are rejected before hitting the facilitator.

Post-settle tool failure

Settlement happens before the tool runs. If the tool throws after the facilitator has settled, the payment has already moved on-chain and is not refundable from this layer. The settlement receipt always lands on the response — every Throwable thrown by the tool (synchronous or mid-stream in a generator) is caught, returned as a tool error result, and stamped with result._meta["x402/payment-response"] so agents can prove the payment settled even when delivery failed. Two exceptions to that guarantee:

This ordering is by design: the x402 settle is the canonical proof of payment, and the spec requires it to be observable independently of tool execution. If your tool needs transactional "execute-or-refund" semantics, do the work in two steps — settle the user into a credit balance first, debit on successful execution — rather than relying on this layer.

Wire format

Per specs/transports-v2/mcp.md:

Direction Location Shape
Client → Server (payment) params._meta["x402/payment"] PaymentPayload v2 envelope
Server → Client (settled) result._meta["x402/payment-response"] {success, transaction, network, payer}
Server → Client (required) result.structuredContent + result.content[0].text + result.isError = true PaymentRequired
Server → Client (advertised) _meta["x402/price"] on each item of tools/list / resources/list / prompts/list {amount, asset, network[, payTo]}

The same _meta["x402/payment"] / _meta["x402/payment-response"] envelope and the same 402 challenge shape apply to resources/read and prompts/get — the gating mirrors tools/call 1:1, only the challenge resource URI differs (resources use the request URI verbatim; prompts use mcp://prompt/{name}).

The HTTP-level PAYMENT-SIGNATURE / PAYMENT-RESPONSE headers used by the x402 HTTP transport are NOT used in MCP — payment travels at the JSON-RPC layer, inside the request/response body.

Idempotency

A transport drop between facilitator-settle and JSON-RPC delivery would otherwise leave the user paid without recourse: the agent retries the same signed authorization, the replay-guard rejects the duplicate nonce with replay_attempt, and there's no path back. The bundled PaidToolResponseCache closes that gap — the same idea as laravel-x402 0.3's x402.cache middleware, applied to JSON-RPC tools/call, resources/read, and prompts/get.

How it works:

  1. Before claiming the nonce, the handler computes a CacheScope (tools/call|mcp://tool/{name}|sha256(canonical_args) etc.) and looks up a cached response keyed by (scope, signature).
  2. On HIT: rebuild the cached JsonRpcResponse with the new request's id and return it. No facilitator round-trip, no nonce burn.
  3. On MISS: claim the nonce, settle, run the primitive, store the result under (scope, signature), return.

What's pinned in the key:

What's NOT cached:

Configuration. The cache-store name and TTL are shared with laravel-x402's HTTP middleware (one knob across both transports); the cache prefix is MCP-namespaced so HTTP and JSON-RPC consumers can co-exist on a shared Redis without colliding.

Key Default Effect
x402.response_cache.cache_store null (Laravel default store) PSR-16-bridged store name
x402.response_cache.ttl 3600 Idempotency window in seconds
x402_mcp.response_cache.prefix x402:idem:mcp: JSON-RPC cache-key prefix

The store binding is via laravel-x402's LaravelPsr16Bridge over Illuminate's cache repository — bind any PSR-16 backend (Redis, file, array). The TTL must comfortably exceed the nonce-store's TTL so a retry that arrives after the nonce expires still hits the response cache. Use a persistent store (Redis) in production; the array driver is process-local and only useful in tests.

Stdio transport

Stdio MCP servers can also receive _meta["x402/payment"] because _meta is a JSON-RPC field, not an HTTP envelope. Paid tools work on stdio as well as HTTP.

Operator commands

Lists every tool, resource, and prompt on the given Server class with a Type column, marking gated entries with their amount, asset, network, and payTo (or (default) when not overridden). Free entries render as (free). Mirrors x402:list-routes from laravel-x402 for the JSON-RPC transport.

Testing

laravel-x402 ships a recording fake. Swap it in once at the top of a test and the bridge picks it up automatically:

PaymentSettled / PaymentRejected events still fire through DispatchingFacilitator, so Event::fake([PaymentSettled::class]) composes alongside.

License

MIT.


All versions of laravel-x402-mcp with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
sandermuller/laravel-x402 Version ^0.5
laravel/mcp Version ^0.6 || ^0.7
illuminate/support Version ^11.0|^12.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package sandermuller/laravel-x402-mcp contains the following files

Loading the files please wait ...