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.

  1. 01you

    Apply

    Tell us who you are and what you will build. A person verifies you before anything can be published.

    publisher application

  2. 02you

    Build

    Write a Plugin manifest, a hosted capability, or fork ShiftAboveCtrl/ai17z for an in-core integration.

    manifest · gateway · fork

  3. 03you

    Submit

    An exact version: manifest bytes or commit + pull request, permissions, disclosures, tests, compatibility and price.

    immutable once submitted

  4. 04Studio admin

    Review

    An admin reads the exact bytes, the hosts, the data handling and the tests, and classifies the risk.

    LOW · MEDIUM · HIGH

  5. 05Studio admin

    Publish

    Approved versions go live and never change. Fixes are new versions, reviewed again.

    free, one-time, monthly or yearly

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.

Delivery modes compared
Declarative pluginHosted capabilityIn-core integration
ModeREGISTRY_MANIFESTHOSTED_GATEWAYIN_CORE_INTEGRATION
You shipA 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.
RunsIn 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.
NeedsAny 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.

plugin manifest · schema v1 · json
{
  "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}&current=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
TypeScript · illustrative
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.
In your fork
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.

EndpointPurposeAuth
GET /api/v1/pluginsPlugin Registry protocol v1 catalogue — what AI17Z’s Plugins screen already speaksnone, registry key, or DPoP
GET /api/v1/plugins/<id>Exact manifest text and its SHA-256same
POST /api/v1/device/authorizeStart linking (RFC 8628) and register the installation’s public key—
POST /api/v1/tokenRedeem the device code, or mint a 10-minute token by proving the keyDPoP proof
GET /api/v1/installation/entitlementsEntitlement sync — necessary, never sufficient, for a capability to runDPoP-bound token
POST /api/v1/tool-authorizations5-minute, capability-scoped tool token for hosted pluginsDPoP-bound token
/api/gateway/v1/<plugin>/<capability>The Tool GatewayDPoP-bound tool token

Registry address for AI17Z’s Plugins settings: https://ai17z.io

Developers · AI17Z