> ## Documentation Index
> Fetch the complete documentation index at: https://developers.reintersect.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manifest

> The description of your app that Reintersect derives from code and stores with every version.

> Reintersect apps are in developer preview. Names and limits can still change before general
> release.

The manifest lists everything your app provides and everything it can access. You never write it:
`reintersect dev`, `reintersect deploy` and the GitHub Action compute it from the exported `app`
and sync it to Reintersect. **Settings → Developer → Apps → your app → Manifest** shows each version's
manifest read-only, and `GET /v0/apps/:appId/manifest` returns the published or latest preview
manifest ([API](/api-reference/tooling/get-manifest)).

To inspect it locally, call `manifestOf`:

```ts theme={null}
import { manifestOf } from "@reintersect/sdk/app";
import { app } from "./app";

console.log(JSON.stringify(manifestOf(app), null, 2));
```

## Shape

```ts theme={null}
interface AppManifest {
  schemaVersion: 1;
  name: string;
  slug: string;
  description?: string;
  icon?: string;
  hosting: "self" | "reintersect";
  endpoint?: { url: string };
  scopes: ReadonlyArray<Scope>;
  egressHosts: ReadonlyArray<string>;
  domains: ReadonlyArray<string>;
  env: ReadonlyArray<{ key: string; secret: boolean; required: boolean }>;
  installConfig?: JsonSchema;
  blocks: ReadonlyArray<{
    type: string;
    title: string;
    description?: string;
    icon?: string;
    insertable: boolean;
    reopenable: boolean;
    props: JsonSchema;
    state: JsonSchema;
    staleAfter?: number;
    inputs: Record<string, { kind: "choice"; values: string[]; multiple?: boolean; anonymous?: boolean }>;
    sections: ReadonlyArray<string>;
    actions: ReadonlyArray<{
      name: string;
      description?: string;
      args?: JsonSchema;
      input?: JsonSchema;
      hints: { readOnly: boolean; destructive: boolean; idempotent: boolean };
      scopes: ReadonlyArray<Scope>;
      agent: boolean;
    }>;
  }>;
  references: ReadonlyArray<{
    kind: string;
    title: string;
    patterns: ReadonlyArray<{ id: string; pattern: string }>;
    searchable: boolean;
    hasBlock: boolean;
  }>;
  messageActions: ReadonlyArray<{
    id: string;
    label: string;
    icon?: string;
    context?: "message" | "thread" | "conversation";
  }>;
  commands?: ReadonlyArray<{
    name: string;
    description: string;
    options: ReadonlyArray<{
      name: string;
      description: string;
      type: "string" | "integer" | "number" | "boolean" | "choice" | "member" | "circle" | "appObject";
      required: boolean;
      choices?: ReadonlyArray<{ value: string; label: string }>;
      objectKind?: string;
    }>;
  }>;
  events: ReadonlyArray<EventType>;
  mcp?: { url: string; auth: "oauth" | "reintersect" | "none" };
}
```

## Fields

