PAMbaseDocs
Concept

App manifest.

The manifest is the declaration your app registers with PAMbase: who you are, the scopes you want, and the signal types you plan to emit. It is your app's contract with the platform and with users.

Why it matters

The manifest is the single source of truth for what your app is allowed to do, and it does three jobs at once:

  • The scopes it lists become the exact permissions a user sees and approves on the consent screen — nothing your app does can exceed them.
  • The signal types it lists are declared up front so subscribers can discover what your app emits. Signals are free-form, so this list is documentation, not enforcement.
  • The context intents it lists are the only intents you may request context with — this one is enforced.

Margin's manifest

Here is the full manifest for our reading companion. Notice the scopes match exactly what Margin requests on the permissions page:

margin/manifest.json
{
"slug": "margin",
"name": "Margin",
"type": "app",
"description": "A reading companion that learns what you love and tells you what to read next.",
"scopesRequested": [
"identity:read",
"memory:read:note.*",
"memory:write:note.*",
"memory:read:preference",
"memory:write:preference",
"context:read:app.session.start",
"ai:host:chat",
"signal:subscribe"
],
"eventTypes": [
"note.highlighted"
],
"contextIntents": [
"app.session.start"
],
"hostsAI": true
}

The fields

FieldWhat it does
slugKebab-case identifier, unique across the platform. Used in URLs and the ecosystem catalog.
nameHuman-readable name shown on the consent screen.
typeYour app's category, e.g. app, game, productivity.
descriptionOne line shown to users at consent.
scopesRequestedThe full set of scopes users may approve. They can grant a subset; your token reflects what they actually granted.
eventTypesThe signal types you declare you'll emit, so subscribers can discover them. Free-form — documentation, not enforcement.
contextIntentsThe only intents you may request context with. Same enforcement.
hostsAISet true if you use the gateway; surfaces a different consent block.
scopesRequested is a ceiling, not a guarantee
Listing a scope means users can approve it — not that they will. A user might grant memory:read:note.* but decline ai:host:chat. Always check what you actually hold before relying on a scope; see Discover the vocabulary.

Naming: the scope taxonomy is the shared world

Memory scopes come from a standard, extensive taxonomy — the shared domains every app writes into. Pick the namespace that fits (a free sub-scope like note.reading is yours); that's how a newsletter app recalls Margin's preference memories with zero coordination, today and as the ecosystem grows. Browse them all in the Catalog.

If nothing fits, use general — or ask
A write's top-level scope must be a standard namespace; use general when nothing fits. Signal types, by contrast, are free-form (they're ephemeral notifications). If a domain is missing from the taxonomy and would be broadly useful, it can be added — the taxonomy grows additively, so your app never breaks.

Editing your manifest

You edit the manifest in the developer portal. Changing it does not retroactively touch existing users: connections keep the scopes they were already granted. New connections see the updated set. That means widening a scope on an existing user requires them to reconnect — plan scope changes accordingly.

Next

  • Permissions — the scope grammar your manifest is built from.
  • Discover the vocabulary — read standard and ecosystem names, and check granted scopes.
  • Catalog — the standard scopes, event types, and intents to declare.