Resource Tools

A resource is what a plan unlocks: a place a connector gates, or a perk tracked by hand.

A resource is what a plan unlocks: a place a connector gates, or a perk tracked by hand. These tools register resources, link and unlink them, read their health and manage the standby and replacement flows Disaster Recovery relies on.

Tools

Switch a project resource on so the plans that link it grant it again. Emits project.resource.updated when the switch flips.

Turn a resource back on. The plans that link it never stopped linking it while it was off — switching off only stopped the bot offering and granting the channel or group — so switching on needs no re-linking: the plans grant it again from the next admission.

Runs the same Action the dashboard and the REST API use. project.resource.updated emits once, carrying changes.active from false to true, and only when the switch actually flips. Re-calling on a resource that is already on is a no-op: the current row comes back and nothing emits.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveIdempotent

A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time.

Arguments

resource_id*string

UUID of the resource to switch on.

What it returns

{  "data": {    "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "telegram:channel",    "connector": "telegram",    "space": {      "id": "3c1f7a58-2b6e-4d90-8f41-6a2e9c5d7b10",      "external_id": "-1001234567890",      "title": "Research Channel"    },    "title": "Research Channel",    "description": null,    "active": true,    "created_at": "2026-05-18T10:05:00+00:00",    "updated_at": "2026-09-06T08:30:12+00:00"  }}

The full get_resource row, with active: true.

How it fails

VALIDATION_FAILED

the caller is a team member whose role lacks the team's resource-update

RESOURCE_NOT_FOUND

unknown resource_id, a resource on another team's project, or one outside

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-resource:update.

create_resource

DESTRUCTIVE

Create a manual project resource (PDF link, token, URL placeholder) on a project with a connected connector. Gated places are linked through their connector.

Create a manual project resource. Delegates to an Action so policy checks and cache invalidation run identically to the dashboard, and a project.resource.created event fires.

Gated places (a channel, group or supergroup on Telegram, and whatever another connector gates) cannot be created through this tool. Only the connector can prove its installation administers the place, so a link starts with request_resource_link and finishes on the platform. Create manual perks here, and only once a connector on the project is connected: a project with none answers CONNECTOR_NOT_INSTALLED.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

project_id*string

UUID of the parent project.

title*string

Resource title (5..255 chars).

descriptionstringoptional

Optional resource description. Max 1000 chars, HTML is filtered.

activebooleanoptional

Defaults to true. Set false to create in inactive state.

What it returns

{  "data": {    "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "manual",    "connector": null,    "space": null,    "title": "Onboarding PDF",    "description": "Link to the onboarding pack.",    "active": true,    "created_at": "2026-05-18T10:05:00Z",    "updated_at": "2026-05-18T10:05:00Z"  }}

The full get_resource row: a manual perk is kind: "manual" with connector and space both null.

How it fails

VALIDATION_FAILED

title is outside the 5..255 character range.

CONNECTOR_NOT_INSTALLED

no connector on the project is connected, so nothing could deliver the resource; install and connect one first.

RESOURCE_NOT_FOUND

project_id is unknown or out of the token's team scope.

TOKEN_MISSING_ABILITY

token lacks project-resource:create.

Switch a project resource off without touching the plans that sell it. Reversible with activate_resource. Emits project.resource.updated when the switch flips.

Pause one channel or group without editing a single plan. While a resource is off the bot stops offering and granting it, and the plans that link it keep selling everything else they include. The link itself is untouched, which is what makes this reversible: activate_resource brings it back exactly as it was.

The safe alternative to delete_resource

delete_resource removes the row for good and every plan loses the link. Switching off keeps the row, the link and the connector binding. Reach for it for maintenance, a channel being reorganised, or anything you might want back.

Runs the same Action the dashboard and the REST API use. project.resource.updated emits once, carrying changes.active from true to false, and only when the switch actually flips. Re-calling on a resource that is already off is a no-op: the current row comes back and nothing emits.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveIdempotent

A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time.

Arguments

resource_id*string

UUID of the resource to switch off.

What it returns

{  "data": {    "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "telegram:channel",    "connector": "telegram",    "space": {      "id": "3c1f7a58-2b6e-4d90-8f41-6a2e9c5d7b10",      "external_id": "-1001234567890",      "title": "Research Channel"    },    "title": "Research Channel",    "description": null,    "active": false,    "created_at": "2026-05-18T10:05:00+00:00",    "updated_at": "2026-09-06T08:30:12+00:00"  }}

The full get_resource row, with active: false. space is kept — the binding survives the switch.

How it fails

VALIDATION_FAILED

the caller is a team member whose role lacks the team's resource-update

RESOURCE_NOT_FOUND

unknown resource_id, a resource on another team's project, or one outside

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-resource:update.

delete_resource

DESTRUCTIVE

Hard-delete a project resource. Emits project.resource.deleted before the row disappears so listeners see the snapshot.

Hard-delete a project resource by UUID. Delegates to an Action that emits project.resource.deleted with the row snapshot before the delete executes so downstream listeners capture the final state. Scoped to the caller's team.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveIdempotentOpen world

A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

resource_id*string

UUID of the resource to delete.

What it returns

{  "data": {    "resource_id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "deleted": true  }}

How it fails

RESOURCE_NOT_FOUND

unknown resource_id, or the parent project is outside the token's scope.

TOKEN_MISSING_ABILITY

token lacks project-resource:delete.

Fetch a single project resource by UUID. Returns its kind, connector, the place it is bound to, title, description, switch and timestamps.

Fetch full detail for one project resource. Results are scoped to the caller's team; unknown or out-of-scope IDs surface as RESOURCE_NOT_FOUND to prevent existence leaks.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Annotations

Read-only

It reads and never changes anything.

Arguments

resource_id*string

UUID of the project resource to fetch.

What it returns

{  "data": {    "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "telegram:channel",    "connector": "telegram",    "space": {      "id": "3c1f7a58-2b6e-4d90-8f41-6a2e9c5d7b10",      "external_id": "-1001234567890",      "title": "Research Channel"    },    "title": "Research Channel",    "description": null,    "active": true,    "created_at": "2026-05-18T10:05:00Z",    "updated_at": "2026-05-18T10:05:00Z"  }}

kind is manual for a perk the creator hands over by hand, otherwise the connector's kind spelled connector:kind as list_connectors lists each connector's resource_kinds. connector and space are null for a manual perk; space is also null for a place-kind resource that was unlinked.

How it fails

RESOURCE_NOT_FOUND

unknown resource_id, or the parent project is outside the token's scope.

TOKEN_MISSING_ABILITY

token lacks project-resource:view.

Paginated list of project resources (the places a connector gates plus manual perks) scoped to one project, narrowable by kind and by connector.

List every resource attached to a project — the places a connector gates, manual PDF / URL perks, and any other unit the creator has registered as gated content. Results are scoped to the caller's team and ordered newest-first. kind narrows the page to one kind of resource and connector to everything one connector gates; either alone or both together.

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Annotations

Read-only

It reads and never changes anything.

Arguments

project_id*string

UUID of the parent project.

limitintegeroptional

Maximum resources to return per page (1..100).

min1max100
pageintegeroptional

1-indexed page number.

min1
kindstringoptional

Only resources of one kind: `manual`, or a connector's kind spelled `connector:kind` as `list_connectors` lists each connector's `resource_kinds`.

connectorstringoptional

Only the resources one connector gates, by the key `list_connectors` lists it under.

What it returns

{  "data": [    {      "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",      "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",      "kind": "telegram:channel",      "connector": "telegram",      "space": {        "id": "3c1f7a58-2b6e-4d90-8f41-6a2e9c5d7b10",        "external_id": "-1001234567890",        "title": "Research Premium Lounge"      },      "title": "Research Premium Lounge",      "description": "Daily research notes.",      "active": true,      "created_at": "2026-05-18T10:05:00Z",      "updated_at": "2026-05-18T10:05:00Z"    },    {      "id": "8c2f4a61-3d7e-4b90-a5c8-1e6f9d0b2c73",      "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",      "kind": "manual",      "connector": null,      "space": null,      "title": "Onboarding PDF",      "description": "Link to the onboarding pack.",      "active": true,      "created_at": "2026-05-18T10:05:00Z",      "updated_at": "2026-05-18T10:05:00Z"    }  ],  "meta": {    "page": 1,    "limit": 25,    "total": 2,    "has_more": false  }}

space is the place the resource is bound to, null for a manual perk and for a place-kind resource that was unlinked. The row is the same object GET /v1/projects/{project}/resources returns.

How it fails

RESOURCE_NOT_FOUND

unknown project_id, or the project belongs to a team outside the token's scope.

VALIDATION_FAILED

kind is neither manual nor connector:kind, or connector is not a connector key.

TOKEN_MISSING_ABILITY

token lacks project-resource:view-any.

Ask the creator, through the connector, to pick the place a new resource will be; it appears the moment they choose.

Linking a place a connector gates is a conversation with the creator on the connector: only the platform can prove the installation administers the place, so the connector messages the creator with a picker and the resource appears, announced by project.resource.linked, the moment they choose. Nothing is created by this call itself; a manual perk is created with create_resource. The REST twin is POST /v1/projects/{project}/resources/link-requests.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

project_id*string

UUID of the project the linked place will belong to.

kind*string

The kind of place to ask for, spelled `connector:kind`: a connector's key, a colon, and one of the `resource_kinds` that `list_connectors` lists for it.

{  "data": {    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "telegram:channel",    "status": "request_sent"  },  "meta": {}}
CONNECTOR_NOT_INSTALLED

the project runs no connected connector, so nothing could finish the link.

VALIDATION_FAILED

kind is manual, a bare word or otherwise not connector:kind; no connected connector on the project gates the kind; or the creator cannot be reached on the connector.

RESOURCE_NOT_FOUND

project_id is not a project the token can see.

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-resource:create.

DESTRUCTIVE

Clear the connector place from a resource, reverting it to an unlinked placeholder the creator can relink through the connector.

Clear the connector place (space) from a resource, reverting it to an unlinked placeholder row the creator can relink through the connector with request_resource_link. Delegates to an Action so a project.resource.unlinked event fires. No-op if the resource is already unlinked.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveIdempotentOpen world

A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.

resource_id*string

UUID of the resource to unlink.

{  "data": {    "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "telegram:channel",    "connector": "telegram",    "space": null,    "title": "Research Channel",    "description": null,    "active": true,    "created_at": "2026-05-18T10:05:00Z",    "updated_at": "2026-09-06T08:30:12Z"  }}

The full get_resource row with space cleared. The resource keeps its kind and connector: it is still a Telegram channel resource, only one bound to no place until the creator links another.

RESOURCE_NOT_FOUND

unknown resource_id, or the parent project is outside the token's scope.

TOKEN_MISSING_ABILITY

token lacks project-resource:update.

update_resource

DESTRUCTIVE

Retitle, describe or switch a project resource. Partial by design — anything omitted keeps its stored value; the kind and the place are fixed.

Change what the dashboard's resource editor lets a creator change: the title, the description and the active switch. Only the arguments present are written; anything omitted is filled from the stored row, so a title-only change never touches the description and is never logged as a description edit.

Emits project.resource.updated with the fields that actually moved. A call whose arguments change nothing returns the current row and emits nothing.

`kind`, `connector` and `space` are silently ignored

The resource kind is its identity and the connector place (space) is its binding; neither can be set here. Sending them is not an error — they are simply not read. A place is linked through the connector with request_resource_link, and cleared with unlink_resource.

`active` here, or the dedicated switches

active is accepted alongside the other fields. When the switch is the only thing changing, activate_resource and deactivate_resource do the same thing with a one-argument call.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveIdempotentOpen world

A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

resource_id*string

UUID of the resource to change.

titlestringoptional

New title, 5 to 255 characters.

descriptionstringoptional

New description, up to 1000 characters of well-formed HTML. Pass null or an empty string to clear it.

activebooleanoptional

true offers the resource on the plans that link it, false switches it off without touching those plans.

What it returns

{  "data": {    "id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "kind": "telegram:channel",    "connector": "telegram",    "space": {      "id": "3c1f7a58-2b6e-4d90-8f41-6a2e9c5d7b10",      "external_id": "-1001234567890",      "title": "Members lounge"    },    "title": "Members lounge (VIP)",    "description": "Where the regulars hang out.",    "active": true,    "created_at": "2026-05-18T10:05:00+00:00",    "updated_at": "2026-09-06T08:30:12+00:00"  }}

The full get_resource row. description comes back purified, so the HTML you read may be tidier than the HTML you sent. space is null on a manual perk and on a resource not yet linked to a place on its connector.

How it fails

VALIDATION_FAILED

title outside 5–255 characters (error.context.title); description

RESOURCE_NOT_FOUND

unknown resource_id, a resource on another team's project, or one outside

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-resource:update.

How is this guide?

On this page

Subscriby is a product designed by you — for you.No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request