MCP Tools
The Marcora MCP Server exposes a set of tools that your AI assistant can call directly to interact with your workspace. Each tool maps to a specific action — from generating content to retrieving context — and can be invoked naturally through conversation.
The tools below are available to any connected AI assistant once the Marcora MCP Server is configured.
Tools
Context Intelligence
apply_grounding_fix
Apply Marcora's stored recommended fix for one or more findings, by finding_id. Serves both content-grounding findings and Context Intelligence health-audit recommendations. Review each suggested_fix with the user first - this writes to their library.
Input Schema
{
"type": "object",
"required": [
"finding_ids"
],
"properties": {
"finding_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Required. The finding_id values to apply, from check_content_grounding, get_grounding_result or list_ci_findings. Pass one or many."
},
"context_item_overrides": {
"type": "object",
"description": "Optional. Redirect specific fixes: a map of finding_id to the context_item_id it should be written to instead of the finding's default target. Every key must also appear in finding_ids. Mirrors the destination picker in the Marcora UI.",
"additionalProperties": {
"type": "string",
"format": "uuid"
}
}
}
}Output Schema
{
"type": "object",
"required": [
"requested",
"queued",
"skipped",
"jobs",
"errors"
],
"properties": {
"jobs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"type": "string"
},
"finding_id": {
"type": "string",
"format": "uuid"
},
"document_uuid": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"generation_id": {
"type": "string",
"format": "uuid",
"description": "A UUID. Poll get_generation_status with it; the document_updated field there tells you whether the document actually changed."
},
"context_item_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Where the fix was written. null means the document itself."
}
}
},
"description": "One per finding that started. Check this AND errors[]."
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"finding_id": {
"type": "string",
"format": "uuid"
}
}
},
"description": "One per finding that could not start. Partial success is normal."
},
"queued": {
"type": "integer",
"description": "How many runs actually started."
},
"skipped": {
"type": "integer",
"description": "How many could not start - see errors[]."
},
"requested": {
"type": "integer",
"description": "How many findings were submitted."
}
}
}check_content_grounding
Run a grounding scan on a document to check its factual claims against the team's context library, sorting each into supported, conflict, or gap. Waits ~20s inline; poll get_grounding_result with the scan_id if it returns running.
Input Schema
{
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Optional. Only meaningful alongside content. When omitted the name is derived from the first line of the markdown."
},
"content": {
"type": "string",
"description": "Optional. Markdown to ground. On its own, it is stored as a NEW document and scanned. ⚠️ DANGER — combined with `content_id`, this REPLACES THE ENTIRE BODY of that document, exactly like update_content. It is a whole-document overwrite, never a fragment check. If you want to check one paragraph or section of an existing document, do NOT pass that fragment here with a content_id — you would destroy the rest of the document. Either pass the FULL revised document, or omit `content` entirely and scan the existing item by content_id alone."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Optional. An existing document to scan. Pass it ALONE to scan that document as it currently stands — that is the safe default. Combining it with `content` REPLACES the document's entire body first (see the `content` warning)."
}
}
}Output Schema
{
"type": "object",
"required": [
"content_id",
"status",
"link_url",
"summary"
],
"properties": {
"claims": {
"type": "array",
"items": {
"type": "object",
"properties": {
"refs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": [
"string",
"null"
]
},
"link_url": {
"type": "string"
},
"context_item_id": {
"type": [
"string",
"null"
]
}
}
},
"description": "Context items supporting or contradicting this claim."
},
"value": {
"type": [
"string",
"null"
]
},
"bucket": {
"enum": [
"supported",
"conflict",
"gap"
],
"type": "string"
},
"subject": {
"type": [
"string",
"null"
]
},
"claim_id": {
"type": [
"string",
"null"
]
},
"claim_text": {
"type": [
"string",
"null"
]
},
"confidence": {
"type": [
"string",
"null"
],
"description": "Extraction confidence for this claim, as a decimal STRING (e.g. \"0.82\") — matching the shape the context-item claims endpoint returns."
},
"finding_id": {
"type": [
"string",
"null"
]
},
"source_excerpt": {
"type": [
"string",
"null"
],
"description": "The passage in the document the claim came from."
}
}
},
"description": "Every factual claim extracted from the document, with its verdict. Creator-only."
},
"status": {
"enum": [
"running",
"complete",
"failed",
"none"
],
"type": "string",
"description": "running = poll get_grounding_result with this scan_id, do not re-scan. none = no scan has been run for this content yet."
},
"message": {
"type": "string",
"description": "Present when the scan is still running, or when details are withheld."
},
"scan_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "The scan run. Null only if no scan has ever run for this content."
},
"summary": {
"type": "object",
"properties": {
"gaps": {
"type": "integer",
"description": "Claims the library can neither support nor contradict."
},
"conflicts": {
"type": "integer",
"description": "Claims that contradict the library — the ones to act on first."
},
"supported": {
"type": "integer",
"description": "Claims the context library backs up."
},
"total_claims": {
"type": "integer"
},
"corpus_freshness": {
"type": [
"object",
"null"
],
"description": "What the pre-scan freshness sweep refreshed before grounding. Free; does not count against credits.",
"additionalProperties": true
}
},
"description": "Claim counts. Present even when details_visible is false."
},
"findings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": [
"string",
"null"
],
"description": "conflict or gap."
},
"status": {
"type": [
"string",
"null"
],
"description": "pending, acknowledged, dismissed or resolved."
},
"subject": {
"type": [
"string",
"null"
],
"description": "What the finding is about."
},
"link_url": {
"type": [
"string",
"null"
],
"description": "Opens the finding."
},
"severity": {
"type": [
"string",
"null"
]
},
"statement": {
"type": [
"string",
"null"
],
"description": "What the document says versus what the library says."
},
"finding_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Pass to get_ci_finding / update_ci_finding_status."
},
"suggested_fix": {
"type": [
"object",
"null"
],
"description": "The full recommended update, exactly as Marcora stored it — read this to review the exact change before calling apply_grounding_fix. The wording sits under whichever of ai_prompt, new_value, append_value or insert_value the engine wrote.",
"additionalProperties": true
},
"recommendation": {
"type": [
"string",
"null"
],
"description": "What Marcora suggests doing."
},
"context_item_id": {
"type": [
"string",
"null"
],
"description": "The context item apply_grounding_fix will write to for this finding. null means the fix targets the content document itself rather than a library item."
},
"has_suggested_fix": {
"type": "boolean",
"description": "True when Marcora has drafted a fix for this finding."
}
}
},
"description": "Actionable conflicts and gaps. Creator-only."
},
"link_url": {
"type": "string",
"description": "Opens the document in Marcora with the grounding panel showing."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "The content item that was scanned. In content-submission mode this is the newly created item — keep it for polling and for follow-up calls."
},
"corpus_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": [
"string",
"null"
]
},
"source": {
"type": [
"string",
"null"
],
"description": "context_item, project_brief or generation."
},
"link_url": {
"type": [
"string",
"null"
],
"description": "Null for corpus entries that are not standalone context items, such as project briefs."
},
"context_item_id": {
"type": [
"string",
"null"
],
"description": "null for entries that are not context items, such as project briefs."
},
"content_category": {
"type": [
"string",
"null"
],
"description": "company_authoritative, reference_material or unclassified — how authoritative this source is."
}
}
},
"description": "The context items this scan was actually grounded against, recorded at scan time. Creator-only."
},
"excluded_items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Present only when reference material was locked mid-edit and could not be included in the corpus — the grounding is honest but incomplete."
},
"details_visible": {
"type": "boolean",
"description": "False when the caller is not the content's creator — findings, claims and corpus_items are then omitted."
}
},
"description": "The grounding envelope. check_content_grounding and get_grounding_result return exactly this shape, so one handler works for both."
}get_grounding_result
Read the result of a grounding scan. The poll companion to check_content_grounding - it never starts a scan and never charges credits. Poll with scan_id; content_id skips a still-running scan.
Input Schema
{
"type": "object",
"properties": {
"scan_id": {
"type": "string",
"format": "uuid",
"description": "The scan id returned by check_content_grounding. Pass this when polling — it reads the exact run you started, whatever its status. Either scan_id or content_id is required."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "The content id returned by check_content_grounding. Passed alone, it reads the latest COMPLETED grounding for that document and skips any scan still running — so use scan_id, not this, when polling. Either scan_id or content_id is required."
}
}
}Output Schema
{
"type": "object",
"required": [
"content_id",
"status",
"link_url",
"summary"
],
"properties": {
"claims": {
"type": "array",
"items": {
"type": "object",
"properties": {
"refs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": [
"string",
"null"
]
},
"link_url": {
"type": "string"
},
"context_item_id": {
"type": [
"string",
"null"
]
}
}
},
"description": "Context items supporting or contradicting this claim."
},
"value": {
"type": [
"string",
"null"
]
},
"bucket": {
"enum": [
"supported",
"conflict",
"gap"
],
"type": "string"
},
"subject": {
"type": [
"string",
"null"
]
},
"claim_id": {
"type": [
"string",
"null"
]
},
"claim_text": {
"type": [
"string",
"null"
]
},
"confidence": {
"type": [
"string",
"null"
],
"description": "Extraction confidence for this claim, as a decimal STRING (e.g. \"0.82\") — matching the shape the context-item claims endpoint returns."
},
"finding_id": {
"type": [
"string",
"null"
]
},
"source_excerpt": {
"type": [
"string",
"null"
],
"description": "The passage in the document the claim came from."
}
}
},
"description": "Every factual claim extracted from the document, with its verdict. Creator-only."
},
"status": {
"enum": [
"running",
"complete",
"failed",
"none"
],
"type": "string",
"description": "running = poll get_grounding_result with this scan_id, do not re-scan. none = no scan has been run for this content yet."
},
"message": {
"type": "string",
"description": "Present when the scan is still running, or when details are withheld."
},
"scan_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "The scan run. Null only if no scan has ever run for this content."
},
"summary": {
"type": "object",
"properties": {
"gaps": {
"type": "integer",
"description": "Claims the library can neither support nor contradict."
},
"conflicts": {
"type": "integer",
"description": "Claims that contradict the library — the ones to act on first."
},
"supported": {
"type": "integer",
"description": "Claims the context library backs up."
},
"total_claims": {
"type": "integer"
},
"corpus_freshness": {
"type": [
"object",
"null"
],
"description": "What the pre-scan freshness sweep refreshed before grounding. Free; does not count against credits.",
"additionalProperties": true
}
},
"description": "Claim counts. Present even when details_visible is false."
},
"findings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": [
"string",
"null"
],
"description": "conflict or gap."
},
"status": {
"type": [
"string",
"null"
],
"description": "pending, acknowledged, dismissed or resolved."
},
"subject": {
"type": [
"string",
"null"
],
"description": "What the finding is about."
},
"link_url": {
"type": [
"string",
"null"
],
"description": "Opens the finding."
},
"severity": {
"type": [
"string",
"null"
]
},
"statement": {
"type": [
"string",
"null"
],
"description": "What the document says versus what the library says."
},
"finding_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Pass to get_ci_finding / update_ci_finding_status."
},
"suggested_fix": {
"type": [
"object",
"null"
],
"description": "The full recommended update, exactly as Marcora stored it — read this to review the exact change before calling apply_grounding_fix. The wording sits under whichever of ai_prompt, new_value, append_value or insert_value the engine wrote.",
"additionalProperties": true
},
"recommendation": {
"type": [
"string",
"null"
],
"description": "What Marcora suggests doing."
},
"context_item_id": {
"type": [
"string",
"null"
],
"description": "The context item apply_grounding_fix will write to for this finding. null means the fix targets the content document itself rather than a library item."
},
"has_suggested_fix": {
"type": "boolean",
"description": "True when Marcora has drafted a fix for this finding."
}
}
},
"description": "Actionable conflicts and gaps. Creator-only."
},
"link_url": {
"type": "string",
"description": "Opens the document in Marcora with the grounding panel showing."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "The content item that was scanned. In content-submission mode this is the newly created item — keep it for polling and for follow-up calls."
},
"corpus_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": [
"string",
"null"
]
},
"source": {
"type": [
"string",
"null"
],
"description": "context_item, project_brief or generation."
},
"link_url": {
"type": [
"string",
"null"
],
"description": "Null for corpus entries that are not standalone context items, such as project briefs."
},
"context_item_id": {
"type": [
"string",
"null"
],
"description": "null for entries that are not context items, such as project briefs."
},
"content_category": {
"type": [
"string",
"null"
],
"description": "company_authoritative, reference_material or unclassified — how authoritative this source is."
}
}
},
"description": "The context items this scan was actually grounded against, recorded at scan time. Creator-only."
},
"excluded_items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Present only when reference material was locked mid-edit and could not be included in the corpus — the grounding is honest but incomplete."
},
"details_visible": {
"type": "boolean",
"description": "False when the caller is not the content's creator — findings, claims and corpus_items are then omitted."
}
},
"description": "The grounding envelope. check_content_grounding and get_grounding_result return exactly this shape, so one handler works for both."
}list_ci_findings
List Context Intelligence findings — issues Marcora's automated scans detected in your reference library (stale content, contradictions, outdated web sources, gaps). Newest-first; filter by status, severity, or scan type.
Input Schema
{
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "Page number (default 1)."
},
"status": {
"type": "string",
"description": "Filter by finding status: pending (actionable queue) | acknowledged | dismissed | resolved. Omit for all."
},
"per_page": {
"type": "integer",
"description": "Items per page (default 20, max 100)."
},
"severity": {
"type": "string",
"description": "Filter by severity as recorded by the scan (e.g. high, medium, low). Omit for all."
},
"process_type": {
"type": "string",
"description": "Filter by originating scan: health_audit (library-wide sweep) | web_freshness (tracked webpage changes). Omit for all."
}
}
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Finding objects: id (UUID), summary, recommendation, severity, status, process_type, finding_type, suggested_fix, context_item_ids, created_at, resolved_at, resolved_by."
},
"curPage": {
"type": "integer"
},
"nextPage": {
"type": [
"integer",
"null"
]
},
"prevPage": {
"type": [
"integer",
"null"
]
},
"itemsTotal": {
"type": "integer"
}
}
}get_ci_finding
Fetch one Context Intelligence finding in full detail by its UUID — the full recommendation, the suggested fix, and which context items it involves.
Input Schema
{
"type": "object",
"required": [
"finding_id"
],
"properties": {
"finding_id": {
"type": "string",
"description": "Required. UUID of the finding (from list_ci_findings)."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"status": {
"type": "string",
"description": "pending | acknowledged | dismissed | resolved"
},
"summary": {
"type": "string"
},
"severity": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"resolved_at": {
"type": [
"integer",
"null"
]
},
"resolved_by": {
"type": [
"integer",
"null"
]
},
"finding_type": {
"type": "string"
},
"process_type": {
"type": "string"
},
"suggested_fix": {
"type": [
"object",
"null"
],
"description": "Proposed fix: field, new_value, context_item_id."
},
"recommendation": {
"type": [
"string",
"null"
]
},
"context_item_ids": {
"type": [
"array",
"null"
]
}
}
}update_ci_finding_status
Acknowledge, dismiss, or resolve a Context Intelligence finding after reviewing it. Records resolver + timestamp on resolve; does not itself apply the suggested fix (that's done in the web app).
Input Schema
{
"type": "object",
"required": [
"finding_id",
"status"
],
"properties": {
"status": {
"type": "string",
"description": "Required. New status: acknowledged (seen, still open) | dismissed (not relevant) | resolved (issue fixed — records resolver + timestamp)."
},
"finding_id": {
"type": "string",
"description": "Required. UUID of the finding (from list_ci_findings)."
}
}
}Output Schema
{
"type": "object",
"description": "The updated finding row, including the new status (and resolved_at/resolved_by when resolved)."
}trigger_health_audit_scan
Start a library-wide Context Intelligence health audit — an AI sweep of your context/reference items that produces findings. Consumes credits, plan-gated (Business/Command), runs in the background.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "running"
},
"message": {
"type": "string"
},
"scan_run_id": {
"type": [
"string",
"null"
],
"format": "uuid"
}
}
}Content
ask_content_assistant
Send a natural-language request to Marcora's in-document Content Assistant to edit, extend, or ideate on an existing document. It runs asynchronously and streams its reply and any edits into the document's sidebar in Marcora.
Input Schema
{
"type": "object",
"required": [
"content_id",
"prompt"
],
"properties": {
"prompt": {
"type": "string",
"description": "The request in natural language (an edit, an extension, or a question)."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the content document to act on. Get from list_content, get_content, or get_project."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Project UUID (from list_projects) whose context to include."
},
"ai_provider": {
"enum": [
"anthropic",
"openai"
],
"type": "string",
"description": "Model family to use."
},
"selected_text": {
"type": "string",
"description": "Optional highlighted text in the document to focus the request on."
},
"thinking_mode": {
"type": "boolean",
"description": "Enable extended reasoning for complex requests."
},
"chat_only_mode": {
"type": "boolean",
"description": "Force a sidebar-only reply with no document changes."
},
"collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Context Collection IDs (from list_context_collections) to include."
}
}
}Output Schema
{
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Always pending on dispatch."
},
"generation_id": {
"type": "string",
"format": "uuid",
"description": "Identifies this run. Poll get_generation_status with it for the result."
}
}
}create_content
Create a content document from an AI prompt, your own supplied text, or a blueprint template. It automatically pulls in all relevant brand and reference context, so there is no need to fetch context first. When generating from `instructions`, you can also pass `reference_content_ids` to fold specific existing documents into the prompt as reference material. The document's title always comes from its first heading — there is no title parameter.
Input Schema
{
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "Pre-written text to save directly as a document (no AI generation). Mutually exclusive with `instructions` — never send both, not even to carry a title — and cannot be combined with `blueprint_uuid`. Prefer markdown-formatted content. Start with the title as a level-1 heading (`# <Title>` on the first line): the document title is taken from the first heading. Use a markdown conversion tool first if you have a url or html."
},
"plan_id": {
"type": "string",
"format": "uuid",
"description": "Optional plan UUID (from create_plan / list_plans / get_plan — use plan_uuid, not the integer id). Associates the new content with the plan and triggers an automatic stage transition to In_Process. Linkage applies only when used WITH blueprint_uuid (the async blueprint-generation path); sync paths accept the field without error but do not auto-link. Invalid plan_id is logged but does NOT fail content creation. Do NOT pass if the plan is in Complete stage — call update_plan target_stage='Accepted' first."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Optional project UUID (from list_projects) to associate the new content with. When set, the project's Project Context (brief + project context items) is automatically included in generation."
},
"category_id": {
"type": "integer",
"description": "Optional content category id from list_content_categories. Organizational only — does not change generation behavior."
},
"instructions": {
"type": "string",
"description": "AI prompt describing what to create. Mutually exclusive with `content`. Required if `content` is omitted. If the user wants a specific document title, state it in this text — the title is taken from the generated document's first heading."
},
"blueprint_uuid": {
"type": "string",
"format": "uuid",
"description": "UUID of a blueprint to generate from (get from list_blueprints). When set, this becomes an ASYNC call — poll get_generation_status with the returned generation_id. Only valid with `instructions`."
},
"collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Optional context collection IDs (from list_context_collections) to include during generation, on top of the always-on Brand Foundation + Reference Library + Project Context."
},
"dimension_option_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Optional targeting dimension OPTION IDs (from list_targeting_dimensions — drill into each dimension's options) to shape the generation for a specific audience (e.g. persona, industry, buying stage)."
},
"reference_content_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Optional content UUIDs (from list_content, or list_content with `search`) whose full text is folded into the generation prompt as reference material. The canonical way to have Marcora write with reference to existing documents — no need to paste their text into `instructions`. Valid only on the generation paths (`instructions`, with or without `blueprint_uuid`); rejected with the verbatim `content` path. An unknown or inaccessible id fails the whole call (never silently skipped)."
},
"use_extended_thinking": {
"type": "boolean",
"description": "Set true for complex content that benefits from deeper reasoning. Only applies to the freeform sync path (`instructions` without `blueprint_uuid`)."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Content record ID (only present without blueprint)."
},
"title": {
"type": "string",
"description": "Document title (only present without blueprint)."
},
"content": {
"type": "string",
"description": "Document content in markdown (only present without blueprint)."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/open this content in Marcora (only present without blueprint)."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — use as content_id in get_content and share tools (only present without blueprint)."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation (only present without blueprint)."
},
"generation_id": {
"type": "string",
"format": "uuid",
"description": "UUID to track async generation — pass to get_generation_status to poll for completion (only present WITH blueprint)."
}
},
"description": "When blueprint_uuid is NOT provided, returns the content object directly. When blueprint_uuid IS provided, returns only generation_id — poll get_generation_status to track progress."
}get_generation_status
Check the status of an asynchronous content generation started by create_content (with a blueprint) or by ask_content_assistant. Poll it with the generation_id until the run completes; once finished it returns the current document and the latest Content Assistant reply.
Input Schema
{
"type": "object",
"required": [
"generation_id"
],
"properties": {
"generation_id": {
"type": "string",
"description": "The generation ID (UUID) returned by create_content (with blueprint_uuid) or ask_content_assistant."
}
}
}Output Schema
{
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status of THIS generation_id. Terminal is \"completed\" for blueprint runs, \"complete\" for Content Assistant runs; \"failed\" on error."
},
"content": {
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": [
"string",
"null"
],
"description": "Document name."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/open the document in Marcora."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "The document UUID (blueprint flow or Content Assistant flow)."
},
"blueprint_id": {
"type": "integer",
"description": "Blueprint flow only: the blueprint used."
},
"current_content": {
"type": [
"string",
"null"
],
"description": "Content Assistant flow only: the document's CURRENT markdown (may include the user's own later edits)."
},
"document_updated": {
"type": "boolean",
"description": "Content Assistant flow only: whether the most recent interaction changed the document body."
},
"assistant_summary": {
"type": [
"string",
"null"
],
"description": "Content Assistant flow only: the most recent assistant sidebar reply for this document."
}
},
"description": "Null until the run completes. For ai_assistant, reflects the CURRENT document + the most recent assistant interaction (not a snapshot of this specific generation). Shape depends on flow_type."
},
"flow_type": {
"type": "string",
"description": "Which flow produced this generation: \"ai_assistant\" for ask_content_assistant, otherwise a blueprint/content generation."
},
"generation_id": {
"type": "string",
"description": "The generation ID being checked (UUID)."
}
}
}list_content
List all content documents visible to you as a single unified array, whether created from scratch or from a blueprint. Use a content_id to fetch full content or to create a share link. Pass a `search` query to rank results by semantic relevance instead of recency.
Input Schema
{
"type": "object",
"properties": {
"search": {
"type": "string",
"description": "Optional natural-language query. When provided, results are ranked by semantic relevance to it (instead of recency) and each row gains a relevance_score. Omit or leave empty for the normal recency-ordered list. Scores are cross-comparable with list_context_items — to find the best reference material across both content and context, call both with the same search, merge the arrays, and take the top matches by relevance_score."
}
}
}Output Schema
{
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"content_id"
],
"properties": {
"name": {
"type": "string",
"description": "Content name."
},
"stage": {
"type": "string",
"description": "in_progress or ready."
},
"web_url": {
"type": "string",
"description": "Direct URL to view this content in Marcora."
},
"category": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"description": "{id, name} or null if uncategorized."
},
"projects": {
"type": "array",
"items": {
"type": "string"
},
"description": "Project names this content belongs to."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Content identifier."
},
"created_by": {
"type": "string",
"description": "Name of the creator."
},
"visibility": {
"type": "string",
"description": "private or team."
},
"relevance_score": {
"type": [
"number",
"null"
],
"description": "Present only when a `search` query was given. A number (cosine similarity 0–1; higher = more relevant) when the item was scored against embeddings, or null when the item is not embedded yet and could not be scored (sorts last). Absent entirely when no search was provided. Cross-comparable with list_context_items relevance_score."
}
}
}
}
}
}get_content
Retrieve the full markdown body of a content document by its content_id. Use it when you need to read a document's text to answer a question about it — not to show the user content they can already open in Marcora.
Input Schema
{
"type": "object",
"required": [
"content_id"
],
"properties": {
"content_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the content to retrieve. Get from list_content, get_project (documents array), or get_generation_status."
}
}
}Output Schema
{
"type": "object",
"required": [
"content_id",
"name",
"content"
],
"properties": {
"name": {
"type": "string",
"description": "Content name."
},
"stage": {
"type": "string",
"description": "Enumeration of in_progress or ready."
},
"content": {
"type": "string",
"description": "Full document content in markdown format."
},
"category": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": "integer",
"description": "Category ID."
},
"name": {
"type": "string",
"description": "Category name."
}
},
"description": "Content category, or null if not categorized."
},
"link_url": {
"type": "string",
"description": "Direct URL to view this content in Marcora."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Content identifier."
},
"visibility": {
"type": "string",
"description": "Visibility setting (e.g. private, team)."
}
}
}update_content
Update a content document by its content_id — edit the body, rename it, or change its stage, visibility, category, or project. Only the fields you supply change, and body updates replace the entire text, so read it first when splicing into existing content.
Input Schema
{
"type": "object",
"required": [
"content_id"
],
"properties": {
"stage": {
"enum": [
"in_progress",
"ready"
],
"type": "string",
"description": "Mark the document in-progress or ready. Omit to leave stage unchanged."
},
"content": {
"type": "string",
"description": "New full markdown body. Omit to leave body unchanged. Read existing via get_content first if splicing edits."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the content to update. Get from list_content, get_content, get_generation_status, or get_project."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Project UUID to set as this document's project. Replaces any existing project association. Omit to leave project unchanged."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "Document visibility. Omit to leave unchanged."
},
"category_id": {
"type": "integer",
"description": "Category ID from list_content_categories. Omit to leave unchanged."
},
"name_override": {
"type": "string",
"description": "Custom document name. Setting this locks the name (won't auto-resync from content header on future edits). Omit unless overriding the auto-derived title."
},
"change_summary": {
"type": "string",
"description": "What changed and why, for the doc's AI-assistant history. Format as skimmable markdown — a bulleted list (bold lead + detail) for multi-part edits."
}
}
}Output Schema
{
"type": "object",
"required": [
"content_id",
"name",
"content"
],
"properties": {
"name": {
"type": "string",
"description": "Document name (computed from name_override + has_custom_name + content header)."
},
"stage": {
"type": "string",
"description": "Enum: in_progress or ready."
},
"content": {
"type": "string",
"description": "Full document content in markdown."
},
"category": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": "integer",
"description": "Category ID."
},
"name": {
"type": "string",
"description": "Category name."
}
},
"description": "Content category, or null if not categorized."
},
"link_url": {
"type": "string",
"description": "Direct URL to view this content in Marcora."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Content identifier."
},
"visibility": {
"type": "string",
"description": "Enum: private or team."
}
}
}Workflows
create_workflow
Create a reusable, multi-step workflow template for the team, with an explicit list of allowed tools. New workflows are saved Inactive and any schedule is saved Paused — it runs on its own only once the workflow is set Active and the user turns the schedule on with Resume schedule in the app.
Input Schema
{
"type": "object",
"required": [
"name",
"steps",
"allowed_tools"
],
"properties": {
"name": {
"type": "string",
"description": "Display name for the workflow, shown in the workflow list and passed to the agent that runs it. Required and must be non-empty — a missing or blank value is rejected. `list_workflows` searches on this name, so make it distinctive and confirm the wording with the user first."
},
"tags": {
"description": "Free-form labels for organizing workflows. Must be an array of strings; any other value is ignored and a single blank tag is stored instead. Purely descriptive — listing and search do not filter on tags."
},
"steps": {
"description": "Ordered list of the actions the workflow should perform, handed to the agent as JSON at run time. Required. Write each step so a fresh agent with no conversation history can carry it out without asking follow-up questions."
},
"inputs": {
"description": "Object declaring the values this workflow expects at run time (for example a topic or a date range). It is stored and returned as documentation for callers and for the app UI; the agent itself receives the actual per-run values via `input_values`, not this declaration. Optional — defaults to an empty object."
},
"description": {
"type": "string",
"description": "One or two sentences on what the workflow accomplishes. It is inserted verbatim into the prompt given to the agent that runs the workflow, so write it as orienting context, not marketing copy. Optional — stored as an empty string when omitted."
},
"allowed_tools": {
"description": "REQUIRED, non-empty. Tools the workflow runner may use; an empty list is rejected."
},
"schedule_config": {
"type": "object",
"properties": {
"hour": {
"type": "integer",
"maximum": 23,
"minimum": 0,
"description": "Calendar mode: hour of day in UTC (0–23). Selects calendar mode when present."
},
"timezone": {
"type": "string",
"description": "The user's IANA timezone, for display only. Does not change when the schedule runs."
},
"frequency": {
"enum": [
"hourly",
"daily",
"weekly"
],
"type": "string",
"description": "\"daily\" or \"weekly\" (the app's editor options). \"hourly\" is interval mode only. Anything else is treated as daily."
},
"day_of_week": {
"type": "integer",
"maximum": 6,
"minimum": 0,
"description": "Calendar mode with frequency \"weekly\": a single day in UTC, 0=Sunday … 6=Saturday. Superseded by `days_of_week`, which the app now writes; still read when `days_of_week` is absent."
},
"days_of_week": {
"type": "array",
"items": {
"type": "integer",
"maximum": 6,
"minimum": 0
},
"maxItems": 7,
"minItems": 1,
"description": "Calendar mode with frequency \"weekly\": the days to run on, in UTC — 0=Sunday … 6=Saturday. 1–7 distinct integers; requires an integer `hour`. This is how a multi-day cadence (\"3 times a week\" → [1,3,5]) is saved, and it is what the app's weekday picker edits. Rejected with a readable error if the values are out of range, duplicated, or `hour` is missing.",
"uniqueItems": true
},
"interval_hours": {
"type": "number",
"description": "Interval mode only (ignored when `hour` is set): hours between runs.",
"exclusiveMinimum": 0
}
},
"description": "Include only when the user explicitly asks for the workflow to run on a schedule. A non-empty object creates the schedule, which is always saved Paused — the user turns it on in the app with \"Resume schedule\", and it fires only while the workflow is Active. Two modes:\n- **Calendar mode (preferred — it is what the app's editor shows and edits):** set `hour` (integer 0–23, in **UTC**). With `frequency: \"weekly\"`, set `days_of_week` — an array of 1–7 distinct integers, 0=Sunday … 6=Saturday, in **UTC** — so \"3 times a week\" is one schedule, e.g. `[1,3,5]`. (The older single `day_of_week` is still read when `days_of_week` is absent; prefer the array.) Any frequency other than weekly runs daily at `hour`. Convert the user's local time (and weekday) to UTC yourself, and set `timezone` to the user's IANA timezone (e.g. \"America/Sao_Paulo\") for display.\n- **Interval mode (when `hour` is absent):** runs every `interval_hours` hours, or every 1 / 24 / 168 hours for hourly / daily / weekly if `interval_hours` is omitted. There is no fixed time of day, and the first run is one full interval after the user switches the schedule on. The app's editor cannot show or edit an interval schedule, so use it only when calendar mode can't express what the user needs, and say what you saved.\n`timezone` is display-only; the scheduler always uses UTC."
}
}
}Output Schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id",
"name",
"status",
"team_id",
"created_at",
"link_url"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Workflow UUID. Use as workflow_id in other workflow tools."
},
"name": {
"type": "string"
},
"tags": {
"type": "array"
},
"steps": {
"type": "array"
},
"inputs": {
"type": "object"
},
"status": {
"enum": [
"inactive",
"active",
"archived"
],
"type": "string"
},
"team_id": {
"type": "integer"
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view this workflow in Marcora."
},
"schedule": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Plain-language description of exactly what was saved (times in UTC). Quote it to the user."
},
"is_enabled": {
"type": "boolean",
"description": "Always false on create: the schedule is Paused, and does not fire until the user clicks \"Resume schedule\" in the app — and even then only while the workflow is Active."
},
"trigger_id": {
"type": "string",
"format": "uuid"
},
"schedule_config": {
"type": "object"
}
},
"description": "Present only when schedule_config created a schedule. Read back from the saved schedule."
},
"next_step": {
"type": "string",
"description": "Always present. What will and won't run, across both switches — the workflow's status (Active / Inactive) and its schedule (On / Paused / none) — computed from what was saved, with the words to use. Follow it and lead your reply with it."
},
"created_at": {
"type": "integer"
},
"updated_at": {
"type": "integer"
},
"description": {
"type": "string"
},
"allowed_tools": {
"type": "array"
},
"created_by_user_id": {
"type": "integer"
}
}
}get_workflow
Fetch one workflow's full definition, triggers, latest run and run_state — whether the workflow is Active or Inactive and whether its schedule is On, Paused or absent. Always call it before update_workflow so you can preserve the fields you are not changing.
Input Schema
{
"type": "object",
"required": [
"workflow_id"
],
"properties": {
"workflow_id": {
"type": "string",
"description": "UUID of the workflow to fetch, as returned by `list_workflows` or `create_workflow`. The workflow must belong to the user's current team; a workflow owned by another team is refused. Fetch this before any `update_workflow` call so you can preserve the fields you are not changing."
}
}
}Output Schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"workflow"
],
"properties": {
"workflow": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"steps": {
"type": "array"
},
"inputs": {
"type": "object"
},
"status": {
"type": "string"
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view this workflow in Marcora."
},
"schedule": {
"type": "object",
"description": "Present only when the workflow has a schedule. Read back from the saved schedule: trigger_id, is_enabled (true = On, false = Paused), summary (plain language, times in UTC), schedule_config."
},
"_triggers": {
"type": "array"
},
"run_state": {
"type": "string",
"description": "What will and won't run, across both switches — the workflow's status (Active / Inactive) and its schedule (On / Paused / none) — with the words to use. Follow it when you describe the workflow to the user."
},
"_latest_run": {
"type": [
"object",
"null"
],
"description": "Most recent run, or null. When present, includes its own link_url."
},
"allowed_tools": {
"type": "array"
}
}
}
}
}get_workflow_runs
Inspect a workflow's run history — either a paginated list of runs, or the detailed step and tool-call logs for a single run. Useful for checking whether a workflow ran and for troubleshooting failures.
Input Schema
{
"type": "object",
"required": [
"workflow_id"
],
"properties": {
"page": {
"type": "integer",
"description": "1-based page number through the run list, which is ordered newest first. Defaults to 1, so you only need it to reach runs older than the first page. Ignored when `run_id` is supplied."
},
"run_id": {
"type": "string",
"description": "UUID of one specific run to inspect in full — its step-by-step logs, tool calls and the agent's messages. Pass it when the user asks what a particular run actually did. Omit it to get the paginated list of runs instead."
},
"status": {
"type": "string",
"description": "Restricts the run list to a single exact status: \"pending\", \"running\", \"succeeded\", \"failed\" or \"skipped\". Use \"failed\" when troubleshooting, or \"running\" to see whether something is in flight. Ignored when `run_id` is supplied."
},
"per_page": {
"type": "integer",
"description": "How many runs to return per page. Defaults to 20 when omitted or when the value is not a positive number; set it low (for example 5) when you only need the most recent few. Ignored when `run_id` is supplied."
},
"workflow_id": {
"type": "string",
"description": "UUID of the workflow whose run history you want. Required. It scopes the list of runs; when you also pass `run_id`, the run is looked up by that id alone and this value is not used to filter."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Single-run mode — the run UUID."
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"status": {
"type": "string"
},
"link_url": {
"type": "string",
"format": "uri"
},
"workflow_template_id": {
"type": "string",
"format": "uuid"
}
}
},
"description": "List mode only — array of runs (most recent first)."
},
"status": {
"type": "string",
"description": "Single-run mode — run status."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "URL to the run detail page (single-run mode; also present on each list item)."
},
"_step_logs": {
"type": "array",
"description": "Single-run mode — per-step execution logs."
},
"itemsTotal": {
"type": "integer",
"description": "List mode only — total number of runs."
},
"_tool_call_logs": {
"type": "array",
"description": "Single-run mode — tool call logs."
},
"workflow_template_id": {
"type": "string",
"format": "uuid",
"description": "Single-run mode — parent workflow UUID."
}
},
"description": "Workflow run history. Shape depends on whether run_id was supplied. List mode (run_id omitted) populates items + itemsTotal. Single-run mode (run_id supplied) populates id, workflow_template_id, status, _step_logs, and _tool_call_logs."
}list_workflows
List the team's workflows, with an optional status filter (Active, Inactive or archived) and name search. Use it to see existing workflows or to check for duplicate names before creating one.
Input Schema
{
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "1-based page number through the list, which is ordered newest first. Defaults to 1; only needed when the team has more workflows than a single page holds."
},
"search": {
"type": "string",
"description": "Case-insensitive substring match against the workflow name only — it does not look at descriptions, steps or tags. Use it before creating a workflow to check the team does not already have one with a similar name."
},
"status": {
"type": "string",
"description": "Restricts results to workflows in one state: \"active\", \"inactive\" or \"archived\". Omit to return every workflow for the user's current team. Use \"active\" when the user asks what automations are able to run — Active means allowed to run, not running; whether one runs on its own also depends on its schedule (see get_workflow)."
},
"per_page": {
"type": "integer",
"description": "How many workflows to return per page. Defaults to 20 when omitted or when the value is not a positive number."
}
}
}Output Schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view this workflow in Marcora."
}
}
}
},
"curPage": {
"type": "integer"
},
"nextPage": {
"type": [
"integer",
"null"
]
},
"prevPage": {
"type": [
"integer",
"null"
]
},
"itemsTotal": {
"type": "integer"
}
}
}run_workflow
Manually run an Active workflow, dispatching a live agent session. Inactive workflows are refused; a Paused schedule does not block manual runs. Returns the run record — check its status to see whether the run started, failed, or was skipped.
Input Schema
{
"type": "object",
"required": [
"workflow_id"
],
"properties": {
"workflow_id": {
"type": "string",
"description": "UUID of the workflow to run immediately. The workflow must be \"active\" — running an inactive or archived one is rejected, so set the status with `update_workflow` first. Its schedule's state (On or Paused) does not matter for a manual run. The call starts the run and returns straight away; it does not wait for the work to finish."
},
"input_values": {
"description": "Object holding the actual values for this run, matching the fields the workflow declares in its `inputs`. They are handed to the agent as the run's inputs and it is instructed to use only what you provide, so include every id or value the steps depend on. Defaults to an empty object when omitted, which is correct for workflows that take no inputs."
}
}
}Output Schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Workflow run UUID."
},
"status": {
"type": "string"
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view this run in Marcora."
},
"error_reason": {
"type": [
"string",
"null"
]
},
"trigger_type": {
"type": "string"
},
"error_summary": {
"type": "string"
},
"runner_session_id": {
"type": "string"
},
"workflow_template_id": {
"type": "string",
"format": "uuid",
"description": "Parent workflow UUID."
}
}
}update_workflow
Make a partial update to a workflow template; only the fields you send change. Use it to set a workflow Active or Inactive, rename, archive, or edit its steps — call get_workflow first. It cannot edit a schedule or turn one on.
Input Schema
{
"type": "object",
"required": [
"workflow_id"
],
"properties": {
"name": {
"type": "string",
"description": "New display name for the workflow. Omit it to leave the name as it is — only the keys you send are written."
},
"tags": {
"description": "Replacement array of label strings; it overwrites the existing tags. Must be an array — any other value leaves the tags untouched."
},
"steps": {
"description": "Replacement ordered list of actions. It overwrites the existing steps outright rather than merging, so start from the list `get_workflow` returned and send the whole intended sequence. Omit it — or send an empty object, which counts as \"not provided\" — to leave the steps unchanged."
},
"inputs": {
"description": "Replacement declaration of the values the workflow expects at run time. It overwrites the previous declaration outright. Omit it to leave it unchanged; note an empty object `{}` is also treated as \"not provided\" and changes nothing."
},
"status": {
"type": "string",
"description": "Lifecycle state of the workflow: \"active\" (allowed to run — required before `run_workflow` will start it or its schedule will fire), \"inactive\" (nothing runs, by any route; its schedule, if any, is kept exactly as it is) or \"archived\" (the soft-delete convention; the record is kept but taken out of normal use). Set \"active\" only once the user has confirmed the steps. Any other value is rejected and nothing is saved — there is no \"paused\" status: pausing is something a schedule does, and the user does it in the app."
},
"description": {
"type": "string",
"description": "Replacement description. It is inserted into the prompt given to the agent that runs the workflow, so refresh it whenever the steps change meaningfully. Omit to leave it unchanged."
},
"workflow_id": {
"type": "string",
"description": "UUID of the workflow to update, as returned by `list_workflows`, `create_workflow` or `get_workflow`. Required, and the workflow must belong to the user's current team. Call `get_workflow` first so you can send a minimal change set and know what the current values are."
},
"allowed_tools": {
"description": "Replacement list of the tools the workflow's agent is permitted to call. It overwrites the existing allowlist, so send the full intended set rather than just additions, and keep it tight for scheduled workflows. Omit it (or send an empty object) to leave the allowlist unchanged."
}
}
}Output Schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"tags": {
"type": "array"
},
"steps": {
"type": "array"
},
"inputs": {
"type": "object"
},
"status": {
"type": "string"
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view this workflow in Marcora."
},
"schedule": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Plain-language description of what is saved (times in UTC)."
},
"is_enabled": {
"type": "boolean",
"description": "false = the schedule is Paused: it does not fire until the user clicks \"Resume schedule\" in the app. true = On, which fires only while the workflow is Active."
},
"trigger_id": {
"type": "string",
"format": "uuid"
},
"schedule_config": {
"type": "object"
}
},
"description": "Present whenever the workflow has a schedule, on every update. Inert context, read back from the saved trigger."
},
"next_step": {
"type": "string",
"description": "Present ONLY when this call set status to \"active\" or \"inactive\". What will and won't run afterwards, across both switches — the workflow's status and its schedule — with the words to use. Follow it in substance. A call that changes anything else (a rename, say) returns no next_step, so nothing asserts a change that did not happen or pushes the user toward a schedule they did not ask about."
},
"updated_at": {
"type": "integer"
},
"allowed_tools": {
"type": "array"
}
}
}Account
get_current_user_info
Return profile and subscription information for the current user, including their active team, plan, and remaining AI credits. Use it to personalize responses or check limits before creating content.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"name",
"email",
"active_team_name",
"active_team_role",
"plan_name",
"plan_slug",
"subscription_status",
"ai_credits_available",
"ai_credits_max"
],
"properties": {
"name": {
"type": "string",
"description": "User's display name."
},
"email": {
"type": "string",
"description": "User's email address."
},
"plan_name": {
"type": "string",
"description": "Subscription plan display name."
},
"plan_slug": {
"type": "string",
"description": "Subscription plan identifier."
},
"ai_credits_max": {
"type": "integer",
"description": "AI credit limit for this billing period."
},
"active_team_name": {
"type": "string",
"description": "Name of the user's active team."
},
"active_team_role": {
"type": "string",
"description": "User's role on the active team."
},
"subscription_status": {
"type": "string",
"description": "Current subscription status."
},
"ai_credits_available": {
"type": "integer",
"description": "AI credits remaining this billing period (limit minus used)."
}
}
}get_team_info
Always call when the user asks what team accounts they have, which teams they belong to / are on, or wants to switch teams — do NOT answer from memory or session context, which knows only the single currently-active team and will undercount. This tool is the only way to enumerate the full list. Returns every team you belong to, each with its full member roster. Read-only, no inputs.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"teams"
],
"properties": {
"teams": {
"type": "array",
"items": {
"type": "object",
"required": [
"team_id",
"team_name",
"is_active",
"your_role",
"members"
],
"properties": {
"members": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"role",
"status"
],
"properties": {
"name": {
"type": "string",
"description": "Member name (or the invited email for pending invites)."
},
"role": {
"type": "string",
"description": "Member's role."
},
"email": {
"type": [
"string",
"null"
],
"description": "Member email."
},
"status": {
"type": "string",
"description": "active or invited."
},
"user_id": {
"type": [
"integer",
"null"
],
"description": "Numeric user id (what assigned_to expects). null for a pending invite."
}
}
},
"description": "The team's members."
},
"team_id": {
"type": "integer",
"description": "Numeric team id. Pass to set_active_team."
},
"is_active": {
"type": "boolean",
"description": "True for the caller's currently active team (exactly one)."
},
"team_name": {
"type": "string",
"description": "Team name."
},
"your_role": {
"type": "string",
"description": "The caller's role in this team (e.g. admin, editor, viewer)."
}
}
},
"description": "Every team the caller is an active member of."
}
}
}set_active_team
Sets your active team — the team all subsequent Marcora tool calls operate against. Switching changes your active team everywhere for your account; the response returns `previous_team_id` so you can restore it afterward.
Input Schema
{
"type": "object",
"required": [
"team_id"
],
"properties": {
"team_id": {
"type": "integer",
"description": "The numeric team_id (from get_team_info) to switch to. Must be a team you belong to."
}
}
}Output Schema
{
"type": "object",
"required": [
"active_team"
],
"properties": {
"active_team": {
"type": "object",
"required": [
"team_id",
"team_name"
],
"properties": {
"team_id": {
"type": "integer",
"description": "The now-active team's id."
},
"team_name": {
"type": "string",
"description": "The now-active team's name."
}
}
},
"previous_team_id": {
"type": [
"integer",
"null"
],
"description": "The team that was active before this call. Pass it back to set_active_team to restore."
}
}
}invite_user
Invite someone to your Marcora account by email as a creator or admin, or into a specific project as a collaborator. An invitation email is sent automatically, and the response also returns the exact invite link so you can share it directly. Admins can invite any role; a creator can invite collaborators only.
Input Schema
{
"type": "object",
"required": [
"email",
"role"
],
"properties": {
"role": {
"enum": [
"admin",
"creator",
"collaborator"
],
"type": "string",
"description": "Role to grant: admin, creator, or collaborator"
},
"email": {
"type": "string",
"description": "Email address of the person to invite"
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Project UUID (from list_projects). Required for collaborator; for creator/admin, optionally also adds them to this project and deep-links their invite to it."
}
}
}Output Schema
{
"type": "object",
"required": [
"outcome",
"emailed",
"message",
"email",
"role"
],
"properties": {
"role": {
"type": "string",
"description": "`admin`, `creator`, or `collaborator`."
},
"email": {
"type": "string",
"description": "The invited email address."
},
"emailed": {
"type": "boolean",
"description": "True when an invitation email was sent."
},
"message": {
"type": "string",
"description": "Human-readable summary of what happened."
},
"outcome": {
"type": "string",
"description": "`invited` (an invitation email was sent) or `added_to_project` (the email was already a team member and was added straight to the project)."
},
"project_id": {
"type": [
"string",
"null"
],
"description": "Project the invitee was added to / pointed at, if any."
},
"invite_link": {
"type": [
"string",
"null"
],
"description": "The exact link to share directly — the sign-up link (with the project deep-link when a project was given) for new users, or the login URL for existing users. null when no invitation was sent."
},
"invite_token": {
"type": [
"string",
"null"
],
"description": "Invitation token, when one was sent."
},
"existing_user": {
"type": [
"boolean",
"null"
],
"description": "True if the email already had a Marcora account (login link) vs a new sign-up link."
},
"invitation_id": {
"type": [
"integer",
"null"
],
"description": "ID of the created/reused invitation, when one was sent."
}
}
}Context & Resources
get_brand_foundation
Return the team's Brand Foundation: company overview, brand voice, writing style, and writing examples. Call it whenever the user asks about, or wants you to use, their brand voice, company information, or writing style.
Input Schema
{
"type": "object",
"properties": {
"elements": {
"type": "array",
"items": {
"enum": [
"company_overview",
"brand_voice",
"writing_style",
"writing_examples"
],
"type": "string"
},
"description": "Optional subset of elements to return. Omit or pass empty to return all four."
}
}
}Output Schema
{
"type": "object",
"properties": {
"link_url": {
"type": "string",
"description": "Deep-link to the Brand Foundation section in the Marcora web app. Always present."
},
"brand_voice": {
"type": "string",
"description": "Markdown content for Brand Voice. Empty string if not set. Only present if requested via elements."
},
"writing_style": {
"type": "string",
"description": "Markdown content for Writing Style. Empty string if not set. Only present if requested via elements."
},
"company_overview": {
"type": "string",
"description": "Markdown content for Company Overview. Empty string if not set. Only present if requested via elements."
},
"writing_examples": {
"type": "string",
"description": "Markdown content for Writing Examples. Free-form structure — whatever the user has saved. Empty string if not set. Only present if requested via elements."
}
}
}list_context_collections
List all context collections you can access. Collections group reference materials; use a collection's ID to add items to it or to target context retrieval.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"collections"
],
"properties": {
"collections": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Collection ID. Pass to add_context or get_relevant_context."
},
"name": {
"type": "string",
"description": "Collection name."
},
"link_url": {
"type": "string",
"description": "URL to view this collection in the Marcora web app."
},
"is_private": {
"type": "boolean",
"description": "Whether this collection is private to the creator."
},
"item_count": {
"type": "integer",
"description": "Number of context items in this collection."
},
"description": {
"type": "string",
"description": "Collection description."
}
}
}
}
}
}update_brand_foundation
Overwrite one of the team's four Brand Foundation elements — company overview, brand voice, writing style, or writing examples — with new content. Always a full replace, so read the current value with get_brand_foundation first to confirm what's being replaced.
Input Schema
{
"type": "object",
"required": [
"element",
"content"
],
"properties": {
"content": {
"type": "string",
"description": "New markdown content for the element. Replaces existing content in full. Free-form — no enforced structure."
},
"element": {
"enum": [
"company_overview",
"brand_voice",
"writing_style",
"writing_examples"
],
"type": "string",
"description": "Which Brand Foundation element to overwrite."
}
}
}Output Schema
{
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "Updated markdown content."
},
"element": {
"enum": [
"company_overview",
"brand_voice",
"writing_style",
"writing_examples"
],
"type": "string",
"description": "Which element was updated."
},
"link_url": {
"type": "string",
"description": "Deep-link to the Brand Foundation section in the Marcora web app. Always present."
}
}
}create_context_collection
Create a new context collection to group related reference materials for easier management and targeted retrieval. Use the returned ID with add_context to add items to the collection.
Input Schema
{
"type": "object",
"required": [
"name",
"description",
"is_private"
],
"properties": {
"name": {
"type": "string",
"description": "Display name for the collection, shown wherever collections are listed and picked. Required. Make it specific — \"Q2 Product Research\" rather than \"Research\" — since it is the only label anyone sees when filing reference material into it."
},
"is_private": {
"type": "boolean",
"description": "true makes the collection visible only to you: material filed in it is hidden from every other team member, including from their list_context_items and get_context_item calls. false shares it with the whole team, which is the default and the right choice unless the user explicitly asks to keep it to themselves."
},
"description": {
"type": "string",
"description": "Free-text note on what belongs in this collection, so you and teammates file material consistently later. It is stored for display only and has no effect on search, retrieval, or generation. An empty string is accepted if there is nothing useful to say."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Collection ID. Pass this as collection_id to add_context to add items to this collection."
},
"name": {
"type": "string",
"description": "Collection name."
},
"link_url": {
"type": "string",
"description": "URL to view this collection in the Marcora web app."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"is_private": {
"type": "boolean",
"description": "Whether this collection is private to the creator."
},
"description": {
"type": "string",
"description": "Collection description."
}
}
}add_context
Add a new reference item to your context library, the source material that powers on-brand AI generation. Supply the body as pasted markdown, a one-off URL import, or a tracked live web page, and optionally file it under a collection or project.
Input Schema
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Short, descriptive label for this reference item, shown in the library list and used when the AI cites it — make it specific enough to tell similar items apart (\"Q3 Pricing Page\" rather than \"Pricing\"). Required. When tracking a live web page, an empty name falls back to the page's own title."
},
"content": {
"type": "string",
"description": "The item's body as markdown, pasted inline. Best for short or hand-authored material — it is stored as-is and embedded for retrieval immediately, so the item is usable the moment the call returns. Exactly one of content, import_url, or connected_webpage_url must be set; sending none, or more than one, is rejected with a 400 (an empty string counts as not set)."
},
"import_url": {
"type": "string",
"description": "A publicly reachable URL to fetch ONCE and store as a static markdown snapshot; the URL itself is not kept, so the item can never be refreshed. Use it for one-off material — a competitor's post, an exported doc behind a temporary link. Exactly one of content, import_url, or connected_webpage_url may be set (none or two-plus → 400), and the fetch runs in the background: the call returns straight away with import_status \"processing\", so poll get_context_item with the returned id until the body lands."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "UUID of a project to attach this item to, from list_projects, so it shows up as that project's reference material. Omit it to leave the item unattached to any project. The project must belong to your team or the call fails, and users with the collaborator role can only add reference material inside a project, so for them this is effectively required."
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "Numeric ID of the collection to file this item in, from list_context_collections or create_context_collection. Omit it (or pass null or 0) to leave the item loose in the reference library. The collection must belong to your team, and a private collection must be one you created — otherwise the call is rejected."
},
"connected_webpage_url": {
"type": "string",
"description": "A URL to track as a live page: the page is fetched and its URL is stored, so the item can be re-pulled later with update_context refresh_webpage. Use it for the customer's own pages and anything you want to keep current; re-adding a URL the team already tracks updates that item in place rather than creating a duplicate. Exactly one of content, import_url, or connected_webpage_url may be set (none or two-plus → 400), and adding a tracked page requires an admin or editor role."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Context item ID"
},
"name": {
"type": "string",
"description": "Context item name"
},
"content": {
"type": [
"string",
"null"
],
"description": "The stored reference content (null for import_url / connected_webpage_url items while processing — fetch the full body with get_context_item)"
},
"link_url": {
"type": "string",
"description": "URL to view this context item in the Marcora web app."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation"
},
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Project association (if assigned)"
},
"word_count": {
"type": "integer",
"description": "Word count of content (0 while an import / webpage fetch is still processing)"
},
"content_type": {
"type": "string",
"description": "manual (content/import_url) or webpage (connected_webpage_url)"
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "Collection this item belongs to (if assigned)"
},
"import_status": {
"type": [
"string",
"null"
],
"description": "For import_url and connected_webpage_url items: processing (fetch running in background) then ready once loaded. null for pasted content."
}
}
}update_context
Update an existing context item: change its name, body, collection, or project, or re-pull a tracked web page's content. Collection and project use full-replace semantics, so always pass both.
Input Schema
{
"type": "object",
"required": [
"context_item_id",
"collection_id"
],
"properties": {
"name": {
"type": "string",
"description": "New display name for the item. Omit it to leave the current name untouched — this is not a rename-to-blank; only a value you actually pass takes effect. Changing the name re-embeds the item so retrieval matches the new wording. Ignored when refresh_webpage is true."
},
"content": {
"type": "string",
"description": "Replacement markdown body — the complete new text, not a patch or an append. Omit it to leave the existing body alone; passing it re-embeds the item for retrieval and queues a re-check of anything that relied on the old text. Mutually exclusive with import_url (sending both → 400), and ignored when refresh_webpage is true."
},
"import_url": {
"type": "string",
"description": "A publicly reachable URL that is fetched and converted to markdown, replacing the whole body with a fresh one-off snapshot — use it instead of content when the new body is large. Unlike add_context, this fetch happens inline, so the call takes longer and returns a 400 if extraction fails; it is a snapshot only, so to keep a tracked page in sync use refresh_webpage instead. Mutually exclusive with content (both → 400), and ignored when refresh_webpage is true."
},
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "The project this item is attached to AFTER the update — full-replace, with NO \"leave unchanged\" option, and the one field on this tool that can lose data. Omitting the key is treated identically to passing null: the item is DETACHED from whatever project it was in, and the call still returns 200 so nothing warns you. To keep the item where it is you must read its current project_id (get_context_item) and pass that value back on every call; pass a different ID to move it (the project must belong to the same team), and pass null only when you intend to detach it. Not read at all when refresh_webpage is true, so a refresh never moves the item."
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "The collection this item should sit in AFTER the update. You must send this key on every call — omitting it is a 400 (\"Missing param: collection_id\") — because it fully replaces the current value rather than merging. Pass the item's current collection ID to keep it where it is, a different ID to move it, or null (or 0) to move it back to the loose reference library; read the current value with get_context_item first if you don't know it. Not read at all when refresh_webpage is true, so it is not required on that branch."
},
"context_item_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the reference item to update — required, and the only way to target the item. Get it from list_context_items, get_project, get_relevant_context, or the id returned by add_context. An unknown id returns not-found, and an item belonging to another team is rejected."
},
"refresh_webpage": {
"type": "boolean",
"description": "Set true to re-pull a tracked page's body from the URL stored when it was added — the same action as the refresh button in the app. It only works on items added via add_context connected_webpage_url; on anything else it returns an error telling you to use content or import_url instead. When true, name, content, and import_url are all ignored, and so are collection_id and project_id — this branch does not read them, so collection_id is not required here and the item stays in whatever project and collection it was already in. Defaults to false."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Context item ID"
},
"name": {
"type": "string",
"description": "Updated context item name"
},
"content": {
"type": "string",
"description": "Updated reference content"
},
"link_url": {
"type": "string",
"description": "URL to view this context item in the Marcora web app."
},
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Project this item is associated with (null if none)"
},
"updated_at": {
"type": "integer",
"description": "Unix timestamp of last update"
},
"word_count": {
"type": "integer",
"description": "Word count of updated content"
},
"content_type": {
"type": "string",
"description": "manual or webpage"
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "Collection this item belongs to (null if none)"
},
"content_intro": {
"type": "string",
"description": "Truncated content intro used in listings"
},
"relevancy_processed_status": {
"enum": [
"unprocessed",
"provisional",
"complete"
],
"type": "string",
"description": "Targeting-dimension processing state, for reference-library items only. Omitted entirely for items that belong to a project or a context collection. This does NOT indicate whether the item is embedded or retrievable — every context item is embedded for semantic search at ingestion regardless of this value. Reset to 'unprocessed' whenever name or content changes."
}
}
}get_relevant_context
Search the team's context library and return the most relevant chunks for a prompt. Use it when you need to read context yourself to answer a question or ideate — not before create_content, which gathers context automatically.
Input Schema
{
"type": "object",
"required": [
"prompt"
],
"properties": {
"prompt": {
"type": "string",
"description": "Search prompt describing the topic / question you want context on. Be specific (e.g. \"competitor X's pricing model\" rather than \"competitors\")."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Optional project UUID (from list_projects). Additive: ALSO searches that project's context alongside your general library — not an exclusive filter."
},
"collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Optional context collection IDs (from list_context_collections). Additive: ALSO searches those collections alongside your general library — not an exclusive filter."
},
"context_rag_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Optional list of previously-returned chunk IDs to exclude (for pagination — pass back the context_rag_ids from a prior call)."
},
"dimension_option_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Optional targeting dimension OPTION IDs (from list_targeting_dimensions) to scope the search by audience / persona / industry / etc."
},
"_frontend_realtime_key": {
"type": "string",
"description": "For frontend progress updates only. Do not use from MCP clients."
},
"include_brand_foundation": {
"type": "boolean",
"description": "Set true to also include the team's Brand Foundation in the response. Default false."
}
}
}Output Schema
{
"type": "object",
"properties": {
"sources": {
"type": "array",
"items": {
"type": "object",
"required": [
"context_item_id",
"context_rag_ids"
],
"properties": {
"is_stale": {
"type": [
"boolean",
"null"
],
"description": "True when this item is flagged as out of date — treat its claims with caution and prefer a fresher source."
},
"link_url": {
"type": [
"string",
"null"
],
"description": "Deep-link that opens this item in the Marcora web app."
},
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "The project the item belongs to, if any."
},
"source_url": {
"type": "string",
"description": "Original external page URL. Present only for webpage items."
},
"content_type": {
"type": [
"string",
"null"
],
"description": "One of: file, manual, webpage, canvas, deliverable, integration_data, call_transcript."
},
"last_updated": {
"type": [
"integer",
"null"
],
"description": "Unix ms timestamp of the item's last update."
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "The collection the item belongs to, if any."
},
"context_item_id": {
"type": "string",
"format": "uuid",
"description": "The parent context item's ID."
},
"context_rag_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "The chunk IDs in this response that belong to this item."
},
"content_category": {
"type": [
"string",
"null"
],
"description": "How this item is classified for grounding: company_authoritative (the team's own source of truth), reference_material, or unclassified. Authoritative sources outrank reference material when they disagree."
},
"context_item_name": {
"type": [
"string",
"null"
],
"description": "The item's name."
}
}
},
"description": "One entry per parent context item the returned chunks came from."
},
"retrieval": {
"type": "object",
"properties": {
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Echo of the project_id input."
},
"team_scope": {
"type": "string",
"description": "Always authenticated_user_active_team."
},
"collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Echo of the collection_ids input."
},
"returned_count": {
"type": "integer",
"description": "Number of context chunks returned."
},
"dimension_option_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Echo of the dimension_option_ids input."
},
"excluded_context_rag_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Echo of the context_rag_ids input (the exclusions)."
}
},
"description": "Echo of the search scope this response was produced under."
},
"context_rag_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "All chunk IDs returned. Pass back in context_rag_ids to exclude from future searches (pagination)."
},
"brand_foundation": {
"type": "object",
"properties": {
"elements": {
"type": [
"object",
"null"
],
"properties": {
"brand_voice": {
"type": "string"
},
"writing_style": {
"type": "string"
},
"company_overview": {
"type": "string"
},
"writing_examples": {
"type": "string"
}
},
"description": "Null unless included. When present: company_overview, brand_voice, writing_style, writing_examples (all strings)."
},
"included": {
"type": "boolean",
"description": "True only when include_brand_foundation: true was passed."
},
"link_url": {
"type": "string",
"description": "Deep-link to the Brand Foundation tab in the Marcora web app (present only when included)."
}
},
"description": "Always present. elements is null unless include_brand_foundation is true."
},
"relevant_context": {
"type": "string",
"description": "Ready-to-use markdown context packet assembled from the matched chunks."
}
}
}list_context_items
List context items from the team's library, each with its collection, project, and a link to open it in Marcora. By default it returns all items you can see; private items you don't have access to are filtered out. Pass a `search` query to rank items by semantic relevance instead of recency.
Input Schema
{
"type": "object",
"properties": {
"search": {
"type": "string",
"description": "Optional natural-language query. When provided, items are ranked by semantic relevance to it (by their best-matching chunk) instead of recency, and each item gains a relevance_score. Omit or leave empty for the normal recency-ordered list. Scores are cross-comparable with list_content — call both with the same search, merge, and take the top matches by relevance_score."
},
"reference_library_only": {
"type": "boolean",
"description": "Set true to return only the items that sit in no project and no collection — what the app shows as the \"Reference Library\". Leave it out (default false) to get everything you can see across projects, collections, and the reference library. Set it true when you want a clean view of unfiled material, for example to decide what still needs organising."
}
}
}Output Schema
{
"type": "object",
"required": [
"context_items"
],
"properties": {
"context_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name",
"link_url"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Context item ID. Pass to get_context_item to fetch full markdown."
},
"name": {
"type": "string"
},
"added_by": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"description": "{id: integer, name: string} — the user who added the item."
},
"link_url": {
"type": "string",
"description": "URL to view this context item in the Marcora web app."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Project this item is associated with, or null."
},
"source_url": {
"type": [
"string",
"null"
],
"description": "Tracked web-page URL for webpage items; null otherwise."
},
"updated_at": {
"type": [
"integer",
"null"
],
"description": "Unix timestamp of last update."
},
"word_count": {
"type": "integer"
},
"content_type": {
"type": "string",
"description": "One of manual, webpage, canvas, deliverable, integration_data, call_transcript, file."
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "Collection this item lives in, or null."
},
"content_intro": {
"type": "string",
"description": "Short truncation of the content for previews."
},
"relevance_score": {
"type": [
"number",
"null"
],
"description": "Semantic relevance to `search` (max cosine similarity across the item's chunks; higher = more relevant). ONLY present when `search` was supplied: a number means the item was scored against embedded chunks; null means it isn't embedded yet and couldn't be scored (sorted last). Absent entirely when no `search` was given. Cross-comparable with list_content relevance_score."
},
"relevancy_processed_status": {
"enum": [
"unprocessed",
"provisional",
"complete"
],
"type": "string",
"description": "Targeting-dimension processing state, for reference-library items only. Omitted entirely for items that belong to a project or a context collection. This does NOT indicate whether the item is embedded or retrievable — every context item is embedded for semantic search at ingestion regardless of this value."
}
}
}
}
}
}get_context_item
Fetch the full markdown content and metadata of a single context item by ID. Use it when you need an item's actual content, since list_context_items returns only a short preview.
Input Schema
{
"type": "object",
"required": [
"context_item_id"
],
"properties": {
"context_item_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the reference item whose full markdown body and metadata you want. Get it from list_context_items, get_project(...).context_items, or the context_item_ids that get_relevant_context returns for matched passages. Items outside your team, items in private collections you did not create, and items in private projects you are not a member of all come back as not-found."
}
}
}Output Schema
{
"type": "object",
"required": [
"id",
"name",
"content",
"link_url"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Context item ID."
},
"name": {
"type": "string",
"description": "Context item name."
},
"content": {
"type": "string",
"description": "Full markdown content of the context item."
},
"added_by": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"description": "{id: integer, name: string} — the user who added the item."
},
"link_url": {
"type": "string",
"description": "URL to view this context item in the Marcora web app."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Project this item is associated with, or null."
},
"source_url": {
"type": [
"string",
"null"
],
"description": "Tracked web-page URL for webpage items; null otherwise."
},
"updated_at": {
"type": [
"integer",
"null"
],
"description": "Unix timestamp of last update."
},
"word_count": {
"type": "integer",
"description": "Word count of the content."
},
"content_type": {
"type": "string",
"description": "One of manual, webpage, canvas, deliverable, integration_data, call_transcript, file."
},
"collection_id": {
"type": [
"integer",
"null"
],
"description": "Collection this item lives in, or null."
},
"content_intro": {
"type": "string",
"description": "Short truncation used in listings."
},
"relevancy_processed_status": {
"enum": [
"unprocessed",
"provisional",
"complete"
],
"type": "string",
"description": "Targeting-dimension processing state, for reference-library items only. Omitted entirely for items that belong to a project or a context collection. This does NOT indicate whether the item is embedded or retrievable — every context item is embedded for semantic search at ingestion regardless of this value."
}
}
}Blueprints
list_blueprints
List all blueprints in your team's library, each with its content category. Use a blueprint's UUID with create_content to generate content from that template.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"blueprints"
],
"properties": {
"blueprints": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Blueprint name."
},
"web_url": {
"type": "string",
"description": "Direct URL to view this blueprint in Marcora."
},
"category": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"description": "Content category this blueprint belongs to: { id, name }. id matches list_content_categories."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp (ms) of creation."
},
"content_count": {
"type": "integer",
"description": "Number of content items generated from this blueprint."
},
"blueprint_uuid": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — pass as blueprint_uuid to create_content."
},
"team_visibility": {
"type": "string",
"description": "Visibility within your team (e.g. team, private)."
},
"input_instructions": {
"type": "string",
"description": "Guidance on what context to provide when generating from this blueprint."
},
"exchange_visibility": {
"type": "string",
"description": "Community exchange visibility (e.g. public, none)."
}
}
}
}
}
}get_blueprint
Retrieve the full details of a specific blueprint by its UUID, including its content, AI-generated analysis, and metadata. Find blueprint UUIDs with list_blueprints.
Input Schema
{
"type": "object",
"required": [
"blueprint_uuid"
],
"properties": {
"blueprint_uuid": {
"type": "string",
"format": "uuid",
"description": "The blueprint's UUID, exactly as returned in the `blueprint_uuid` field of list_blueprints (or by create_blueprint / finalize_blueprint_draft). It is not the community-library id and not a name. The blueprint must belong to your current team or have been created by you, and blueprints marked private are only readable by their creator."
}
}
}Output Schema
{
"type": "object",
"required": [
"blueprint_uuid",
"name"
],
"properties": {
"name": {
"type": "string"
},
"summary": {
"type": "string"
},
"web_url": {
"type": "string"
},
"category": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"created_at": {
"type": "integer"
},
"blueprint_dna": {
"type": "string"
},
"blueprint_uuid": {
"type": "string",
"format": "uuid"
},
"source_content": {
"type": "string"
},
"team_visibility": {
"type": "string"
},
"reference_content": {
"type": "string"
},
"input_instructions": {
"type": "string"
},
"exchange_visibility": {
"type": "string"
}
}
}create_blueprint
Create a reusable blueprint template from finished example content for generating content at scale. The AI analyzes your example and produces the supporting template fields. Use create_blueprint_draft instead if you want to iterate on the template with AI before publishing.
Input Schema
{
"type": "object",
"required": [
"name",
"category_id",
"source_content"
],
"properties": {
"name": {
"type": "string",
"description": "Name for the new blueprint (e.g. \"Customer Case Study Template\")."
},
"category_id": {
"type": "integer",
"description": "Content category id. Get valid IDs from list_content_categories."
},
"source_content": {
"type": "string",
"description": "Markdown template content. The AI analyzes this to derive structure, tone, and the polished reference_content. Use clear section headers and example text representative of what generated content should look like."
}
}
}Output Schema
{
"type": "object",
"required": [
"blueprint_uuid",
"name",
"link_url"
],
"properties": {
"name": {
"type": "string",
"description": "Blueprint name."
},
"summary": {
"type": "string",
"description": "AI-generated summary of what this blueprint produces."
},
"category": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Category ID."
},
"name": {
"type": "string",
"description": "Category name."
}
},
"description": "Content category this blueprint belongs to."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct link to view this blueprint in Marcora."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"blueprint_dna": {
"type": "string",
"description": "AI-generated analysis of the template structure, tone, and section descriptions."
},
"blueprint_uuid": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — use as blueprint_uuid in create_content."
},
"source_content": {
"type": "string",
"description": "The original template content you provided."
},
"team_visibility": {
"type": "string",
"description": "Visibility within your team (e.g. team, private)."
},
"reference_content": {
"type": "string",
"description": "AI-polished reference version of the template content."
},
"input_instructions": {
"type": "string",
"description": "AI-generated guidance for users on what context to provide when generating from this blueprint."
}
}
}create_blueprint_draft
Create an AI-assisted blueprint draft from a prompt that the user can review and edit in Marcora before publishing. Use create_blueprint instead if you already have the finished template content.
Input Schema
{
"type": "object",
"required": [
"instructions",
"name",
"content"
],
"properties": {
"name": {
"type": "string",
"description": "Display name for the draft (visible in the user's app)."
},
"content": {
"type": "string",
"description": "Initial markdown content the AI will iterate on. Can be empty to let the AI generate from instructions alone."
},
"category_id": {
"type": "integer",
"description": "Optional content category id from list_content_categories."
},
"instructions": {
"type": "string",
"description": "Prompt describing the blueprint to create (e.g. \"A weekly product update email with sections for new features, fixes, and a tip of the week\")."
}
}
}Output Schema
{
"type": "object",
"required": [
"id",
"uuid",
"title",
"content",
"link_url"
],
"properties": {
"id": {
"type": "integer",
"description": "Record ID for the blueprint draft."
},
"uuid": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for this draft. Pass as draft_uuid to finalize_blueprint_draft."
},
"title": {
"type": "string",
"description": "Blueprint draft name."
},
"content": {
"type": "string",
"description": "AI-generated blueprint template content in markdown."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/edit this blueprint draft in Marcora."
}
}
}finalize_blueprint_draft
Publish a previously created blueprint draft into a full, usable blueprint. This is the final step after the user reviews the draft produced by create_blueprint_draft.
Input Schema
{
"type": "object",
"required": [
"draft_uuid"
],
"properties": {
"name": {
"type": "string",
"description": "Optional name override. If not provided, uses the draft's existing title."
},
"draft_uuid": {
"type": "string",
"format": "uuid",
"description": "The UUID of the blueprint draft to finalize (returned as 'uuid' from create_blueprint_draft)."
},
"category_id": {
"type": "integer",
"description": "Optional category ID override. If not provided, uses the draft's existing category. Get valid IDs from list_content_categories."
}
}
}Output Schema
{
"type": "object",
"required": [
"blueprint_uuid",
"name",
"link_url"
],
"properties": {
"name": {
"type": "string",
"description": "Blueprint name."
},
"summary": {
"type": "string",
"description": "AI-generated summary of what this blueprint produces."
},
"category": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Category ID."
},
"name": {
"type": "string",
"description": "Category name."
}
},
"description": "Content category this blueprint belongs to."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/edit this blueprint in Marcora."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"blueprint_dna": {
"type": "string",
"description": "AI-generated analysis of the template structure, tone, and section descriptions."
},
"blueprint_uuid": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — use as blueprint_uuid in create_content."
},
"source_content": {
"type": "string",
"description": "The template content from the finalized draft."
},
"team_visibility": {
"type": "string",
"description": "Visibility within your team (e.g. team, private)."
},
"reference_content": {
"type": "string",
"description": "AI-polished reference version of the template content."
},
"input_instructions": {
"type": "string",
"description": "AI-generated guidance for users on what context to provide when generating from this blueprint."
}
}
}list_community_blueprints
Browse community blueprints shared by other Marcora users, with name, summary, contributor, and category. Use a blueprint's ID to view its full details before importing.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"community_blueprints"
],
"properties": {
"community_blueprints": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name",
"summary"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Blueprint exchange ID. Pass to get_community_blueprint_details or import_community_blueprint."
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
},
"summary": {
"type": "string"
},
"category": {
"type": "string"
},
"visibility": {
"type": "string"
},
"is_featured": {
"type": "boolean"
},
"category_short": {
"type": "string"
},
"contributor_name": {
"type": "string"
},
"input_instructions": {
"type": "string"
},
"contributor_company": {
"type": "string"
}
}
}
}
}
}get_community_blueprint_details
Get the full details of a community blueprint, including its example content and style guide. Use the ID from list_community_blueprints, and pass it to import_community_blueprint to add the blueprint to your team.
Input Schema
{
"type": "object",
"required": [
"blueprint_exchange_id"
],
"properties": {
"blueprint_exchange_id": {
"type": "string",
"format": "uuid",
"description": "The UUID from the `id` field of a list_community_blueprints result — the identifier of an entry in the shared community blueprint library. The `slug` returned alongside it will not resolve; use `id`. Entries that have been retired from the library return a not-found error. Pass the same value to import_community_blueprint to copy the blueprint into your team."
}
}
}Output Schema
{
"type": "object",
"required": [
"id",
"name",
"content"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Blueprint exchange ID. Pass to import_community_blueprint."
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
},
"content": {
"type": "string",
"description": "Full example document content in markdown"
},
"summary": {
"type": "string"
},
"visibility": {
"type": "string"
},
"is_featured": {
"type": "boolean"
},
"contributor_name": {
"type": "string"
},
"input_instructions": {
"type": "string"
},
"content_description": {
"type": "string",
"description": "Template structure and style guidelines"
},
"contributor_company": {
"type": "string"
},
"contributor_job_title": {
"type": "string"
},
"suggested_content_type": {
"type": "string"
}
}
}import_community_blueprint
Import a blueprint from the Marcora community exchange into your team's library. Once imported, use it like any of your own blueprints to generate content.
Input Schema
{
"type": "object",
"required": [
"blueprint_exchange_id"
],
"properties": {
"blueprint_exchange_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the community blueprint to import. Get from list_community_blueprints (the blueprint_exchange_id field on each item)."
},
"_frontend_realtime_key": {
"type": "string",
"description": "For frontend progress updates only. Do not use from MCP clients."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Blueprint record ID"
},
"name": {
"type": "string"
},
"uuid": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — use as blueprint_uuid in create_deliverable_from_blueprint"
},
"content": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"team_visibility": {
"type": "string"
},
"imported_exchange_id": {
"type": "string",
"format": "uuid"
}
}
}Reference
list_content_categories
List the content categories available to your team, such as GTM Messaging or Website & Blog. Use a category's ID when creating blueprints or content.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"categories"
],
"properties": {
"categories": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Category ID. Pass to create_blueprint or create_blueprint_draft as category_id."
},
"name": {
"type": "string",
"description": "Category name (e.g. GTM Messaging)"
}
}
}
}
}
}list_targeting_dimensions
List the team's targeting dimensions and their options, such as Buying Stage or Persona. Pass the option IDs to create_content to target generated content at specific audiences or stages.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"dimensions"
],
"properties": {
"dimensions": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name",
"options"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"description": "Dimension name (e.g. Buying Stage, Persona)"
},
"options": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Pass in dimension_option_ids when creating content."
},
"name": {
"type": "string",
"description": "Option name (e.g. Awareness, Decision)"
}
}
}
}
}
}
}
}
}Sharing
create_external_share
Create a public share link for a content document, optionally with an expiration date. Anyone with the link can view it without a Marcora account, and it won't be indexed by search engines.
Input Schema
{
"type": "object",
"required": [
"content_id"
],
"properties": {
"content_id": {
"type": "string",
"format": "uuid",
"description": "The ID of the content you wish to share"
},
"expires_at": {
"type": "integer",
"description": "Optional expiry for the share link, as a Unix timestamp in MILLISECONDS (e.g. Date.now() + 7 days). It is compared directly against the current time in milliseconds, so a seconds-based timestamp will make the link appear already expired. Omit it — or pass anything that is not a number, which is ignored — to create a link that never expires."
}
}
}Output Schema
{
"type": "object",
"required": [
"share_link"
],
"properties": {
"share_link": {
"type": "string",
"description": "Public URL (https://app.marcora.ai/s/<token>) anyone can use to view the content."
}
}
}convert_markdown_to_word_doc
Export markdown content as a downloadable Word (.docx) file. Useful when the user needs a Microsoft Word or Google Docs–compatible version of a document.
Input Schema
{
"type": "object",
"required": [
"markdown_content"
],
"properties": {
"filename": {
"type": "string",
"description": "Base name for the generated file, without an extension — the service appends \".docx\" (any \".docx\" you include is stripped). Defaults to \"document\" when omitted, so set it whenever you want a recognisable name, such as the document's title."
},
"document_url": {
"type": "string",
"description": "Optional link back to the original document in Marcora. When supplied, a footer is appended to the end of the Word file reading \"View / Edit in Marcora\" and linking to this URL. Use it when the recipient may want to open or edit the live version; omit it for a standalone export."
},
"markdown_content": {
"type": "string",
"description": "The full markdown body to convert into the Word file. Required. Pass the document text you got back from get_content (or that you just wrote); headings, lists, tables and emphasis are carried into the .docx, and nothing else is fetched for you."
}
}
}Output Schema
{
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "Filename of the generated Word document"
},
"download_url": {
"type": "string",
"description": "URL to download the generated .docx Word document"
}
}
}Projects
list_projects
List all projects visible to you. Projects organize content into workstreams; use a project's ID to fetch its details or to associate new content with it.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"required": [
"projects"
],
"properties": {
"projects": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name",
"link_url"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Project ID. Pass to get_project or use when creating content."
},
"name": {
"type": "string",
"description": "Project name."
},
"status": {
"type": "string",
"description": "Project status (e.g. active, archived)."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view this project in the Marcora app."
},
"created_by": {
"type": "string",
"description": "Name of the project creator."
},
"visibility": {
"type": "string",
"description": "Visibility (e.g. team, private)."
},
"member_count": {
"type": "integer",
"description": "Number of project members."
},
"content_count": {
"type": "integer",
"description": "Number of content items in this project."
}
}
}
}
}
}get_project
Get the details of a specific project, including its members, documents, context items, and brief. Find project IDs with list_projects.
Input Schema
{
"type": "object",
"required": [
"project_id"
],
"properties": {
"project_id": {
"type": "string",
"format": "uuid",
"description": "The project's UUID, exactly as returned in the `project_id` field of list_projects or create_project. A numeric id or a project name will not resolve. You must be a member of the project's team, and if the project is private you must also be one of its members, or the call is rejected."
}
}
}Output Schema
{
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Project ID."
},
"name": {
"type": "string",
"description": "Project name."
},
"status": {
"type": "string",
"description": "Project status."
},
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"role": {
"type": "string"
},
"email": {
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"description": "Project members."
},
"documents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"stage": {
"type": "string"
},
"purpose": {
"type": "string",
"description": "Role of content in project (e.g. supporting)."
},
"web_url": {
"type": "string"
},
"category": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"is_ready": {
"type": "boolean",
"description": "Whether generation is complete."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Content UUID — pass to get_content or update_content."
},
"visibility": {
"type": "string"
},
"in_project_context": {
"type": "boolean",
"description": "Whether included in project context for AI generation."
}
}
},
"description": "Documents in this project."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"visibility": {
"type": "string",
"description": "Visibility setting."
},
"context_items": {
"type": "array",
"description": "Context items associated with this project."
},
"project_brief": {
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
},
"content_id": {
"type": "string",
"format": "uuid"
}
},
"description": "The project's pinned brief document, if set. {name, content_id} — same shape as create_project's project_brief field. Pass content_id to update_content / get_content to edit or read the brief. null if the project has no brief set."
}
}
}create_project
Create a new project to organize content and context into a workstream, optionally with a brief supplied directly or generated by AI. Use the returned project ID to associate new content with the project.
Input Schema
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The project's display name, shown in the project list and used to label it everywhere. Required and must be non-empty (surrounding whitespace is trimmed); there is no length limit. If you also pass project_brief_instructions, this name is inserted into the AI prompt used to write the brief, so a descriptive name produces a better brief."
},
"visibility": {
"enum": [
"team",
"private"
],
"type": "string",
"description": "Who on the team can see the project. \"team\" (the default when omitted) makes it visible to team admins and editors as well as anyone added to the project; \"private\" limits it to people explicitly added as project members — the creator is added automatically. Set \"private\" only when the work should not be browsable by the wider team; these are the only two accepted values."
},
"project_brief_content": {
"type": "string",
"description": "Finished brief text to save DIRECTLY as the project brief (no AI, no Studio Credits). Takes precedence over project_brief_instructions."
},
"project_brief_instructions": {
"type": "string",
"description": "Prompt describing the brief to AUTO-GENERATE with AI (uses Studio Credits). Mutually exclusive with project_brief_content, which takes precedence."
}
}
}Output Schema
{
"type": "object",
"required": [
"project_id",
"name",
"link_url"
],
"properties": {
"name": {
"type": "string",
"description": "Project name."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/open this project in Marcora."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Project identifier."
},
"project_brief": {
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string",
"description": "Brief document name."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Content UUID of the brief."
}
},
"description": "Present (non-null) only when `project_brief_content` or `project_brief_instructions` was supplied. Pass `content_id` to update_content / get_content later."
}
}
}update_project
Update mutable fields on an existing project, such as its name, visibility, status, or brief. Uses PATCH semantics, so only the fields you pass change.
Input Schema
{
"type": "object",
"required": [
"project_id"
],
"properties": {
"name": {
"type": "string",
"description": "New project name. Must be non-empty when provided. Omit to leave unchanged."
},
"status": {
"enum": [
"active",
"archived"
],
"type": "string",
"description": "New project status. \"active\" for ongoing work; \"archived\" to hide from the active list while preserving content. Setting to \"active\" requires available active-project usage. Omit to leave unchanged."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the project to update. Get from list_projects or get_project."
},
"visibility": {
"enum": [
"team",
"private"
],
"type": "string",
"description": "New visibility setting. \"team\" makes it visible to all team members; \"private\" restricts to the creator and explicit project members. Omit to leave unchanged."
},
"project_brief_id": {
"type": "string",
"format": "uuid",
"description": "UUID of an existing content item to set as this project's brief. If the content isn't already attached to the project, this tool will attach it AND set it as the brief in one call."
}
}
}Output Schema
{
"type": "object",
"required": [
"success",
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable status message."
},
"project": {
"type": [
"object",
"null"
],
"description": "The updated project record."
},
"success": {
"type": "boolean",
"description": "True if the update applied successfully."
}
}
}Plans & Playbooks
list_plans
List plans visible to the authenticated user with filters and pagination.
Input Schema
{
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "Page number (default 1)."
},
"sort": {
"type": "string",
"description": "Sort order: \"due_asc_nulls_last\" (default — best for action planning) | \"created_desc\" (newest first)."
},
"stage": {
"type": "array",
"items": {
"type": "string"
},
"description": "Array of stage enum values. Use UNDERSCORE form In_Process. Allowed: Suggested, Accepted, In_Process, Complete, Dismissed. Omit for all stages. Note: only the first array element is honored currently — pass single-value arrays to be safe."
},
"source": {
"type": "array",
"items": {
"type": "string"
},
"description": "Array of source enum values: user_added, cora_proactive, cora_requested, workflow, playbook. Note: only the first array element is honored currently — pass single-value arrays to be safe."
},
"per_page": {
"type": "integer",
"description": "Items per page (default 20, max 100)."
},
"due_after": {
"type": "string",
"description": "ISO date YYYY-MM-DD. Returns plans with due_date >= due_after. Note: does not apply yet."
},
"due_before": {
"type": "string",
"description": "ISO date YYYY-MM-DD. Returns plans with due_date <= due_before. Note: does not apply yet."
},
"project_id": {
"type": "string",
"description": "Filter to plans associated with this project (project UUID string)."
},
"category_id": {
"type": "integer",
"description": "Filter to plans in this content category (integer ID). Omit (or pass 0/null) for NO category filter — all plans return, including uncategorized ones."
},
"search_text": {
"type": "string",
"description": "Substring match on plan title (case-insensitive). Note: does not apply yet."
},
"assignee_scope": {
"type": "string",
"description": "Whose plans to return. \"me\" (default — plans assigned to you) | \"created_by_me\" (plans you created) | \"all_visible\" (all plans visible to your team)."
}
}
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stage": {
"type": "string"
},
"title": {
"type": "string"
},
"source": {
"type": "string"
},
"due_date": {
"type": [
"string",
"null"
]
},
"link_url": {
"type": "string",
"format": "uri"
},
"plan_uuid": {
"type": "string",
"format": "uuid"
},
"created_at": {
"type": "integer"
},
"created_by": {
"type": "integer"
},
"updated_at": {
"type": "integer"
},
"assigned_to": {
"type": "integer"
},
"produced_content_id": {
"type": [
"string",
"null"
]
}
}
},
"description": "Array of plan summary objects. Each item: plan_uuid, link_url (shareable deep-link opening this plan's overlay), title, stage, source, assigned_to, created_by, due_date, produced_content_id, created_at, updated_at."
},
"curPage": {
"type": "integer"
},
"nextPage": {
"type": [
"integer",
"null"
]
},
"prevPage": {
"type": [
"integer",
"null"
]
},
"itemsTotal": {
"type": "integer"
}
},
"description": "Paginated plan summary results."
}get_plan
Fetch a single plan by UUID with linked references, context collections, targeting dimensions, and metadata.
Input Schema
{
"type": "object",
"required": [
"plan_uuid"
],
"properties": {
"plan_uuid": {
"type": "string",
"description": "The UUID of the plan to fetch (use plan_uuid, not the integer id)."
}
}
}Output Schema
{
"type": "object",
"required": [
"plan"
],
"properties": {
"plan": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Internal PK; do not use externally."
},
"stage": {
"enum": [
"Suggested",
"Accepted",
"In_Process",
"Complete",
"Dismissed"
],
"type": "string"
},
"title": {
"type": "string"
},
"prompt": {
"type": [
"string",
"null"
]
},
"source": {
"enum": [
"user_added",
"cora_proactive",
"cora_requested",
"workflow",
"playbook"
],
"type": "string"
},
"team_id": {
"type": "integer"
},
"due_date": {
"type": [
"string",
"null"
]
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Shareable deep-link that opens the plans screen with this plan's detail overlay. Give this to the user."
},
"plan_uuid": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"created_by": {
"type": "integer"
},
"project_id": {
"type": [
"string",
"null"
]
},
"updated_at": {
"type": "integer"
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"assigned_to": {
"type": "integer"
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"blueprint_id": {
"type": [
"string",
"null"
]
},
"completed_at": {
"type": [
"integer",
"null"
]
},
"dismissed_at": {
"type": [
"integer",
"null"
]
},
"source_metadata": {
"type": [
"object",
"null"
]
},
"_produced_content": {
"type": [
"object",
"null"
],
"description": "The linked content object or null. When non-null contains at minimum: content_id, name, stage, visibility."
},
"context_collections": {
"type": "array"
},
"produced_content_id": {
"type": [
"string",
"null"
]
},
"reference_documents": {
"type": "array",
"description": "Content UUIDs accessible to the current user."
},
"targeting_dimensions": {
"type": "array"
},
"_source_metadata_resolved": {
"type": [
"object",
"null"
],
"description": "Denormalized tooltip data (workflow_name resolved fresh; the cora_session_id / cora_message_snippet passthrough). Null if source=user_added."
}
}
}
}
}create_plan
Create a new plan in the authenticated user's active team.
Input Schema
{
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Required. The one-line summary of the content intent (1-200 chars)."
},
"prompt": {
"type": "string",
"description": "The actual content prompt — pre-populates the content creation form when the plan is acted on."
},
"source": {
"type": "string",
"description": "Plan source. Default cora_requested for Marcora interactive callers. The cora_* values are legacy wire names that predate the Marcora rename and are unchanged — send them exactly as written. Allowed: user_added, cora_proactive, cora_requested, workflow, playbook. Immutable after creation."
},
"due_date": {
"type": "string",
"description": "Optional target completion date. ISO 8601 date string YYYY-MM-DD."
},
"plan_uuid": {
"type": "string",
"description": "Optional client-supplied UUIDv4 for optimistic creates. Server validates format + uniqueness. Server generates if omitted."
},
"project_id": {
"type": "string",
"description": "Project UUID string to associate with this plan."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "Optional. Defaults to \"private\" (creator-only ideas queue). \"team\" makes the plan visible to all active teammates. Assigning to someone other than the calling user auto-promotes to \"team\"."
},
"assigned_to": {
"type": "integer",
"description": "Optional integer user ID to assign this plan to. Defaults to creator. Must be a current team member."
},
"category_id": {
"type": "integer",
"description": "Content category integer ID."
},
"description": {
"type": "string",
"description": "Optional free-text description of what this plan is for."
},
"blueprint_id": {
"type": "string",
"description": "Blueprint UUID (from list_blueprints) or integer blueprint id. UUIDs are resolved server-side; unknown UUIDs return InputError."
},
"source_metadata": {
"description": "Optional. Shape varies by source: {cora_session_id, cora_message_snippet} for cora_proactive; {workflow_template_id, workflow_run_id, workflow_name, run_timestamp} for workflow. Immutable after creation."
},
"context_collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Array of integer collection IDs to pre-attach."
},
"reference_document_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Array of content UUID strings to associate as reference material."
},
"targeting_dimension_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Array of integer dimension option IDs to pre-attach."
}
}
}Output Schema
{
"type": "object",
"required": [
"plan_uuid",
"id",
"team_id",
"created_by",
"assigned_to",
"stage",
"source",
"title",
"created_at",
"updated_at",
"link_url"
],
"properties": {
"id": {
"type": "integer",
"description": "Internal integer PK; not exposed externally."
},
"stage": {
"enum": [
"Suggested",
"Accepted",
"In_Process",
"Complete",
"Dismissed"
],
"type": "string"
},
"title": {
"type": "string"
},
"prompt": {
"type": [
"string",
"null"
]
},
"source": {
"type": "string"
},
"team_id": {
"type": "integer"
},
"due_date": {
"type": [
"string",
"null"
]
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Shareable deep-link that opens the plans screen with this plan's detail overlay. Give this to the user."
},
"plan_uuid": {
"type": "string",
"description": "UUIDv4 — the external-facing identifier. Use this for all subsequent calls."
},
"created_at": {
"type": "integer"
},
"created_by": {
"type": "integer"
},
"project_id": {
"type": [
"string",
"null"
]
},
"updated_at": {
"type": "integer"
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"assigned_to": {
"type": "integer"
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"blueprint_id": {
"type": [
"string",
"null"
]
},
"completed_at": {
"type": [
"integer",
"null"
]
},
"dismissed_at": {
"type": [
"integer",
"null"
]
},
"source_metadata": {
"type": [
"object",
"null"
]
},
"context_collections": {
"type": "array"
},
"produced_content_id": {
"type": [
"string",
"null"
]
},
"reference_documents": {
"type": "array"
},
"targeting_dimensions": {
"type": "array"
}
},
"description": "Full plan object."
}update_plan
Partial update of a plan: mutable fields and stage transitions.
Input Schema
{
"type": "object",
"required": [
"plan_uuid"
],
"properties": {
"title": {
"type": "string",
"description": "Update plan title (1-200 chars)."
},
"prompt": {
"type": "string",
"description": "Update the content prompt."
},
"due_date": {
"type": "string",
"description": "Update due date (ISO YYYY-MM-DD). null is currently IGNORED (no-op); clearing ships with the null-accept backend change."
},
"plan_uuid": {
"type": "string",
"description": "Required. UUID of the plan to update."
},
"project_id": {
"type": "string",
"description": "Update project association. null is currently IGNORED (no-op); clearing ships with the null-accept backend change."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "Change the plan's visibility. Creator-only — non-creators get InputError."
},
"assigned_to": {
"type": "integer",
"description": "Reassign to a different team member (integer user ID). Must be a current team member. Assigning a private plan to anyone other than the calling user auto-promotes it to team visibility."
},
"category_id": {
"type": "integer",
"description": "Update category association. null is currently IGNORED (no-op); clearing ships with the null-accept backend change."
},
"description": {
"type": "string",
"description": "Update plan description."
},
"blueprint_id": {
"type": "string",
"description": "Update blueprint association — accepts a blueprint UUID (from list_blueprints) or integer id. null is currently IGNORED (no-op); clearing ships with the null-accept backend change."
},
"target_stage": {
"type": "string",
"description": "Request a stage transition. Use UNDERSCORE form In_Process. Validated against the allowed-transition map; disallowed transitions return InputError. Allowed: Suggested, Accepted, In_Process, Complete, Dismissed."
},
"context_collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "REPLACES full set of context collection associations. Pass [] to clear all."
},
"reference_document_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "REPLACES full set of reference doc associations. Pass [] to clear all."
},
"targeting_dimension_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "REPLACES full set of targeting dimension associations. Pass [] to clear all."
}
}
}Output Schema
{
"type": "object",
"required": [
"plan_uuid",
"stage",
"updated_at",
"link_url"
],
"properties": {
"id": {
"type": "integer"
},
"stage": {
"enum": [
"Suggested",
"Accepted",
"In_Process",
"Complete",
"Dismissed"
],
"type": "string"
},
"title": {
"type": "string"
},
"prompt": {
"type": [
"string",
"null"
]
},
"source": {
"type": "string"
},
"team_id": {
"type": "integer"
},
"due_date": {
"type": [
"string",
"null"
]
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Shareable deep-link that opens the plans screen with this plan's detail overlay. Give this to the user."
},
"plan_uuid": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"created_by": {
"type": "integer"
},
"project_id": {
"type": [
"string",
"null"
]
},
"updated_at": {
"type": "integer"
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"assigned_to": {
"type": "integer"
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"blueprint_id": {
"type": [
"string",
"null"
]
},
"completed_at": {
"type": [
"integer",
"null"
]
},
"dismissed_at": {
"type": [
"integer",
"null"
]
},
"source_metadata": {
"type": [
"object",
"null"
]
},
"context_collections": {
"type": "array"
},
"produced_content_id": {
"type": [
"string",
"null"
]
},
"reference_documents": {
"type": "array"
},
"targeting_dimensions": {
"type": "array"
}
},
"description": "Updated plan object with all fields."
}produce_plan
Produce (generate) the actual content a plan describes — the MCP equivalent of the Generate button on the plans board.
Input Schema
{
"type": "object",
"required": [
"plan_uuid"
],
"properties": {
"plan_uuid": {
"type": "string",
"description": "Required. UUID of the Accepted plan to produce (from list_plans / get_plan / create_plan)."
}
}
}Output Schema
{
"type": "object",
"required": [
"path",
"stage",
"message",
"link_url"
],
"properties": {
"path": {
"enum": [
"blueprint",
"freeform"
],
"type": "string",
"description": "Which produce path ran: blueprint (generated from a blueprint) or freeform (no blueprint). Both are async."
},
"stage": {
"type": "string",
"description": "The plan's stage as of this response: Accepted on both paths — flips to In_Process when generation completes."
},
"message": {
"type": "string",
"description": "What happened + what to do next."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Shareable deep-link that opens the plans screen with this plan's detail overlay. Give this to the user."
},
"generation_id": {
"type": "string",
"description": "Both paths — poll get_generation_status with this id."
}
}
}list_playbooks
List all content playbooks visible to the caller in the current team. Returns summaries only — call get_playbook for a playbook's items.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"team_id": {
"type": "integer"
},
"link_url": {
"type": "string",
"description": "URL to open this playbook in the Marcora web app."
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"created_by": {
"type": "integer"
},
"item_count": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Persisted YYYY-MM-DD anchor date, or null."
},
"description": {
"type": [
"string",
"null"
]
}
}
}
},
"itemsTotal": {
"type": "integer"
}
}
}get_playbook
Fetch one content playbook by id, including its full ordered list of items.
Input Schema
{
"type": "object",
"required": [
"playbook_id"
],
"properties": {
"playbook_id": {
"type": "integer",
"description": "Numeric id of the playbook to fetch — the `id` returned by list_playbooks, create_playbook or a previous get_playbook, and the trailing number in the playbook's link_url. It is a plain integer, not a UUID; a non-integer value is rejected. Only playbooks in your current team are reachable, and an unknown id, another team's playbook, or a teammate's private playbook all come back as NotFound."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"title": {
"type": "string",
"description": "Mirror of name."
},
"prompt": {
"type": [
"string",
"null"
]
},
"team_id": {
"type": "integer"
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"sort_order": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"offset_days": {
"type": [
"integer",
"null"
]
},
"playbook_id": {
"type": "integer"
},
"blueprint_id": {
"type": [
"integer",
"null"
]
}
}
},
"description": "Ordered playbook items."
},
"team_id": {
"type": "integer"
},
"link_url": {
"type": "string",
"description": "URL to open this playbook in the Marcora web app — share it so the user can view what you created."
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"created_by": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Persisted YYYY-MM-DD anchor date, or null. Each item's offset_days counts from it; it's the default when instantiating."
},
"description": {
"type": [
"string",
"null"
]
}
}
}create_playbook
Create a reusable content playbook — an ordered template of content-plan items you can stamp out as a batch.
Input Schema
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The playbook's title, shown wherever someone browses or picks a playbook to run. Required and trimmed — a blank or whitespace-only value is rejected. It is also the base of the auto-generated cycle name every time the playbook is run (\"<name> — Mon YYYY\")."
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Item name (title of the plan this item becomes). Alias: `title`."
},
"title": {
"type": "string",
"description": "Alias for `name`."
},
"prompt": {
"type": "string",
"description": "Generation prompt carried onto the plan created from this item."
},
"sort_order": {
"type": "integer",
"description": "Explicit order; defaults to array position."
},
"category_id": {
"type": "integer",
"description": "Content category for the plan (optional)."
},
"description": {
"type": "string"
},
"offset_days": {
"type": [
"integer",
"null"
],
"description": "Days relative to anchor_date at instantiation; sets the plan due_date. Negative = before the anchor. null or omitted = no due date (\"No date\"). Items are a full-replacement set on update, so pass null (or omit) here to CLEAR a previously scheduled item."
},
"blueprint_id": {
"type": "integer",
"description": "Blueprint to attach to the plan (optional)."
}
}
},
"description": "The ordered steps of the playbook — each entry becomes exactly one content plan when the playbook is run. Every entry needs a `name` (`title` is accepted as an alias) and may also carry description, prompt, blueprint_id, category_id, offset_days and sort_order; array order sets the sequence unless sort_order is given. Optional — omit it to save an empty shell you fill in later, but a playbook with no items cannot be run until you add some."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "Optional. Defaults to \"team\". \"private\" keeps the playbook creator-only."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Optional YYYY-MM-DD anchor date this playbook is built around (e.g. a launch date). Each item's offset_days counts from it, and it becomes the default anchor when instantiating. Offer to set this when the user has a specific date in mind; omit or null for an evergreen/undated template."
},
"description": {
"type": "string",
"description": "Optional free-text note saying what this playbook is for and when to run it, for teammates browsing the playbook list. It is stored on the playbook only and is never fed into content generation; omit it and it is saved empty."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"title": {
"type": "string",
"description": "Mirror of name."
},
"prompt": {
"type": [
"string",
"null"
]
},
"team_id": {
"type": "integer"
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"sort_order": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"offset_days": {
"type": [
"integer",
"null"
]
},
"playbook_id": {
"type": "integer"
},
"blueprint_id": {
"type": [
"integer",
"null"
]
}
}
}
},
"team_id": {
"type": "integer"
},
"link_url": {
"type": "string",
"description": "URL to open this playbook in the Marcora web app — share it so the user can view what you created."
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"created_by": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Persisted YYYY-MM-DD anchor date, or null. Each item's offset_days counts from it; it's the default when instantiating."
},
"description": {
"type": [
"string",
"null"
]
}
},
"description": "The created playbook object, including its persisted anchor_date (YYYY-MM-DD or null) and a link_url that opens it in the Marcora web app."
}create_playbook_from_plans
Create a playbook by capturing existing content plans as reusable template items ("save what worked as a template").
Input Schema
{
"type": "object",
"required": [
"plan_ids"
],
"properties": {
"name": {
"type": "string",
"description": "Title for the new playbook being saved from these plans — usually the campaign or sequence they came from. Treat it as required: if it is omitted or blank the call fails with \"Missing param: name\". It also becomes the base of the auto-generated cycle name each time the playbook is later run."
},
"plan_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "UUIDs of existing content plans to capture as template items."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "Optional. Defaults to \"team\". \"private\" keeps the playbook creator-only."
},
"description": {
"type": "string",
"description": "Optional free-text note on what this captured sequence is for and when to reuse it, shown to teammates browsing playbooks. It describes the playbook only — the captured steps keep the titles, descriptions and prompts copied from the source plans. Omitted means it is saved empty."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"title": {
"type": "string",
"description": "Mirror of name."
},
"prompt": {
"type": [
"string",
"null"
]
},
"team_id": {
"type": "integer"
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"sort_order": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"offset_days": {
"type": [
"integer",
"null"
]
},
"playbook_id": {
"type": "integer"
},
"blueprint_id": {
"type": [
"integer",
"null"
]
}
}
}
},
"team_id": {
"type": "integer"
},
"link_url": {
"type": "string",
"description": "URL to open this playbook in the Marcora web app — share it so the user can view what you created."
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"created_by": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Persisted YYYY-MM-DD anchor date, or null. Each item's offset_days counts from it; it's the default when instantiating."
},
"description": {
"type": [
"string",
"null"
]
}
},
"description": "The created playbook object, including its anchor_date (null unless later set) and a link_url that opens it in the Marcora web app."
}update_playbook
Edit a content playbook. Pass only the fields to change; if items is provided it fully replaces the playbook's items and order.
Input Schema
{
"type": "object",
"required": [
"playbook_id"
],
"properties": {
"name": {
"type": "string",
"description": "Omit to keep the current name (it cannot be cleared — playbooks always have a name)."
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Item name (title of the plan this item becomes). Alias: `title`."
},
"title": {
"type": "string",
"description": "Alias for `name`."
},
"prompt": {
"type": "string",
"description": "Generation prompt carried onto the plan created from this item."
},
"sort_order": {
"type": "integer",
"description": "Explicit order; defaults to array position."
},
"category_id": {
"type": "integer",
"description": "Content category for the plan (optional)."
},
"description": {
"type": "string"
},
"offset_days": {
"type": [
"integer",
"null"
],
"description": "Days relative to anchor_date at instantiation; sets the plan due_date. Negative = before the anchor. null or omitted = no due date (\"No date\"). Items are a full-replacement set on update, so pass null (or omit) here to CLEAR a previously scheduled item."
},
"blueprint_id": {
"type": "integer",
"description": "Blueprint to attach to the plan (optional)."
}
}
},
"description": "Full replacement set of ordered items. Omit to keep existing items."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "Change the playbook's visibility. Creator-only — non-creators get InputError."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Optional YYYY-MM-DD anchor date the playbook is built around. Omit to KEEP the current value; pass null to CLEAR it. Each item's offset_days counts from it, and it's the default anchor when instantiating."
},
"description": {
"type": [
"string",
"null"
],
"description": "Omit to KEEP the current description; pass null to CLEAR it."
},
"playbook_id": {
"type": "integer",
"description": "Numeric id of the playbook to edit — the `id` from list_playbooks or get_playbook, or the trailing number in its link_url, not a UUID. It only selects which playbook to change and is never itself modified. Unknown ids, playbooks in another team, and teammates' private playbooks all return NotFound."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"title": {
"type": "string",
"description": "Mirror of name."
},
"prompt": {
"type": [
"string",
"null"
]
},
"team_id": {
"type": "integer"
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"sort_order": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"category_id": {
"type": [
"integer",
"null"
]
},
"description": {
"type": [
"string",
"null"
]
},
"offset_days": {
"type": [
"integer",
"null"
]
},
"playbook_id": {
"type": "integer"
},
"blueprint_id": {
"type": [
"integer",
"null"
]
}
}
}
},
"team_id": {
"type": "integer"
},
"link_url": {
"type": "string",
"description": "URL to open this playbook in the Marcora web app — share it so the user can view what you created."
},
"created_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"created_by": {
"type": "integer"
},
"updated_at": {
"type": "integer",
"description": "Unix ms timestamp."
},
"visibility": {
"enum": [
"private",
"team"
],
"type": "string",
"description": "private = creator-only; team = visible to all active teammates."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Persisted YYYY-MM-DD anchor date, or null. Each item's offset_days counts from it; it's the default when instantiating."
},
"description": {
"type": [
"string",
"null"
]
}
},
"description": "The updated playbook object, including its anchor_date (YYYY-MM-DD or null) and link_url."
}instantiate_playbook
Run a playbook: create one content plan per playbook item, in order, as a batch.
Input Schema
{
"type": "object",
"required": [
"playbook_id"
],
"properties": {
"project_id": {
"type": "string",
"format": "uuid",
"description": "Scope every created plan to this project (optional)."
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "The reference date every item's `offset_days` counts from: each plan's due_date = anchor_date + offset_days. Three distinct cases, so choose deliberately — OMIT the field to inherit the playbook's own saved anchor_date (due dates are only unset if the playbook has no saved anchor either); pass an explicit null (or empty string) to force NO anchor, which leaves every due date unset even when the playbook has a saved one; or pass a YYYY-MM-DD date to override with that date. Any other format is rejected. When the user names a date (\"anchored to next Monday\") send it explicitly; when they just say \"run my playbook\" omit the field so their saved anchor is honored."
},
"assigned_to": {
"type": "integer",
"description": "User id to assign the created plans to. Defaults to the caller."
},
"category_id": {
"type": "integer",
"description": "Override the content category for every created plan (optional)."
},
"playbook_id": {
"type": "integer",
"description": "Numeric id of the saved playbook to run — the `id` from list_playbooks or the trailing number in its link_url, not a UUID. If you only have the playbook's name, call list_playbooks first to resolve the id. The playbook must contain at least one item; running an empty playbook fails."
}
}
}Output Schema
{
"type": "object",
"properties": {
"run": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"description": "Auto-named \"<playbook> — <Mon YYYY>\" unless you passed a name."
},
"link_url": {
"type": "string",
"description": "https://app.marcora.ai/runs/{run_id}"
},
"anchor_date": {
"type": [
"string",
"null"
],
"description": "Persisted YYYY-MM-DD reference date, or null."
}
},
"description": "The created cycle: id, name (auto-named \"<playbook> — <Mon YYYY>\" unless you passed a name), anchor_date, and link_url (https://app.marcora.ai/runs/{run_id}) — share it to hand the user their new cycle."
},
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"link_url": {
"type": "string",
"description": "https://app.marcora.ai/plans/{plan_uuid}"
}
},
"description": "Full content-plan payload (same shape as create_plan / get_plan returns), each with its own link_url (https://app.marcora.ai/plans/{plan_uuid}). Stage = Accepted, source = \"playbook\"."
},
"description": "The created content plans (same shape as create_plan / get_plan), stage Accepted, source playbook."
},
"run_id": {
"type": "integer",
"description": "ID of the cycle (run) this instantiation created — the group its plans belong to."
},
"playbook_id": {
"type": "integer",
"description": "The instantiated playbook."
},
"created_count": {
"type": "integer",
"description": "Number of plans created (one per playbook item)."
}
},
"description": "An object describing the run."
}