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": "The poll key for get_generation_status. Jobs applied together in one run (fixes landing in the same document) share it."
},
"context_item_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Where the fix was written. null means the document itself."
}
}
},
"description": "One entry per finding that started. Jobs whose fixes land in the same document share a generation_id (one run applies them together); poll each distinct generation_id with get_generation_status."
},
"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."
},
"support_only_calls": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": {
"type": [
"string",
"null"
],
"description": "When the call happened (ISO 8601), or null."
},
"kind": {
"type": [
"string",
"null"
],
"description": "Kind of call, or null."
},
"company": {
"type": [
"string",
"null"
],
"description": "The other company on the call, or null."
}
}
},
"description": "Present only on a supported claim whose every supporting source is a call: the calls it rests on, one entry per call. Absent when any support is not a call, and absent for calls you cannot see. Tell the user such a claim rests only on calls, which are one conversation's word rather than a written source."
}
}
},
"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."
},
"support_only_calls": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": {
"type": [
"string",
"null"
],
"description": "When the call happened (ISO 8601), or null."
},
"kind": {
"type": [
"string",
"null"
],
"description": "Kind of call, or null."
},
"company": {
"type": [
"string",
"null"
],
"description": "The other company on the call, or null."
}
}
},
"description": "Present only on a supported claim whose every supporting source is a call: the calls it rests on, one entry per call. Absent when any support is not a call, and absent for calls you cannot see. Tell the user such a claim rests only on calls, which are one conversation's word rather than a written source."
}
}
},
"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. Choose how Marcora writes with `generation_mode`: Quick (one model) or Multi-model (two drafts and a synthesis).
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."
},
"ai_provider": {
"type": "string",
"description": "Quick only: which model family writes the document. The allowed values and the default are in the tool's input schema. Ignored with `multi_model`."
},
"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."
},
"generation_mode": {
"enum": [
"quick",
"multi_model"
],
"type": "string",
"description": "`quick` (one model) or `multi_model` (two drafts and a synthesis). When omitted, a call with a blueprint runs Multi-model and a call without one runs Quick. `instructions` paths only."
},
"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": "Quick only: whether the model reasons at length before writing. Default `true`; slower and can use more Studio Credits. Pass `false` for a faster run. Ignored with `multi_model`."
},
"confirm_private_sources": {
"type": "string",
"description": "Pass only after the user agrees. A write that would put Only me material this session read into a team-visible document is refused with a confirmation token; repeat the same call with that token here only once the user has said yes. The token releases only the items it names, for that document and that one write, and expires in 5 minutes"
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Content record ID (Quick, synchronous path only)."
},
"title": {
"type": "string",
"description": "Document title (Quick, synchronous path only)."
},
"content": {
"type": "string",
"description": "Document content in markdown (Quick, synchronous path only)."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/open this content in Marcora (Quick, synchronous path only)."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — use as content_id in get_content and share tools (Quick, synchronous path only)."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation (Quick, synchronous path only)."
},
"generation_id": {
"type": "string",
"format": "uuid",
"description": "UUID to track async generation — pass to get_generation_status to poll for completion (blueprint or Multi-model asynchronous paths only)."
}
},
"description": "Quick (no blueprint) returns the content object directly. With blueprint_uuid, or with generation_mode multi_model, 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 Multi-model), produce_plan, ask_content_assistant or apply_grounding_fix. Poll it with the generation_id until the run completes; once finished it returns the current document and the Content Assistant reply that run produced.
Input Schema
{
"type": "object",
"required": [
"generation_id"
],
"properties": {
"generation_id": {
"type": "string",
"description": "The generation ID returned by `create_content` (with `blueprint_uuid` or `generation_mode: \"multi_model\"`), `produce_plan`, `ask_content_assistant` or `apply_grounding_fix`."
}
}
}Output Schema
{
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status of THIS generation_id. Terminal is \"completed\" for document generation (blueprint or document flow), \"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 or document generation, or Content Assistant flow)."
},
"blueprint_id": {
"type": "integer",
"description": "Blueprint runs 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 turn this run produced changed the document body."
},
"assistant_summary": {
"type": [
"string",
"null"
],
"description": "Content Assistant flow only: the assistant reply this run produced, as the sidebar thread shows it. Null if the run has written no reply, or it was written before runs were tracked; a reply that used sources the caller cannot open comes back as a notice."
}
},
"description": "Null until the run completes. For ai_assistant, the current_content is the live document, while assistant_summary and document_updated describe the turn this run produced (the document is not a frozen snapshot). Shape depends on flow_type."
},
"flow_type": {
"type": "string",
"description": "Which flow produced this generation: \"blueprint\" (generated from a blueprint), \"document\" (generated without a blueprint, e.g. Multi-model create_content or produce_plan without a blueprint) or \"ai_assistant\" (ask_content_assistant)."
},
"generation_id": {
"type": "string",
"description": "The generation ID being checked (UUID)."
},
"generation_mode": {
"enum": [
"quick",
"multi_model"
],
"type": "string",
"description": "How the document was written: quick (one model) or multi_model (two drafts and a synthesis). Omitted when not recorded."
}
}
}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 sort results by similarity instead of recency; search only re-orders and drops nothing.
Input Schema
{
"type": "object",
"properties": {
"search": {
"type": "string",
"description": "Optional natural-language query. When provided, every visible row is scored by similarity to it and the list is sorted by that score instead of recency; each row gains a relevance_score. Nothing is dropped, so the response is still all of the team's content. Omit or leave empty for the normal recency-ordered list."
}
}
}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. Cosine similarity (0–1; higher = more similar) of the row to the query."
}
}
}
}
}
}get_content
Retrieve the full markdown body of a content document by its content_id. Always use it to read a project's brief in full when get_project or get_relevant_context returns it truncated. Otherwise use it only when you need a document's text to answer a question, 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."
},
"confirm_private_sources": {
"type": "string",
"description": "Pass only after the user agrees. See Only me material in the tool notes: a write of content or name_override that would put Only me material this session read into a team-visible document returns a confirmation token; repeat the same call with that token here only once the user has said yes. The token expires in 5 minutes"
}
}
}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",
"description": "ID of the session that executed the run"
},
"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 Studio 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": "Studio 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": "Studio 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 and for existing users with no active team, or the login URL for existing users who still belong to an active team. 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. Such a user gets the login link if they still belong to an active team, or the sign-up link to rejoin if they have none (for example, a removed teammate). False for a brand-new user (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."
},
"message_for_user": {
"type": "string",
"description": "Present only with workspace_status \"empty\": plain text written to the user, saying the workspace is empty and offering to set it up. Pass it on in your reply as it is. It is an offer: save nothing without their OK"
},
"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."
},
"brand_foundation_build": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "queued or building"
},
"message": {
"type": "string",
"description": "What to tell the user"
}
},
"description": "Present only while Marcora is building the team's blank Brand Foundation sections from a website: {status, message}; status is queued or building. The blank sections are in progress, not empty: tell the user what message says and don't offer to draft them meanwhile. Absent otherwise"
}
}
}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, a tracked live web page, or calls imported from a connected call-recording app, 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."
},
"as_call": {
"type": "boolean",
"description": "Whether to save `content` as a call transcript in Calls. Omit it and Marcora decides: text that looks like a transcript becomes a call. true: save as a call even if it does not look like one. false: save as an ordinary context item even if it looks like a transcript. Only valid with `content`."
},
"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 (an empty string counts as not set)."
},
"audience": {
"enum": [
"only_me",
"team"
],
"type": "string",
"description": "Calls only. Who can see the call: only_me (default; visible only to the person who added it) or team. Rejected when the text is saved as an ordinary context item."
},
"call_date": {
"type": "string",
"description": "Calls only. When the call happened, as YYYY-MM-DD or an ISO 8601 timestamp. Omit it to take the date from the transcript."
},
"call_kind": {
"enum": [
"customer",
"external",
"team_meeting",
"one_on_one",
"recorded"
],
"type": "string",
"description": "Calls only. The kind of call: customer (a customer call), external (a meeting with people outside the team), team_meeting, one_on_one, recorded (a recorded talk or other single-speaker recording). Omit it to let Marcora work it out from who spoke."
},
"import_url": {
"type": "string",
"description": "A publicly reachable URL to fetch ONCE and store as a static markdown snapshot; the page is imported once as a static snapshot that cannot be refreshed (use connected_webpage_url for a page that should stay current). 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 is rejected), and the call waits up to about 25 seconds for the import: import_status \"ready\" on success, an error if the page can't be read (nothing is added), or \"processing\" only for a slow page. In that case the item does not exist until the import finishes: poll get_context_item with the returned id for up to about 5 minutes (not found, then the item with its content); if it is still not found, tell the user the save couldn't be confirmed yet and do not re-add the URL yourself. A failed slow import sends the user a \"wasn't saved\" notification."
},
"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."
},
"import_from": {
"type": "object",
"required": [
"toolkit",
"call_ids"
],
"properties": {
"toolkit": {
"type": "string",
"description": "fathom, gong or fireflies."
},
"call_ids": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 10,
"minItems": 1,
"description": "The app's own call ids, 1 to 10, each once. Get them from its list or search tool."
}
},
"description": "Bring in calls from a connected call-recording app instead of passing text. Use it instead of content, import_url and connected_webpage_url (it cannot be combined with them or with as_call, call_date, call_kind or call_company). Marcora fetches and cleans the transcripts itself; never pass transcript text. audience, project_id and collection_id apply as for calls."
},
"call_company": {
"type": [
"string",
"null"
],
"description": "Calls only. The other company on the call (null for none). Omit it to take the company from the transcript."
},
"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, and its stored content is overwritten with the fresh fetch. Because of that overwrite, add_context is marked as a destructive tool. Exactly one of content, import_url, or connected_webpage_url may be set (none or two-plus is rejected), and adding a tracked page requires an admin or editor role. The call waits up to about 25 seconds for the page, the same way import_url does: import_status \"ready\" on success, an error on failure (nothing is added for a new URL, and a tracked URL keeps its saved copy), or \"processing\" only if it is slow. In that case the item exists at once with empty content (word_count 0) until the fetch lands: poll get_context_item for up to about 5 minutes (a failed new page is removed, so it comes back not found; a tracked page keeps its saved copy); if unconfirmed, tell the user and do not re-add the URL."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Context item ID"
},
"call": {
"type": "object",
"required": [
"audience"
],
"properties": {
"date": {
"type": [
"string",
"null"
],
"description": "When it happened (ISO 8601), or null."
},
"kind": {
"enum": [
"customer",
"external",
"team_meeting",
"one_on_one",
"recorded",
null
],
"type": [
"string",
"null"
],
"description": "Kind of call."
},
"people": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"side"
],
"properties": {
"name": {
"type": "string"
},
"side": {
"enum": [
"internal",
"external",
"unknown"
],
"type": "string",
"description": "internal = user’s team."
},
"company": {
"type": [
"string",
"null"
]
}
}
},
"description": "Who was on the call."
},
"company": {
"type": [
"string",
"null"
],
"description": "Other company, or null."
},
"audience": {
"enum": [
"only_me",
"team"
],
"type": "string",
"description": "only_me or team."
},
"summary_status": {
"enum": [
"pending",
"ready",
"skipped",
"failed",
"waiting_credits",
null
],
"type": [
"string",
"null"
],
"description": "Summary state; ready = a summary exists."
}
},
"description": "Call details; present only on call items."
},
"name": {
"type": "string",
"description": "Context item name"
},
"content": {
"type": [
"string",
"null"
],
"description": "Always null on add_context for URL paths and pasted content — fetch the body with get_context_item"
},
"message": {
"type": "string",
"description": "Calls only. Where it went and who can see it; tell the user."
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"call_id",
"status",
"message"
],
"properties": {
"name": {
"type": "string",
"description": "The context item's name (imported)."
},
"status": {
"enum": [
"imported",
"duplicate",
"not_ready",
"failed"
],
"type": "string",
"description": "imported = saved; duplicate = already in Marcora; not_ready = the app has no transcript yet, try later; failed = it could not be brought in."
},
"call_id": {
"type": "string",
"description": "The app's id for the call."
},
"message": {
"type": "string",
"description": "What happened, in words for the user."
},
"audience": {
"enum": [
"only_me",
"team"
],
"type": "string",
"description": "Who can see it (imported)."
},
"filed_in": {
"type": "string",
"description": "Where it was filed, in words: Calls, a project or a collection (imported)."
},
"link_url": {
"type": "string",
"description": "Opens the context item in the Marcora web app (imported). Present exactly as returned."
},
"context_item_id": {
"type": "string",
"format": "uuid",
"description": "The saved context item (imported), or the existing one (duplicate)."
}
}
},
"description": "Present only on an import_from add: one entry per requested call, in order."
},
"summary": {
"type": "object",
"required": [
"imported",
"duplicate",
"not_ready",
"failed"
],
"properties": {
"failed": {
"type": "integer"
},
"imported": {
"type": "integer"
},
"duplicate": {
"type": "integer"
},
"not_ready": {
"type": "integer"
}
},
"description": "Present only on an import_from add: how many calls ended in each state."
},
"audience": {
"enum": [
"only_me",
"team"
],
"type": "string",
"description": "Calls only. Who can see it."
},
"capacity": {
"type": "object",
"properties": {
"used": {
"type": "integer"
},
"limit": {
"type": "integer"
},
"remaining": {
"type": "integer"
}
},
"description": "Present only when the team's plan limits context items: {used, limit, remaining} after this add. Absent when the plan has no limit. At the limit, a call that would create an item returns an error stating the limit"
},
"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 is still processing)"
},
"import_from": {
"type": "object",
"required": [
"toolkit",
"app_name"
],
"properties": {
"toolkit": {
"type": "string",
"description": "The app's id, for example fathom."
},
"app_name": {
"type": "string",
"description": "The app's name to show the user."
}
},
"description": "Present only on an import_from add: which app the calls came from."
},
"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: \"ready\" once the page has loaded (the call waits up to ~25 seconds); \"processing\" only if it is still running. null for pasted content"
},
"saved_as_call": {
"type": "boolean",
"description": "True when saved as a call."
},
"automatic_import_link": {
"type": "string",
"description": "Present only when at least one call was imported. Opens the automatic-import rule editor with this source, destination and audience filled in; nothing is saved until the user saves it. Offer it, exactly as returned."
},
"brand_foundation_build": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Always \"queued\" on add_context"
},
"message": {
"type": "string",
"description": "What to tell the user"
}
},
"description": "Present only on a connected_webpage_url add that queued a build of the team's blank Brand Foundation sections from the website: {status: \"queued\", message}. message says what to tell the user (the blank sections are being built and should be ready within about a minute, not empty). Absent otherwise, so never imply a build is running without it"
}
}
}update_context
Update an existing context item: change its name, body, collection, or project, or re-pull a tracked web page's content. collection_id is always required; omitting project_id keeps the item's project.
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 sits in. Omit the key to leave the item's project unchanged: project and collection placement are independent, so moving an item into a collection does not touch this. Pass a project ID to move the item to that project (same team only). Pass null only when the user asked to take the item out of its project. 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. With a project_id, the first call also returns the project's brief. Use it to write on-brand content yourself (with include_brand_foundation: true) or to answer questions about the company — not before create_content with instructions, which gathers context automatically.
Input Schema
{
"type": "object",
"required": [
"prompt"
],
"properties": {
"calls": {
"type": "object",
"properties": {
"kinds": {
"type": "array",
"items": {
"enum": [
"customer",
"external",
"team_meeting",
"one_on_one",
"recorded"
],
"type": "string"
},
"description": "Only these kinds."
},
"date_to": {
"type": "string",
"description": "Up to this date (YYYY-MM-DD)."
},
"companies": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these companies."
},
"date_from": {
"type": "string",
"description": "From this date (YYYY-MM-DD)."
}
},
"description": "Also search the team's calls. Optional filters: date_from / date_to (YYYY-MM-DD or ISO 8601, compared with the call's own date), kinds, companies. Pass {} for every call you may use. Only Team calls unless include_only_me is true.",
"additionalProperties": false
},
"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)."
},
"include_only_me": {
"type": "boolean",
"default": false,
"description": "Default false: only Team items are searched. Set true to also search your own Only me items, including Only me calls; never another member's. Calls filed in Calls come back only when that Calls collection's id is in collection_ids, or through their project; on its own, true returns none of them. Only me results carry audience: only_me. If you then write what you read into a team-visible document, you are asked first."
},
"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."
},
"include_project_brief": {
"type": "boolean",
"default": true,
"description": "Default true. When project_id is given, also return that project's brief as a top-level project_brief block. Leave true on the first call for a project in a conversation; set false on later calls for the same project so the brief isn't re-sent. Ignored when project_id is omitted."
},
"_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": {
"audience": {
"enum": [
"team",
"only_me"
],
"type": "string",
"description": "Who can see this item: team, or only_me (yours alone; returned only when include_only_me is true)."
},
"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"
},
"source_url": {
"type": "string",
"description": "Original external page URL. Present only for webpage items."
},
"content_type": {
"type": [
"string",
"null"
]
},
"last_updated": {
"type": [
"integer",
"null"
],
"description": "Unix ms timestamp of the item's last update."
},
"collection_id": {
"type": [
"integer",
"null"
]
},
"context_item_id": {
"type": "string",
"format": "uuid"
},
"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": "One entry per parent context item the returned chunks came from."
},
"retrieval": {
"type": "object",
"properties": {
"project_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"team_scope": {
"type": "string"
},
"collection_ids": {
"type": "array",
"items": {
"type": "integer"
}
},
"returned_count": {
"type": "integer",
"description": "Number of context chunks returned."
},
"dimension_option_ids": {
"type": "array",
"items": {
"type": "integer"
}
},
"excluded_context_rag_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
"description": "Echo of the search scope this response was produced under."
},
"project_brief": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"truncated": {
"type": "boolean",
"description": "True when content_intro is an excerpt and the full body must be fetched with get_content."
},
"content_id": {
"type": "string",
"format": "uuid"
},
"read_first": {
"type": "string",
"description": "Imperative instruction stating why the brief must be read before working in this project, including the content_id to fetch."
},
"word_count": {
"type": "integer",
"description": "Word count of the full brief body."
},
"content_intro": {
"type": "string",
"description": "The brief's body, in full when short, otherwise its opening ~400 words."
}
},
"description": "Present only when project_id is given, include_project_brief is true (the default) and the project has a brief; absent otherwise. The same block get_project returns: the project's authoritative statement of premise, scope and structural decisions. READ IT FIRST: the context chunks in this response may be older than it or contradict it. content_intro is an excerpt (the full body when the brief is short, otherwise the opening ~400 words with truncated: true); pass content_id to get_content for the full text."
},
"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"
}
}
},
"included": {
"type": "boolean"
},
"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."
},
"message_for_user": {
"type": "string",
"description": "Present only with workspace_status \"empty\": plain text written to the user, saying the workspace is empty and offering to set it up. Pass it on in your reply as it is. It is an offer: save nothing without their OK"
},
"relevant_context": {
"type": "string",
"description": "Ready-to-use markdown context packet assembled from the matched chunks."
},
"brand_foundation_build": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "queued or building"
},
"message": {
"type": "string",
"description": "What to tell the user"
}
},
"description": "Present only while Marcora is building the team's blank Brand Foundation sections from a website: {status, message}; status is queued or building. The blank sections are in progress, not empty: tell the user what message says and don't offer to draft them meanwhile. Absent otherwise"
}
}
}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 sort items by similarity instead of recency; search only re-orders and drops nothing.
Input Schema
{
"type": "object",
"properties": {
"kinds": {
"type": "array",
"items": {
"enum": [
"customer",
"external",
"team_meeting",
"one_on_one",
"recorded"
],
"type": "string"
},
"description": "Calls only: keep calls of these kinds (customer (a customer call), external (a meeting with people outside the team), team_meeting, one_on_one, recorded (a recorded talk or other single-speaker recording)). Setting it returns calls only."
},
"search": {
"type": "string",
"description": "Optional natural-language query. When provided, every item you can see is scored by its best-matching passage and the list is sorted by that score instead of recency; each item gains a relevance_score. Nothing is dropped, so the response is still the whole library. Omit or leave empty for the normal recency-ordered list. To retrieve the passages relevant to a question, use get_relevant_context."
},
"company": {
"type": "string",
"description": "Calls only: keep calls with this company (a case-insensitive part of the company name, or its exact domain). Setting it returns calls only."
},
"date_to": {
"type": "string",
"description": "Return only items dated on or before this, as YYYY-MM-DD (the whole day counts) or ISO 8601. A call with no known date does not match a date bound."
},
"date_from": {
"type": "string",
"description": "Return only items dated on or after this, as YYYY-MM-DD or ISO 8601. Compared with the call’s own date (when it happened) for calls, and the created date (when it was added) for every other item. A call with no known date does not match a date bound."
},
"content_type": {
"type": "string",
"description": "Return only items of this type, for example call_transcript (calls), manual (pasted text) or webpage. Omit for every type."
},
"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."
},
"call": {
"type": "object",
"required": [
"audience"
],
"properties": {
"date": {
"type": [
"string",
"null"
],
"description": "When it happened (ISO 8601), or null."
},
"kind": {
"enum": [
"customer",
"external",
"team_meeting",
"one_on_one",
"recorded",
null
],
"type": [
"string",
"null"
],
"description": "Kind of call."
},
"people": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"side"
],
"properties": {
"name": {
"type": "string"
},
"side": {
"enum": [
"internal",
"external",
"unknown"
],
"type": "string",
"description": "internal = user’s team."
},
"company": {
"type": [
"string",
"null"
]
}
}
},
"description": "Who was on the call."
},
"company": {
"type": [
"string",
"null"
],
"description": "Other company, or null."
},
"audience": {
"enum": [
"only_me",
"team"
],
"type": "string",
"description": "only_me or team."
},
"summary_status": {
"enum": [
"pending",
"ready",
"skipped",
"failed",
"waiting_credits",
null
],
"type": [
"string",
"null"
],
"description": "Summary state; ready = a summary exists."
}
},
"description": "Call details; present only on call items."
},
"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."
},
"audience": {
"enum": [
"only_me"
],
"type": "string",
"description": "Present (only_me) only on an Only me item, visible to its owner alone; Team items omit it. Ask the user before copying its text anywhere the team can see."
},
"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": "Similarity of the item's best-matching passage to `search` (cosine 0–1; higher = more similar). ONLY present when a `search` query was given; null means the item has no indexed passage yet and could not be scored (sorted last). Absent entirely when no `search` was given."
},
"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
Open a single context item by ID and return its full markdown content and metadata. Use it when you already have an item's ID and need to read the whole item; it does not search (use get_relevant_context for that).
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."
},
"call": {
"type": "object",
"required": [
"audience"
],
"properties": {
"date": {
"type": [
"string",
"null"
],
"description": "When it happened (ISO 8601), or null."
},
"kind": {
"enum": [
"customer",
"external",
"team_meeting",
"one_on_one",
"recorded",
null
],
"type": [
"string",
"null"
],
"description": "Kind of call."
},
"people": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"side"
],
"properties": {
"name": {
"type": "string"
},
"side": {
"enum": [
"internal",
"external",
"unknown"
],
"type": "string",
"description": "internal = user’s team."
},
"company": {
"type": [
"string",
"null"
]
}
}
},
"description": "Who was on the call."
},
"source": {
"type": [
"string",
"null"
],
"description": "How the call came in (paste or upload)."
},
"company": {
"type": [
"string",
"null"
],
"description": "Other company, or null."
},
"summary": {
"type": [
"string",
"null"
],
"description": "The call summary (markdown). Null until summary_status is ready."
},
"audience": {
"enum": [
"only_me",
"team"
],
"type": "string",
"description": "only_me or team."
},
"insights": {
"type": [
"object",
"null"
],
"description": "The summary sections (overview, decisions, action_items, quotes and, by kind, pains, objections, competitors, asks, content_commitments, key_points), each a list of points with optional time_ms and speaker. Null until summary_status is ready.",
"additionalProperties": true
},
"source_url": {
"type": [
"string",
"null"
],
"description": "Link to the original recording, when there is one."
},
"call_purpose": {
"type": [
"string",
"null"
],
"description": "discovery, demo, renewal, onboarding, review, support or other, when worked out from the summary."
},
"duration_min": {
"type": [
"integer",
"null"
],
"description": "Length of the call in minutes."
},
"summary_status": {
"enum": [
"pending",
"ready",
"skipped",
"failed",
"waiting_credits",
null
],
"type": [
"string",
"null"
],
"description": "Summary state; ready = a summary exists."
}
},
"description": "Call details; present only on call items."
},
"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."
},
"audience": {
"enum": [
"only_me"
],
"type": "string",
"description": "Present (only_me) only on an Only me item, visible to its owner alone; Team items omit it. Ask the user before copying its text anywhere the team can see."
},
"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."
}
}
}find_app
Look up the apps Marcora offers to connect, by name (for example Gong) or by what they do (for example "call recordings"). Returns each match's connection state for the current user, whether its calls can be brought in with add_context import_from, and a link to connect it. Read-only.
Input Schema
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "Matches to return, 1 to 20. Default 10."
},
"query": {
"type": "string",
"description": "An app name or what it does. Required."
}
}
}Output Schema
{
"type": "object",
"required": [
"query",
"apps",
"total_matches",
"message"
],
"properties": {
"apps": {
"type": "array",
"items": {
"type": "object",
"required": [
"app",
"name",
"description",
"connection_state",
"brings_in_calls",
"connect_link"
],
"properties": {
"app": {
"type": "string",
"description": "The app's id, for example gong."
},
"name": {
"type": "string",
"description": "The app's name to show the user."
},
"description": {
"type": "string",
"description": "What the app does."
},
"connect_link": {
"type": [
"string",
"null"
],
"description": "Opens the Integrations page on this app. Nothing connects until the user acts. Present exactly as returned."
},
"brings_in_calls": {
"type": "boolean",
"description": "True when add_context import_from can bring in this app's calls."
},
"connection_state": {
"enum": [
"connected",
"not_connected",
"expired"
],
"type": "string",
"description": "The user's own connection: connected; not_connected (never completed); expired (worked before, needs renewing)."
}
}
},
"description": "Matching apps, best match first. Empty when Marcora offers no such app."
},
"query": {
"type": "string",
"description": "The query that was searched."
},
"message": {
"type": "string",
"description": "How to use the result."
},
"total_matches": {
"type": "integer",
"description": "How many apps matched before the limit."
}
}
}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. Uses Studio Credits.
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_content."
},
"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)"
}
}
}
}
}
}
}
}
}learn_marcora_tools
Returns Marcora's guide to its own tools: what each Marcora object is, which tool fits which request, the order the tools chain in, and the mistakes to avoid.
Input Schema
{
"type": "object",
"properties": {
"topic": {
"enum": [
"choosing-tools",
"generate-content",
"projects-and-briefs",
"add-context",
"find-context",
"grounding",
"workflows",
"plans-and-playbooks",
"pitfalls",
"edge-cases",
"recipes",
"glossary"
],
"type": "string",
"description": "Which section of the guide to return. Omit it for the overview, which lists every topic with a summary — then pass the topic whose summary matches the task (e.g. `workflows` before building a Marcora workflow, `projects-and-briefs` before working inside a project)."
}
}
}Output Schema
{
"type": "object",
"required": [
"topic",
"title",
"guide_version",
"content",
"topics"
],
"properties": {
"title": {
"type": "string",
"description": "Human-readable title of the section."
},
"topic": {
"type": "string",
"description": "The section returned: `overview`, or the topic that was requested."
},
"topics": {
"type": "array",
"items": {
"type": "object",
"required": [
"topic",
"title",
"summary"
],
"properties": {
"title": {
"type": "string",
"description": "Title of the topic."
},
"topic": {
"type": "string",
"description": "Value to pass as `topic`."
},
"summary": {
"type": "string",
"description": "One line on what the topic covers, to decide whether the task needs it."
}
}
},
"description": "Every topic in the guide, in order. Pass one as `topic` to read that section."
},
"content": {
"type": "string",
"description": "The section's guidance, in markdown."
},
"guide_version": {
"type": "string",
"description": "Version of the Marcora guide this text comes from (matches the companion marcora-mcp skill's version)."
}
}
}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: its members, documents, context items, and its brief. Read the brief before doing substantive work in the project. 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",
"format": "uuid",
"description": "Project UUID."
},
"name": {
"type": "string",
"description": "Project name."
},
"status": {
"type": "string",
"description": "Project status (e.g. active, archived)."
},
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Member name."
},
"role": {
"type": "string",
"description": "Role in project (e.g. owner, member)."
},
"email": {
"type": "string",
"description": "Member email."
},
"user_id": {
"type": "integer",
"description": "User ID."
}
}
}
},
"documents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Content name."
},
"purpose": {
"type": "string",
"description": "Role of content in project (e.g. supporting)."
},
"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": "Content category, or null."
},
"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",
"description": "Visibility setting."
},
"is_project_brief": {
"type": "boolean",
"description": "True on the one document that is this project's brief. Brief-flagged entries are sorted first. Read that document before doing substantive work in this project — see the top-level project_brief block."
},
"in_project_context": {
"type": "boolean",
"description": "Whether included in project context for AI generation."
}
}
}
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation."
},
"visibility": {
"type": "string",
"description": "Visibility (e.g. team, private)."
},
"context_items": {
"type": "array",
"description": "Context items associated with this project."
},
"project_brief": {
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
},
"truncated": {
"type": "boolean",
"description": "True when content_intro is an excerpt and the full body must be fetched with get_content."
},
"content_id": {
"type": "string",
"format": "uuid"
},
"read_first": {
"type": "string",
"description": "Imperative instruction stating why the brief must be read before working in this project, including the content_id to fetch."
},
"word_count": {
"type": "integer",
"description": "Word count of the full brief body."
},
"content_intro": {
"type": "string",
"description": "The brief's body, in full when short, otherwise its opening ~400 words."
}
},
"description": "The project's brief, if one is set — the authoritative statement of the project's premise, scope and structural decisions. READ IT FIRST: other documents and context items in this project may be older than it or contradict it. content_intro is an excerpt (the full body when the brief is short, otherwise the opening ~400 words with truncated: true); pass content_id to get_content for the full text, or to update_content to edit it."
}
}
}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. `project_brief_instructions` uses Studio Credits; `project_brief_content` does not.
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"
],
"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": "Summary of the linked content item, or null. When non-null it is exactly: 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). Pass `null` to clear."
},
"plan_uuid": {
"type": "string",
"description": "Required. UUID of the plan to update."
},
"project_id": {
"type": "string",
"description": "Update project association. Pass a new value to change it; `null` is ignored."
},
"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. Pass a new value to change it; `null` is ignored."
},
"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. Pass `null` to clear."
},
"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": "Non-empty array REPLACES the full set of context collection associations; `[]` is ignored."
},
"reference_document_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Non-empty array REPLACES the full set of reference doc associations; `[]` is ignored."
},
"targeting_dimension_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Non-empty array REPLACES the full set of targeting dimension associations; `[]` is ignored."
}
}
}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)."
},
"ai_provider": {
"type": "string",
"description": "Quick only: which model family writes the document. The allowed values and the default are in the tool's input schema. Ignored with `multi_model`."
},
"generation_mode": {
"enum": [
"quick",
"multi_model"
],
"type": "string",
"description": "`quick` (one model) or `multi_model` (two drafts and a synthesis). Default: Multi-model for a plan with a blueprint, Quick for one without."
},
"use_extended_thinking": {
"type": "boolean",
"description": "Quick only: whether the model reasons at length before writing. Default `true`; slower and costlier. Ignored with `multi_model`."
}
}
}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."
}