Skip to content

manifest.json Reference

Every toolkit must include a manifest.json file at the root of its project folder. The manifest is the policy surface: it declares what your toolkit is, what secrets it needs, which external hosts it is allowed to reach, and which Trove capabilities it requests. trove deploy validates the manifest before uploading anything.

manifest.json
{
"id": "acme-orders",
"name": "Acme Orders",
"description": "Query Acme order status and line items.",
"version": "1.0.0",
"sdk": "@ontrove/mcp@^1",
"secrets": ["ORDERS_API_TOKEN"],
"egress": ["orders.acme.com"],
"scopes": [],
"visibility": "private"
}
Typestring
RequiredYes
Pattern^[a-z0-9-]+$ (lowercase, digits, hyphens)

A stable identifier for the toolkit, unique within your account. The id becomes the namespace prefix for all your tools: a toolkit with "id": "acme-orders" exposes its tools as acme-orders__<tool_name>.

The id also appears in the standalone endpoint URL: https://api.ontrove.sh/mcp/s/<id>.


Typestring
RequiredYes

A human-readable display name for the toolkit. Shown in the Trove web app, in trove deploy output, and in future sharing/discovery surfaces. Keep it short and descriptive — "Acme Orders", not "Acme Internal Order Status Lookup System v2".


Typestring
RequiredNo

A one-sentence description of what the toolkit does. Shown in the Trove web app and used as the MCP server description when the standalone endpoint is queried. Not directly model-visible — model-visible descriptions live on individual tools.


Typestring — emoji or URL
RequiredNo

A single emoji or an HTTPS URL to a square PNG/SVG (recommended: 64×64 or 128×128). Shown alongside the toolkit name in the Trove web app.


Typestring — semver
RequiredYes

The toolkit version, following semver. trove deploy records this in the deployment registry and surfaces it in rollback history. Increment this on each meaningful deploy so you can distinguish versions in trove logs and rollback.


Typestring — npm package specifier
RequiredYes

The @ontrove/mcp version range your toolkit is authored against. Used by the platform to validate compatibility and pin the correct runtime wrapper at deploy time.

"sdk": "@ontrove/mcp@^1"

Always use a caret range (^1) rather than an exact pin so you receive patch-level fixes automatically.


Typestring[]
RequiredNo (default: [])

Names of secrets your toolkit will access via ctx.secret(name). Names are declared here; values are stored separately with trove secret set. Any name not listed here is inaccessible at runtime — ctx.secret("UNDECLARED_NAME") throws.

"secrets": ["ORDERS_API_TOKEN", "METRICS_READ_KEY"]

Declare the minimal set your toolkit actually needs. Each secret name must match what you pass to ctx.secret(...) exactly (case-sensitive).

See Secrets and Auth for the vault model and how to set values.


Typestring[] — array of hostnames
RequiredNo (default: [], deny all)

Outbound HTTP is denied by default. List every public-internet hostname your toolkit needs to reach. Requests to any host not in this list are blocked by Trove at the network level — including redirects that resolve to an unlisted host.

"egress": ["orders.acme.com", "metrics.acme.com"]

egress is for public-internet hosts only. Even when listed, a host that resolves to localhost, a private/LAN range, or a reserved address (e.g. 127.0.0.1, 10.0.0.0/8, 192.168.0.0/16, the cloud-metadata IP 169.254.169.254) is blocked — an SSRF defense, see the security model. A toolkit runs in Trove’s cloud and cannot reach your own machine (no localhost, LAN, local files, or Mac apps); for local/private data, use a source (synced by the Mac app) or a local MCP server instead. (orders.acme.com above is a public-internet SaaS host your company exposes — the allowlist accepts it because it resolves to a public address.)

Entries are matched on the exact hostname (no port, no path, no wildcard in V1). If your API uses subdomains, list the specific subdomain you need.


Typestring[]
RequiredNo (default: [])

Trove capabilities your toolkit requests. Absent a scope, the corresponding ctx.trove method is unavailable.

ScopeWhat it unlocks
"trove:search"ctx.trove.search(...) and ctx.trove.getDocument(...) — read access to the calling user’s knowledge base
"trove:ingest"ctx.trove.ingest(...) — write documents into the calling user’s knowledge base
"scopes": ["trove:search"]

A toolkit with no scopes cannot read or write the user’s knowledge base — it can only call external APIs via ctx.fetch. This is the correct default for most toolkits.


Type"private" | "shared"
RequiredNo (default: "private")

Controls who can see and use the toolkit.

ValueMeaning
"private"Only you can see and use this toolkit.
"shared"The toolkit definition (manifest + bundle) can be shared with others, who deploy their own copy with their own secrets. They run an isolated instance; you do not share your secrets or data.

trove deploy validates the manifest before uploading:

  • All required fields present and correctly typed
  • id matches the allowed pattern
  • version is valid semver
  • sdk references a known @ontrove/mcp version range
  • Every name in secrets that has no matching value in the vault produces a warning (not an error — you can set secrets after deploying)
  • Every hostname in egress is a valid DNS name

The typed McpServerDefinition export from your server.ts is also validated against the manifest — trove deploy catches mismatches (e.g., a tool calling ctx.secret("X") when "X" is not in manifest.secrets) before anything reaches the platform.


A toolkit with no external calls and no secrets needs only four fields:

manifest.json
{
"id": "my-toolkit",
"name": "My Toolkit",
"version": "1.0.0",
"sdk": "@ontrove/mcp@^1"
}