| Field | Derived from | Description |
| - | - | - |
| `schemaVersion` | The SDK | Always `1` for this version of the format. |
| `name`, `slug`, `description` | `createReintersectApp` options | Shown on blocks, the consent screen and the integrations directory. |
| `icon` | The `icon` option | An uploaded asset id. Upload your app's icon in Developer → Apps instead; Reintersect shows that one. |
| `hosting` | The `hosting` option | `"reintersect"` by default. |
| `endpoint` | The `endpoint` option | Self-hosted apps only: where Reintersect delivers. |
| `scopes` | Every piece's `scopes`, plus scopes implied by subscribed events | The union. See [Scopes](/reference/scopes). |
| `egressHosts` | The `egress` option | Hosted apps only: the hosts your code may call. |
| `domains` | The `domains` option | Link domains your reference patterns claim. |
| `env` | The `env` option | Keys only, never values. `required` is true for secrets and for schemas that don't accept `undefined`. |
| `installConfig` | The `installConfig` schema | JSON Schema, used to generate the install form. |
| `blocks` | Every `.addBlock` call | Type, title, schemas, inputs, sections and the actions each block attaches. |
| `blocks[].actions[].hints` | `readOnly`, `destructive` and `idempotent` on `defineAction` | Agents and the consent screen use these. |
| `blocks[].actions[].agent` | `agent` on `defineAction` | Whether the action becomes an agent tool. |
| `references` | Every `.addReference` call | `searchable` is true when the reference has a `search` function; `hasBlock` when it has a `block`. |
| `references[].patterns` | `patterns` | Each pattern has an id; Reintersect sends the matching id to `resolve`. |
| `messageActions` | Every `.addMessageAction` call | `id`, `label`, `icon` and `context`. `context` is left out for `"message"`. |
| `commands` | Every `.addCommand` call | `name`, `description` and `options`, with required options first. Left out when the app has no commands. |
| `events` | Every `.addEvent` call | See the [event catalog](/events/catalog). |
| `mcp` | `.addMcp(handler, { auth })` | The server's URL (your app's `/mcp`) and auth mode. Its host must be covered by a verified domain, unless the app is private or hosted on its own `<slug>.reintersect.app` host. See [MCP](/mcp/overview). |

### Size limits

A manifest holds at most 50 blocks, 64 actions and 32 sections per block, 50 reference kinds with 50
patterns each, 10 message actions, 25 commands with 25 options each and 25 choices per option, 50
outbound hosts, 20 domains and 128 environment variables. Each JSON Schema is limited to 5,000 nodes
and 256 KB once `$ref`s are expanded, and the whole manifest to 50,000 nodes and 2 MB, with nesting
up to 128 levels.

## Validation

Reintersect validates the manifest whenever it accepts a version. It rejects a version with an
invalid manifest with `ReintersectAppManifestInvalidError` and a `reason`, and existing installs keep
working:

| Reason | Cause |
| - | - |
| `duplicate` | Two blocks, kinds, actions, patterns, message actions, commands or options of one command share an id. |
| `command-option-choices` | A `choice` option without `choices`, or `choices` on another type. |
| `command-option-object-kind` | An `appObject` option whose `objectKind` is missing or not one of the app's reference kinds, or an `objectKind` on another type. |
| `command-option-order` | A required option after an optional one. |
| `endpoint-required`, `endpoint-unexpected` | A self-hosted app without an endpoint, or a hosted app with one. |
| `hosting-mismatch` | The manifest's hosting differs from the app's hosting in Developer → Apps. |
| `slug-mismatch` | The manifest's slug differs from the app's. |
| `scope-undeclared` | Something needs a scope the manifest doesn't list. |
| `too-many-patterns`, `public-suffix-host` | Too many patterns, or a pattern or domain spanning a public suffix. |
| `reserved-domain` | An outbound host or domain under `reintersect.com` or `reintersect.app`. |
| `reserved-name` | A reserved app name or slug. |
| `env-missing` | A required environment variable has no value in the target environment. |
| `schema-too-complex` | A JSON Schema over budget, recursive, or using remote or dynamic references. |
| `mcp-host-unverified` | The MCP server's host isn't covered by a verified domain. |

Invalid reference patterns fail with `ReintersectAppPatternInvalidError`. `reintersect check` runs
the same rules before you deploy.

## Access and re-consent

Reintersect computes each version's access from:

* `scopes`, `egressHosts`, `domains` and `events`,
* block actions that aren't `readOnly`, and actions that are `destructive`,
* `messageActions`, and each message action's `context`: `thread` and `conversation` count as more
  access than `message`,
* `mcp.url`, and the MCP server's tools that aren't read-only or are destructive.

When you publish a version whose access adds anything, installs stay on their current version until a
workspace admin approves the change, and your app receives `app.reconsentRequired`. These changes
don't widen access: changing a block's layout, titles or descriptions, adding read-only actions,
narrowing a message action's context, and adding or changing commands. See
[Publishing new versions](/concepts/install-and-consent#publishing-new-versions).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.