Developers · publishers
Build plugins for agents that run on their owners’ machines.
One extension system, three reviewed ways into it, and a price you set. Every capability you ship runs through the same Toolspace as the built-in ones.
08What a submission carries
Read by a person · immutable once submitted
- Repository
- Your source, public or reviewed privately
- Fork
- ShiftAboveCtrl/ai17z, for in-core work
- Commit
- The full 40-character SHA under review
- Manifest
- Exact bytes, stored with their SHA-256
- Capabilities
plugin_<id>.<name>, typed in and out- Permissions
- Hosts, effect and risk, read off the manifest
- Compatibility
- Minimum AI17Z version, optional ceiling
- Pricing
- Free, or one-time, monthly or yearly, priced in ETH
Workflow
From application to a published version.
- 01you
Apply
Tell us who you are and what you will build. A person verifies you before anything can be published.
publisher application
- 02you
Build
Write a Plugin manifest, a hosted capability, or fork ShiftAboveCtrl/ai17z for an in-core integration.
manifest · gateway · fork
- 03you
Submit
An exact version: manifest bytes or commit + pull request, permissions, disclosures, tests, compatibility and price.
immutable once submitted
- 04Studio admin
Review
An admin reads the exact bytes, the hosts, the data handling and the tests, and classifies the risk.
LOW · MEDIUM · HIGH
- 05Studio admin
Publish
Approved versions go live and never change. Fixes are new versions, reviewed again.
free, one-time, monthly or yearly
- Fork & build Start from ShiftAboveCtrl/ai17z when your capability belongs in core.
- Plugin manifest v1 The declarative contract AI17Z already installs from.
- Registry documentation Plugins, the registry protocol and the Toolspace, from the source.
- Apply to publish Get verified, then list your first plugin.
Delivery
Three delivery modes. One review.
Pick by what your capability needs. Each is reviewed version by version, and none of them runs publisher code on an owner’s machine.
| Declarative plugin | Hosted capability | In-core integration | |
|---|---|---|---|
| Mode | REGISTRY_MANIFEST | HOSTED_GATEWAY | IN_CORE_INTEGRATION |
| You ship | A Plugin manifest (schema v1): typed input and output, one GET or POST, a host allowlist, a timeout and an hourly quota. | A backend that answers; the Studio Tool Gateway calls it with your sealed vendor credentials and validates the answer. | A capability family in a fork of ShiftAboveCtrl/ai17z, against the real contracts. |
| Runs | In AI17Z’s own bounded network layer. READ only. | On your backend, behind the gateway. Customers never see your secrets or URL. | Inside AI17Z, once merged and released. |
| Needs | Any current AI17Z with the registry set to Studio. | AI17Z builds with Studio linking (installation keys + DPoP). | A reviewed pull request and a canonical release. |
A declarative plugin
The manifest is the whole plugin.
.strict() throughout: an unknown field is a refusal. The id becomes your listing’s permanent id; publisher must be your verified publisher name exactly. Capabilities register as plugin_<id>.<name>, a reserved family.
- Hosts are bare hostnames: no scheme, port, path or wildcard.
- The allowlist is checked on the built URL and again on the address that answered.
- Private addresses and plain http are refused at fetch time, whatever you declare.
- A credential slot must name a config field marked
secret. - Responses are capped at 512 KB. Updates that ask for more must be re-approved by the owner.
Contract source: packages/shared/src/contracts/plugins.ts. Studio validates submissions with a line-for-line port of it.
{
"schemaVersion": 1,
"id": "open-meteo",
"name": "Open-Meteo",
"summary": "Current weather and forecasts for a latitude and longitude.",
"publisher": "Your verified publisher name",
"version": "1.0.0",
"compatibility": { "minimum": "1.0.0" },
"kind": "HTTP_CAPABILITY",
"capabilities": [
{
"name": "read_forecast",
"title": "Read a forecast",
"description": "Reads the current temperature and forecast for a location.",
"category": "RESEARCH",
"effect": "READ",
"risk": "LOW",
"input": { "fields": [
{ "name": "latitude", "type": "number", "required": true },
{ "name": "longitude", "type": "number", "required": true }
] },
"output": { "fields": [
{ "name": "temperature", "type": "number", "from": "current.temperature_2m" }
] },
"http": {
"method": "GET",
"url": "https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t=temperature_2m",
"hosts": ["api.open-meteo.com"],
"timeoutMs": 10000,
"quotaPerHour": 60
}
}
]
}
An in-core integration
Declare it, implement run, register it, test it.
A capability is a typed input, a typed output, a permission, a readiness answer and an audit row, invoked through invokeCapability and nothing else. Network access goes through ask() and safeFetch, which already own rate limits, caching, retries, provenance and size limits.
- Contract
packages/tools/src/capability.ts- Registry
packages/tools/src/capabilityRegistry.ts- Invocation
packages/tools/src/invoke.ts- Your family
packages/runtime/src/*Capabilities.ts- Upstreams
packages/upstream/src/families/- Permissions
packages/runtime/src/capabilityPermissions.ts
import { z } from 'zod';
import { defineCapability } from '@xbam/tools';
export const readForecast = defineCapability({
id: 'weather.read_forecast', // family.verb_noun
name: 'Read a forecast',
description: 'Current temperature for a latitude and longitude.',
category: 'RESEARCH',
effect: 'READ',
risk: 'LOW',
input: z.object({ latitude: z.number(), longitude: z.number() }).strict(),
output: z.object({ temperature: z.number() }).strict(),
modelCallable: true,
timeoutMs: 10_000,
async run(input, ctx) {
const answer = await ask('weather_forecast', input); // through the Toolspace, never raw fetch
return { temperature: answer.value.temperature };
},
});
Prove it
What a submission carries.
- The exact manifest text — Studio stores its SHA-256 and serves those bytes, unchanged, forever.
- For in-core work: the pull request URL and the full 40-character commit SHA under review.
- Capability ids, permissions, network hosts and a plain-language data-handling disclosure.
- Test evidence: which tests you wrote and the command a reviewer runs.
- A changelog, an AI17Z compatibility range, and your requested price.
npm test # unit + integration, against real Postgres
npm run typecheck
What review checks
A person reads every version.
- That the code or manifest does what the listing says, and nothing else.
- Permissions and hosts are the minimum needed; READ-only where declared.
- The data disclosure matches the behaviour.
- Tests exist and pass at the submitted commit.
- Risk class — LOW, MEDIUM or HIGH — recorded with the approval.
Approved versions are immutable — enforced in the database, not just the UI. Fixes are new versions.
Out of bounds
What no plugin can reach.
Properties of the system, not rules in a policy document.
- The owner’s filesystem, shell, Chrome profile or X cookies.
- The master key, provider API keys, or another agent’s memories.
- Prompts, private memory or conversation history — for marketplace analytics or anything else.
- Any host it did not declare, any private address, or plain http.
- Executing downloaded code: no eval, no dynamic import, no postinstall, no WRITE effects in schema v1.
For AI17Z itself
The Studio APIs a linked installation uses.
All outbound from the installation. Studio never connects in.
| Endpoint | Purpose | Auth |
|---|---|---|
GET /api/v1/plugins | Plugin Registry protocol v1 catalogue — what AI17Z’s Plugins screen already speaks | none, registry key, or DPoP |
GET /api/v1/plugins/<id> | Exact manifest text and its SHA-256 | same |
POST /api/v1/device/authorize | Start linking (RFC 8628) and register the installation’s public key | — |
POST /api/v1/token | Redeem the device code, or mint a 10-minute token by proving the key | DPoP proof |
GET /api/v1/installation/entitlements | Entitlement sync — necessary, never sufficient, for a capability to run | DPoP-bound token |
POST /api/v1/tool-authorizations | 5-minute, capability-scoped tool token for hosted plugins | DPoP-bound token |
/api/gateway/v1/<plugin>/<capability> | The Tool Gateway | DPoP-bound tool token |
Registry address for AI17Z’s Plugins settings: https://ai17z.io