Skip to main content

Spin/WASI host adapter for tollbooth-dpyc Operators — deploy a DPYC operator to Fermyon Spin / Akamai Functions with just business logic.

Project description

tollbooth-wasmcp

The Spin/WASI host for tollbooth-dpyc Operators.

A DPYC Operator is business logic — a set of priced MCP tools over the tollbooth-dpyc runtime. On Prefect Horizon, FastMCP is the host that turns that logic into a running MCP server. tollbooth-wasmcp is the peer host for Fermyon Spin / Akamai Functions: it lets the same operator code deploy as a WebAssembly component, reusing the tollbooth-dpyc wheel untouched. Write the operator once; pick the host.

FastMCP's edge jobs — derive the tool schema from your typed functions, coerce inbound args, run the transport — are done here by the adapter (get_type_hints-based schema + pydantic-lite coercion + a WASI transport). Same source of truth (your tool functions' hints + docstrings), a second host projection of it. The operator never writes either.

Writing an operator

import tollbooth_wasmcp                      # FIRST import — installs the pre-init seams
from tollbooth_wasmcp import SpinOperatorHost
from tollbooth.tool_identity import ToolIdentity, capability_uuid
import weather                               # your domain client

_DOMAIN = { UUID: ToolIdentity(tool_id=UUID, capability="get_current_weather", category="read", intent="…"),  }

host = SpinOperatorHost(service_name="my-operator", slug="myslug", domain_tools=_DOMAIN)
tool = host.tool

@tool
@host.runtime.paid_tool(capability_uuid("get_current_weather"))
async def current(latitude: float, longitude: float, npub: str = "", dpop_token: str = ""):
    return await weather.get_current(latitude, longitude)

Tools = host.tools_export()                  # the wasmcp exports.Tools surface

That is the FastMCP tollbooth-sample server, line for line, with SpinOperatorHost(…) where the FastMCP operator writes FastMCP(…) and Tools = host.tools_export() where it writes mcp.run(). See examples/weather-operator for the complete, runnable version.

What the host provides

Importing tollbooth_wasmcp installs — in order, before the wheel imports — every seam the componentize-py build needs, none of which the WASI Python interpreter has natively:

  • httpx over wasi:http — every wheel HTTP call (registry, bridge, Neon, upstream APIs).
  • dpyc:crypto component — a Rust WASI component (NIP-04 ECDH, BIP-340 schnorr verify, AES-CBC/GCM) standing in for coincurve/cryptography. Shipped prebuilt as tollbooth_wasmcp/crypto.wasm.
  • nsec-only bootstrapensure_bootstrapped fetches the operator's encrypted config event through an HTTPS→Nostr-relay bridge Worker and decrypts it with the crypto component (the operator holds only its nsec; the Neon URL is discovered, never configured).
  • schema + coerciontool_schema (correct JSON types even under the wheel's PEP 563 annotations) and bind_args (coerce "90"90 for an int param), the FastMCP/pydantic edge jobs.
  • snapshot fixes — force-bundle the wheel's lazily-imported submodules, pin the wheel version, read config from the live WASI environment (spin up --env) each call.
  • PROOF_DEBUG (opt-in, off by default) — a rejected proof explains which sub-check failed.

Building an operator (out-of-repo)

pip install tollbooth-wasmcp                 # into your build's deps/ (--target deps)
# then in your Makefile:
componentize-py --wit-path $(python -m tollbooth_wasmcp.paths wit) --world operator \
  componentize app -p . -p deps -p $(python -m tollbooth_wasmcp.paths toplevel) -o operator.wasm
wac plug operator.wasm --plug $(python -m tollbooth_wasmcp.paths crypto) -o plugged.wasm
wasmcp compose server plugged.wasm -o server.wasm

Run (the operator is nsec-only — supply the nsec + bridge URL at run time, never in the manifest):

# start the bridge in bridge/:  npx wrangler dev --port 8799 --local
spin up --env TOLLBOOTH_NOSTR_OPERATOR_NSEC=<nsec> --env BRIDGE_URL=http://localhost:8799

Requires componentize-py, wac, wasmcp, and spin on PATH. The standardized WIT world imports wasi:http, dpyc:crypto, wasi:cli/environment, and wasi:config/store; do not run componentize-py bindings separately (it clobbers the vendored poll_loop.py).

Repo layout

tollbooth_wasmcp/       the adapter (PyPI package): SpinOperatorHost, schema, binding, seams
  _toplevel/            pynostr + cryptography shims the wheel imports by top-level name
  wit/                  the standardized DPYC Spin WIT world + deps
  crypto.wasm           prebuilt dpyc:crypto component (from crypto/)
crypto/                 Rust source for the dpyc:crypto component
bridge/                 the HTTPS→Nostr-relay bridge Cloudflare Worker
examples/weather-operator/   a complete reference operator using SpinOperatorHost
tests/                  schema/coercion unit tests (incl. FastMCP parity)

Apache-2.0. Part of the DPYC ecosystem.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tollbooth_wasmcp-0.1.4.tar.gz (131.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tollbooth_wasmcp-0.1.4-py3-none-any.whl (111.4 kB view details)

Uploaded Python 3

File details

Details for the file tollbooth_wasmcp-0.1.4.tar.gz.

File metadata

  • Download URL: tollbooth_wasmcp-0.1.4.tar.gz
  • Upload date:
  • Size: 131.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tollbooth_wasmcp-0.1.4.tar.gz
Algorithm Hash digest
SHA256 ad1db9ffc45856812d5b24b7c1f8b1a681604c88b85f93626ac8283692ffa672
MD5 1ddd75510b0442ccd268645ed7d0837b
BLAKE2b-256 375f0d12a58cc06b8ebbff8ec16eba7f77e8e3220ad1c12fa3752f2889a10bcb

See more details on using hashes here.

Provenance

The following attestation bundles were made for tollbooth_wasmcp-0.1.4.tar.gz:

Publisher: release.yml on lonniev/tollbooth-wasmcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tollbooth_wasmcp-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for tollbooth_wasmcp-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 0060a70a12a77493a3eed1d4dba6d99dcf540e44cba56bec59e3c346e972f46a
MD5 788050b6243b0c9184816aa7669435e4
BLAKE2b-256 a9a79983ddbab50755936b6af34f676a5fbf36b10935e548599be441b54d7e89

See more details on using hashes here.

Provenance

The following attestation bundles were made for tollbooth_wasmcp-0.1.4-py3-none-any.whl:

Publisher: release.yml on lonniev/tollbooth-wasmcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page