Ecosystem
MCP Marketplace
Publish a context server so agents can use Vexo data, with the wearer holding the keys.

What an MCP server sees
A marketplace server is a standard MCP server with one difference: every tool call arrives with a wearer-scoped token, vx_user_9f2k…, minted from a live grant. Your server never holds credentials of its own for a wearer. If the grant covers the scope, the call succeeds. If it does not, the platform rejects it before your handler runs.
Three tool types are exposed to agents. You implement the handlers, Vexo enforces the scope boundary around them.
| Name | Type | Description |
|---|---|---|
| context.read | tool | One-shot read of a derived metric window the wearer has granted, for example the last 24 hours of HRV. Agents call it, get typed JSON, and the read is logged to the wearer's activity feed. |
| context.subscribe | tool | A live stream of granted signals for the duration of an agent session. Closes with code 4403 the moment the wearer revokes, mid-message if necessary. |
| context.summarize | tool | A server-side rollup, for example "sleep quality this week: declining". Your code shapes the summary, Vexo enforces that only granted families feed it. |
Every invocation is logged to the wearer's activity feed with the tool name and scope used.
Scaffold a server
Scaffold the project
One command creates a typed project with the manifest, a sample tool, and a simulated wearer for local runs.
npx @vexoring/create-mcp sleep-coach # ✔ Scaffolded sleep-coach/ # vexo.mcp.ts tool definitions # mcp.manifest.json scopes, retention, pricing # .env.example VEXO_CLIENT_ID, VEXO_APP_TOKENDefine tools
Tools live in
vexo.mcp.ts. Each declares the scopes it needs, an input schema, and a handler that receives a wearer-scoped SDK client.Tool definitionsvexo.mcp.tsimport { defineServer, tool } from "@vexoring/create-mcp"; import { z } from "zod"; export default defineServer({ name: "sleep-coach", tools: [ tool({ name: "context.read", description: "Read the wearer's sleep and HRV window.", scopes: ["biometrics:hrv", "biometrics:temp"], input: z.object({ window: z.enum(["24h", "7d", "30d"]).default("7d"), }), async handler({ window }, { vexo }) { const hrv = await vexo.biometrics.read("hrv", { window }); return { window, hrv: hrv.summary }; // e.g. { median: 61, trend: "up" } }, }), tool({ name: "context.summarize", description: "Plain-language sleep readiness for this morning.", scopes: ["biometrics:hrv"], async handler(_, { vexo }) { const night = await vexo.biometrics.read("hrv", { window: "24h" }); return { readiness: night.summary.median > 55 ? "recovered" : "take it easy", }; }, }), ], });Run locally
vexo devserves the MCP endpoint with a simulated wearer whose grants you can toggle, so you can test revocation without a physical ring.vexo dev # ▸ sleep-coach listening on http://localhost:7823/mcp # ▸ 2 tools registered: context.read, context.summarize # ▸ scopes in manifest: biometrics:hrv, biometrics:temp # ▸ simulated wearer "test-wearer-01" granted all scopes
Manifest reference
The manifest is your public contract. It is rendered word for word on the wearer's grant screen and checked against your code at review time, so write it as the promise it is.
{
"name": "sleep-coach",
"version": "1.2.0",
"description": "Morning readiness summaries from overnight HRV and skin temperature.",
"scopes": ["biometrics:hrv", "biometrics:temp"],
"dataRetention": {
"policy": "ephemeral",
"maxSeconds": 0
},
"pricing": {
"model": "per-call",
"amountUsd": 0.002
},
"endpoints": {
"mcp": "https://sleep-coach.yourapp.com/mcp"
}
}Manifest fields
| Name | Type | Description |
|---|---|---|
| namerequired | string | Unique slug in the marketplace, lowercase with hyphens. Shown to wearers on the grant screen exactly as written. |
| scopesrequired | string[] | Every scope your tools reference, and nothing more. A tool that requests a scope missing from this list fails to register. |
| dataRetentionrequired | object | Declared policy: ephemeral, session, or stored with maxSeconds. Wearers see it verbatim, and review checks your code against it. |
| pricing | object | per-call, subscription, or free. Billed to the calling agent's owner, never to the wearer.Default: free |
Changing scopes or dataRetention in a new version triggers re-review and re-consent from every wearer.
Review and publish
/v1/marketplace/serversSubmit with vexo publish or the endpoint above. Review usually takes two business days and holds three bars: scope minimality, every scope in the manifest must be exercised by a tool. Retention honesty, your code must match the declared dataRetention policy. Plain language, descriptions must say what the server does in words a wearer can act on.
Revenue
Paid servers bill the calling agent's owner per call or per month, set in the manifest's pricing block. Vexo takes 15 percent, pays out monthly at a 25 dollar minimum, and never charges the wearer. Usage and earnings live in the developer dashboard next to your consent metrics, because in this marketplace the two rise together.
Ship something people would consent to twice.
