marcora-mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited marcora-mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The companion skill to the Marcora MCP server.
You are connected to Marcora, a product-marketing context platform for go-to-market teams. Marcora stores brand and product context, generates marketing content with AI, and organizes work into projects. This skill teaches you the object model, the workflow patterns, and the gotchas. The MCP tool definitions already document each tool's parameters and outputs — don't restate them. This skill covers everything the tool schemas can't: which tool to reach for, in what order, with what user intent, and what to do when things look ambiguous.
Mindset: Marcora is a context-first platform. Every piece of content draws on layered context (Brand Foundation → Reference Library → Project Context → per-generation collections). Your job before generating anything is to (1) understand what the user wants, (2) confirm the right context will be in scope, (3) state your plan in one sentence, (4) call the tool. Never silently guess between two tools that look similar — confirm.
Apply this skill on any Marcora-related task. You may already have relevant context in your awareness — a list of blueprints the user mentioned earlier, a project they're currently working on, content they just generated. Use what you already have; only call discovery tools (marcora:list_*) to fill genuine gaps. Don't re-list what you already know.
If the user explicitly opts out ("don't use my Marcora tools for this"), respect that and don't call any marcora:* tool.
The Marcora MCP server is hosted; the user's MCP client connects directly. You do nothing for setup. Every tool call runs as the authenticated user against their active team — auth is implicit. If a call returns an auth error, tell the user to reconnect in Marcora's integration settings; don't try to recover.
These are Marcora's core nouns. Internalize them before calling any tool.
marcora:create_content. Two creation modes that share one tool: pass instructions only for freeform AI generation (sync, 1–3 min), pass instructions + blueprint_uuid for blueprint-driven generation (async, 3–5 min, returns a generation_id to poll), or pass content only to save the user's own pre-written text directly.owner / editor / viewer) and a separate Collaborator role for project-only stakeholders.create_project(project_brief_details) (auto-generates a brief from a description) or on an existing project via update_project(project_brief_id=<content uuid>). The latter handles attachment automatically: if the content isn't yet in the project, the tool attaches it AND sets it as the brief in one call.add_context with no project_id. Filtered by relevancy at generation time.add_context with project_id. Always pulled in for that project's generations.collection_ids or dimension_option_ids on create_content. Not persisted as reusable context.marcora:get_brand_foundation. Always pulled into every content generation. You don't need to read it manually before generating.dimension_option_ids to shape generation for an audience.create_workflow, update_workflow, run_workflow, get_workflow, list_workflows, get_workflow_runs) and the patterns around output destinations, scheduling, and dedup.project_id) and may be generated from a Blueprint (blueprint_uuid).project_item, then "pinned" via project.project_brief_id. It is NOT a context item — different model, different tool.in_progress (being generated or edited) → ready (final).pending → gathering context → processing → completed (or failed). Poll marcora:get_generation_status until completed.active or archived. Project visibility: team or private.When marcora:create_content runs inside a project, Marcora automatically layers (these are the in-app labels — quote them when explaining context):
collection_ids. A project can have default collections.Outside a project, only layers 1, 2, and 4 apply.
Implication: don't repeat brand voice in your prompt (Layer 1 has it). Don't re-explain a project's strategic angle (Layer 3 has the brief). Your prompt's job is the one-off signal for this document — through dimension_option_ids (audience) or one-time collection_ids.
The five workflows you'll handle 80% of the time. Long-tail recipes (workflow-running, community-blueprint imports, exports) live in references/workflows.md.
Goal. Produce a piece of content for the user, optionally inside a project, optionally targeting an audience.
Preconditions. None hard-required. If you don't already know what blueprints exist, what projects exist, or what targeting options exist, fetch them first.
Steps.
marcora:list_blueprints (returns your published blueprints under a blueprints array). Propose a fitting one.marcora:list_community_blueprints (the Blueprint Exchange). If something there fits, propose it: "I don't see a matching template in your library, but '\[name]' on the Blueprint Exchange looks like a fit — want me to import it?" If they say yes: marcora:get_community_blueprint_details to confirm fit → marcora:import_community_blueprint → use the returned UUID as the blueprint_uuid in step 5.marcora:list_projects. If the user mentioned an initiative, propose scoping to it.marcora:list_targeting_dimensions. Pick option IDs.marcora:create_content with instructions (always) + blueprint_uuid (if blueprint) + project_id + dimension_option_ids + optional collection_ids for one-off context. Do not pre-fetch context with get_relevant_context — create_content pulls all relevant context internally.generation_id): poll marcora:get_generation_status every ~30s, surface progress to the user every minute. When status == completed, the response includes content.link_url.Validation. Before step 5, sanity-check that content is not combined with blueprint_uuid or instructions (mutually exclusive — pick one mode).
Output to user. "Done — your case study is ready: [link]. Want me to share it externally, export to Word, or refine?"
Narrow exception to "don't pre-fetch context". If the user wants content about something narrow and specific that probably isn't in the standard Reference Library (a particular customer name, a specific incident, a niche internal initiative), one targeted marcora:get_relevant_context call up front is reasonable — purely so you can ask "I don't see source material on X yet — want to add some before I generate?" Skip the pre-check for broad topics (brand voice, common positioning, generic blog ideas). The model pulls what it needs at generation time.
Goal. Make a specific Content item the strategic anchor of a project.
Preconditions. A project (you have the project_id) and a Content item (you have its UUID). Both must exist; the user must have editor or owner access to the team.
Steps.
marcora:list_projects to resolve it from the name.marcora:list_content and disambiguate with the user.marcora:update_project(project_id, project_brief_id=<content_uuid>). The tool handles BOTH cases automatically: if the content is already in the project's documents → uses the existing wrapper; if not → attaches it AND sets it as the brief in one call.Validation. None required after the call — the tool returns success: true with the updated project record.
Output to user. "Brief set: [project link]."
To edit the brief (not change which doc IS the brief): use update_content on the brief's content_id. Discover it via get_project(project_id).project_brief.content_id (the response includes a top-level project_brief: {name, content_id} | null shortcut so you don't have to guess which document is the brief) or, when the user just created the project, take it directly from the create_project response.
Pitfalls — this is the founding misfire that motivated this skill:
get_content and re-create it via create_content(project_id=...) to "put it in the project." That creates a duplicate with a fresh UUID, orphaned from the original. Attachment is a relationship, not a copy. update_project handles it.get_project first to check if the doc is in the project. update_project handles both states.add_context to set a brief — add_context creates a Context item, which is a different object than a Content item used as a brief.Goal. Persist a reference document (brand guidelines, persona research, competitor analysis, product spec, customer interview) so future generations can draw on it.
Preconditions. None.
Steps.
collection_ids or dimension_option_ids on create_content instead.marcora:list_context_collections. Use existing collection if a fit; otherwise marcora:create_context_collection.marcora:add_context with name and the body, plus optional collection_id (top-level) or project_id (project-scoped). Pick the body argument based on what you have:web_browse/web_fetch it into your conversation first just to forward the bytes. Exactly one of content / content_url is required; both → 400.Output to user. "Added: [link]. Want to use this in a content generation now?"
Goal. Set up a workstream container for an initiative.
Preconditions. None hard-required. If you don't already know the user's projects: marcora:list_projects to avoid duplicates.
Steps.
project_brief_details) or set up empty (and add a brief later via Workflow 2). Both paths are fine.marcora:create_project with name, optional visibility (team default | private), optional project_brief_details. When project_brief_details is supplied, the response includes project_brief: {name, content_id} — save the content_id so the user can edit the brief later via update_content.Output to user. "Project created: [link]."
Goal. Answer the user's question about what's in their library, or help them ideate using their existing context.
Preconditions. None.
Pick the right discovery tool based on intent:
marcora:get_relevant_context. Returns relevance-ranked chunks. Best when the user has a question that needs content, not a list.marcora:list_context_items. Returns names + intros + IDs. No RAG, just inventory. Set reference_library_only=true to scope to top-level Reference Library items only (i.e. items not in any project or collection).marcora:get_context_item(context_item_id). Returns full markdown + metadata + link.Steps (RAG path).
marcora:get_relevant_context with a descriptive prompt. Optionally broaden with project_id or collection_ids — these are additive (they add that project's / those collections' items on top of the general library, they don't restrict to only them). This is the only legitimate use of this tool besides the narrow Workflow 1 sourcing-check.sources[] array — one entry per parent context item, each with its context_item_id, name, content_type, a link_url deep-link (and source_url for webpage items), and the chunk IDs from that item. Use sources to cite/link what you surface.context_rag_ids (excludes already-returned chunks), or offer to add new context.marcora:get_context_item(context_item_id) — get_relevant_context only returns chunks, not the whole item.Writing the content yourself? If you'll draft with your own model instead of handing off to create_content, call marcora:get_relevant_context(prompt, include_brand_foundation=true). You get Reference Library RAG chunks and the team's Brand Foundation (company overview, brand voice, writing style, writing examples) in one response — so you can write on-brand without a separate get_brand_foundation call. Don't set the flag when handing off to create_content (it pulls Brand Foundation in automatically). When paginating, set it true on the first page only.
Steps (browse path).
marcora:list_context_items (default returns everything the user can see; pass reference_library_only=true for just orphan items in the top-level Reference Library). Items in private collections / private projects the user is not in are filtered out automatically.marcora:list_context_collections if the user is asking about collection-level organization, or marcora:get_project(project_id).context_items for one project's items.marcora:get_context_item(context_item_id).Output to user. A summary, not a JSON dump. Offer next steps: drill into a specific item (get_context_item), add new context, generate something based on what was found.
| If the user wants… | Call this | Not this — because… |
|---|---|---|
| To create a new document (any kind) | marcora:create_content | add_context creates a reference item, not a document. |
| To generate from a template they have | marcora:create_content with blueprint_uuid | get_blueprint only fetches details; it doesn't generate. |
| To save their own pre-written text as a document | marcora:create_content with content only | Don't add blueprint_uuid or instructions — incompatible. |
| To pin a Content item as a project's strategic anchor | marcora:update_project(project_brief_id=…) | add_context creates a Context item, NOT a brief. Different objects. |
| To attach an existing Content item to a project (no brief intent) | marcora:update_project(project_brief_id=…) (which auto-attaches), OR have the user attach in-app | Don't create_content(project_id=…) to "duplicate" it into the project — orphaned copy. |
| To add reference material reusable across all projects | marcora:add_context (no project_id) | A Context Collection is just a folder; you still need add_context to put items in it. |
| To add reference material specific to one project | marcora:add_context(project_id=…) | update_project(project_brief_id=…) would make it the brief — only one of those per project. |
| To edit the name, content, or location of an existing context item | marcora:update_context | add_context would create a duplicate. Note: collection_id and project_id are full-replace on every call — pass null to clear. Use marcora:list_context_items to find the ID, or marcora:get_context_item to confirm the current collection_id / project_id values before the full-replace update. To replace the body from a URL, pass content_url instead of content — backend extracts the markdown server-side. |
To edit an existing Content document (canvas or deliverable) — change the body, name, stage (ready / in_progress), visibility, category, or single-project assignment | marcora:update_content | update_context operates on Context items, not Content documents — different object. update_project(project_brief_id=…) only changes a project's brief pointer, not the document body or fields. update_content is partial-update (omit a field = leave alone) and replaces the body in full when content is supplied — call get_content first if you need to splice into the existing markdown. Setting name_override LOCKS the title so it won't auto-resync from the body's first header on future edits. |
| To have Marcora's in-editor AI assistant edit / extend a document — or answer a question about it — with the reply streaming live into the document's sidebar | marcora:ask_content_assistant | update_content is a manual full-body replace — you compute and supply the new markdown. ask_content_assistant hands the request to Marcora's own Content Assistant: it loads the document + brand/reference context, decides whether to edit or just reply, and streams the result live to the user in the app. It's async — returns a generation_id to poll via get_generation_status. It is NOT the general Marcora Agent. |
| To save a URL (blog post, competitor page, Google Doc export, presigned link) as a context item | marcora:add_context with content_url=<url> | Don't web_browse/web_fetch the URL just to paste the markdown into content — backend has the same Mozilla Readability extractor and avoids the round-trip through your conversation. |
| To know what content already exists about a topic | marcora:get_relevant_context for context, OR marcora:list_content for a content list | create_content would generate something new — wrong tool for "what already exists." |
| To browse what's in the user's context library (full inventory, not RAG) | marcora:list_context_items | get_relevant_context returns relevance-scored chunks, not item names. Use list_context_items for the catalog view. Pass reference_library_only=true to scope to just the top-level Reference Library. |
| To read the full markdown of a specific context item | marcora:get_context_item(context_item_id) | list_context_items only returns content_intro (a truncation). get_relevant_context returns RAG chunks. Use this for the actual content. |
| To read the team's Brand Foundation (company overview, brand voice, writing style, writing examples) | marcora:get_brand_foundation | get_relevant_context searches the Reference Library, not Brand Foundation. Also auto-pulled into every create_content — don't fetch as a setup step before generating. |
| To change one of the four Brand Foundation elements | marcora:update_brand_foundation | Brand Foundation lives at the team level, not as Context items — update_context won't touch it. Always full-replace; fetch first with get_brand_foundation to confirm what's being replaced. |
project_item row), not a copy. Use update_project(project_brief_id=...) — it auto-attaches.create_content already pulls in everything internally: Brand Foundation (so you don't need marcora:get_brand_foundation either), Reference Library via relevancy scoring, Project Context if project_id is set, and any collection_ids you pass. Calling marcora:get_relevant_context or marcora:get_brand_foundation as a setup step before generating is wasted work — the only legitimate uses for those tools are the narrow Workflow-1 sourcing-check (specific customer / incident not likely in the library) and direct user Q&A about brand voice or library contents.link_url. get_content is for two cases only: (a) the user later asks a question that requires reading the body to answer, or (b) you need the markdown to feed convert_markdown_to_word_doc.create_content returns a generation_id immediately. Without polling, the user thinks nothing happened. Poll get_generation_status every ~30s; surface progress every minute.create_content (no blueprint) returns the full content directly but the wait is real. Tell the user before calling.content cannot combine with blueprint_uuid either.options array.name="" is a safe no-op rather than a clobber. There's intentionally no way to clear a project name through this tool.name_override locks the title (has_custom_name=true) and there's no un-lock path in this tool — let the next plain content write recompute the auto-name if needed. The tool rejects non-deliverable canvas types (e.g. the canvases that back the context-item editor in the app) — those are managed by separate sync flows and would corrupt the linked context item if edited here.generation_id immediately, and the reply (plus any document edits) stream live into the document's AI Assistant sidebar for a user who has it open. Poll get_generation_status for the result (flow_type: ai_assistant, terminal status complete) — it returns the document's current state + the latest assistant reply, not a frozen snapshot. Reach for it (vs update_content) when you want Marcora's assistant to make the edit with full brand context and live streaming rather than computing the new body yourself. The assistant decides whether to edit the doc or just reply, unless you pass chat_only_mode: true.list_blueprints results from earlier in the conversation, or the user passed in a project ID, or another agent supplied a context summary — use what you have. Only call discovery tools to fill genuine gaps.For deeper edge cases, see references/pitfalls.md.
When things go wrong, surface the raw error to the user — don't silently retry.
update_project with project_brief_id) → the UUID doesn't exist in either canvases or deliverables. Verify with the user; common mistake is pasting a project_id where a content UUID was expected.marcora-workflow-builder skill.Read these only when the task specifically calls for them.
references/workflows.md — Long-tail recipes (community blueprint import, content sharing/export, async generation followup, project rename/archive, blueprint creation).references/pitfalls.md — Detailed edge cases beyond the 12 in the main pitfalls section.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.