MCP server
Connect AI agents to your Inventra organizations.
Inventra ships a hosted Model Context Protocol server that lets any MCP-compatible agent — Claude Code, Claude Desktop, Cursor, and others — manage blocks, blog posts, categories, tags, users, sitemap entries, and billing across every organization you belong to. Sign in once with OAuth and the agent can act on any of your orgs, switching between them as you ask.
How it works
| Endpoint | https://www.inventra.sh/api/mcp |
| Transport | HTTP (Streamable HTTP, no SSE) |
| Auth | OAuth 2.1 — sign in with your Inventra account |
| Scope | Tokens are tied to your user account, not a single organization. Agents discover orgs via list_my_organizations and pass organizationId per tool call. |
Authentication
Inventra MCP authenticates with OAuth only. On first connect, your client opens a browser tab at www.inventra.sh to sign you in. You'll see a consent screen listing every organization the agent will be able to act on. Tokens are tied to your user account; they grant access to every organization you currently belong to.
There is no API key for MCP. The x-api-key header is still used by Inventra's REST API for server-to-server access (see REST API below), but MCP clients never need it.
Install in your client
Claude Desktop
- In Claude Desktop, open Settings → Connectors → Add custom connector.
- Set Name to
Inventraand Remote MCP server URL tohttps://www.inventra.sh/api/mcp. - Click Add. A browser tab opens at
www.inventra.shasking you to sign in. - Sign in, review the list of organizations on the consent screen, and click Authorize.
- Back in Claude Desktop, the Inventra connector is now active.
Once connected, the agent can act on any organization you belong to. Ask it "which Inventra orgs can I access?" to confirm.
Claude Code
Add the server to your project's .mcp.json (or the global ~/.claude.json):
{
"mcpServers": {
"inventra": {
"type": "http",
"url": "https://www.inventra.sh/api/mcp"
}
}
}Or use the CLI:
claude mcp add --transport http inventra https://www.inventra.sh/api/mcpThe first call will open a browser tab to complete the OAuth flow.
Cursor
Add the server to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project-scoped):
{
"mcpServers": {
"inventra": {
"url": "https://www.inventra.sh/api/mcp"
}
}
}Open Cursor Settings → MCP to confirm the server is listed and showing a green status. Complete the OAuth flow on first use.
Other clients
Any MCP client that can speak Streamable HTTP and OAuth 2.1 will work. Point it at https://www.inventra.sh/api/mcp and complete the browser sign-in.
Stdio fallback
For clients that only support stdio transports (or older agents that can't speak HTTP MCP at all), wrap the endpoint with mcp-remote:
{
"mcpServers": {
"inventra": {
"command": "npx",
"args": [
"mcp-remote",
"https://www.inventra.sh/api/mcp"
]
}
}
}mcp-remote handles the OAuth flow via your browser automatically. It's fetched on demand via npx, so you need Node 18+ on your PATH.
Verify it works
Ask your agent:
Who am I? Which Inventra orgs can I access?
It should call get_me and list_my_organizations, then ask which org to operate on (or auto-pick if you only have one). Once it knows the org, ask:
List the blocks in my organization.
If you get an authentication error, sign in again from your client. If you get "not a member of organization", you passed an organizationId for an org you don't belong to — run list_my_organizations to see the IDs you can use.
Available tools
Every org-scoped tool below requires an
organizationIdargument. Agents resolve it once per session vialist_my_organizationsand reuse it for follow-up calls; re-resolving only when you name a different org.
Identity
| Tool | Purpose |
|---|---|
get_me |
Return the authenticated user (id, name, email, image). |
list_my_organizations |
Return every organization you belong to with your role in each. |
Blocks
| Tool | Purpose |
|---|---|
list_blocks |
Paginated listing of blocks. Supports search, sort, and filtering by status. |
list_blocks_schema |
Discovery view of every block with its field contracts — use when the agent needs to understand block structure before editing. |
get_block |
Fetch a single block by UUID or slug. |
create_block |
Create a block (name, slug, pages, fields). |
update_block |
Patch an existing block. |
delete_block |
Delete a block by ID. |
duplicate_block |
Clone a block with media URLs cleared so they can be replaced. |
check_block_slug |
Check whether a slug is available before creating. |
list_block_pages |
List the distinct page names blocks are grouped under. |
Content
| Tool | Purpose |
|---|---|
list_contents |
Paginated listing of blog posts and articles (body excluded for speed). |
get_content_by_id |
Fetch a full content item including its body. |
get_content_by_slug |
Fetch a published item by slug. |
create_content |
Create a blog post or article (draft or published — scheduling goes through the dashboard). |
update_content |
Patch an existing content item. |
delete_content |
Delete a content item by ID. |
Categories
| Tool | Purpose |
|---|---|
list_categories |
All categories in the org, sorted alphabetically. |
create_category |
Create a new content category. Slug is auto-generated from the display name if omitted. Supports aiWriteInstructions, autoPosting, and enableBusinessOfferBridge. |
update_category |
Update an existing category by numeric ID. Only provided fields change. |
delete_category |
Permanently delete a category. Contents lose their category assignment. |
Tags
| Tool | Purpose |
|---|---|
list_tags |
All tags in the org, sorted alphabetically. |
create_tag |
Create a new tag. Slug is auto-generated from the value if omitted. |
delete_tag |
Permanently delete a tag. Content-tag associations are removed. |
Users
| Tool | Purpose |
|---|---|
list_organization_users |
List every member of the organization with their role and join date. |
update_organization_user |
Update a member's name or role (admin / user). |
remove_organization_user |
Remove a member from the organization. Destructive. |
Organization
| Tool | Purpose |
|---|---|
get_organization |
Org metadata plus public integration keys (e.g., Google Analytics measurement ID) and current plan. Never returns the API key, Stripe IDs, or secret credentials. |
update_business_description |
Update the organization's business description — the text the AI writer uses as context when generating blog posts. |
update_business_offers |
Update the organization's business offers (name, description, optional link). Used to generate CTA bridges in AI-written content. |
Billing
| Tool | Purpose |
|---|---|
list_plans |
The public Inventra plan catalog with limits and features. |
get_billing |
Current plan, status, and period dates for the given org. No Stripe IDs. |
start_plan_change |
Owner-only. Returns a Stripe-hosted Checkout or Billing Portal URL the user opens in a browser. The change syncs back via webhook. |
open_billing_portal |
Owner-only. Returns a Stripe Billing Portal URL for self-serve cancellation, payment method updates, and plan changes. |
SEO
| Tool | Purpose |
|---|---|
get_sitemap_entries |
Published slugs with ISO 8601 lastModified timestamps, ready to feed a Next.js sitemap.ts. |
REST API note
If you need server-to-server access (no browser, no human), the REST API at https://www.inventra.sh/api/organizations/<id>/... still accepts an x-api-key header. Find your org's key in Settings → API key. That key is for the REST API only — MCP clients use OAuth.
Troubleshooting
| Symptom | Likely cause |
|---|---|
401 Unauthorized on every call |
Your OAuth session expired or your client lost the refresh token. Disconnect and re-add the server in your client. |
Tool returns "not a member of organization" |
You're passing an organizationId for an org you don't belong to. Run list_my_organizations to see your orgs. |
| Client can't find the server | The client only supports stdio transports. Wrap the URL with mcp-remote — see Stdio fallback. |
start_plan_change returns "Only the organization owner can change billing." |
The signed-in user is not the owner of that org. Ask the owner to run the change. |
| Changes aren't showing up on your site | The MCP writes to Inventra immediately, but your website's cache may still be warm. See Production setup → Caching. |