MCP Tools
Context Intelligence

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.

Parameters

NameTypeRequiredDefaultDescription
content_idstringNoExisting document to scan. Pass it ALONE to scan the document as it stands - the safe default.
contentstringNoMarkdown to ground. Alone, it is stored as a new document. WITH content_id, it REPLACES that document's entire body - pass the full document, never a fragment.
titlestringNoOnly meaningful with content. Omit it and the title is taken from the first line.

Input Schema

{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "content_id"
      ]
    },
    {
      "required": [
        "content"
      ]
    }
  ],
  "properties": {
    "title": {
      "type": "string",
      "description": "Only meaningful with content. Omit it and the title is taken from the first line."
    },
    "content": {
      "type": "string",
      "description": "Markdown to ground. Alone, it is stored as a new document. WITH content_id, it REPLACES that document's entire body - pass the full document, never a fragment."
    },
    "content_id": {
      "type": "string",
      "format": "uuid",
      "description": "Existing document to scan. Pass it ALONE to scan the document as it stands - the safe default."
    }
  },
  "description": "One of content_id or content is required. Passing content TOGETHER with content_id replaces that document's entire body."
}

Output Schema

{
  "type": "object",
  "properties": {
    "claims": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "refs": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "The context the claim was matched against."
          },
          "value": {
            "type": [
              "string",
              "null"
            ]
          },
          "bucket": {
            "enum": [
              "supported",
              "conflict",
              "gap"
            ],
            "type": "string"
          },
          "subject": {
            "type": [
              "string",
              "null"
            ]
          },
          "claim_text": {
            "type": "string"
          },
          "confidence": {
            "type": "string",
            "description": "A STRING, not a number - e.g. \"0.82\". Parse it before comparing."
          }
        }
      },
      "description": "Every factual claim extracted from the document."
    },
    "status": {
      "enum": [
        "running",
        "complete",
        "failed",
        "none"
      ],
      "type": "string",
      "description": "running means the scan is still going - poll with scan_id."
    },
    "scan_id": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid",
      "description": "The scan run. Poll get_grounding_result with this value."
    },
    "summary": {
      "type": "object",
      "properties": {
        "gaps": {
          "type": "integer",
          "description": "Claims the library has nothing on."
        },
        "conflicts": {
          "type": "integer",
          "description": "Claims the library contradicts."
        },
        "supported": {
          "type": "integer",
          "description": "Claims the context library backs."
        },
        "total_claims": {
          "type": "integer"
        },
        "corpus_freshness": {
          "type": "string",
          "description": "How current the context the scan checked against is."
        }
      }
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "enum": [
              "conflict",
              "gap"
            ],
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "acknowledged",
              "dismissed",
              "resolved",
              null
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "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",
            "format": "uuid",
            "description": "Pass to apply_grounding_fix."
          },
          "suggested_fix": {
            "type": [
              "object",
              "null"
            ],
            "description": "The full recommended update. Review this with the user before applying."
          },
          "recommendation": {
            "type": [
              "string",
              "null"
            ],
            "description": "What Marcora suggests doing."
          },
          "context_item_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Where applying would write. null means the fix targets the document itself."
          }
        }
      },
      "description": "The conflicts and gaps worth acting on. Pass a finding_id to apply_grounding_fix."
    },
    "link_url": {
      "type": "string",
      "format": "uri",
      "description": "Opens the document with its grounding panel open. Hand this to the user."
    },
    "content_id": {
      "type": "string",
      "format": "uuid",
      "description": "The document that was scanned."
    },
    "corpus_items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "link_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "null when there is nothing to link to."
          },
          "context_item_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "null for entries that are not context items, such as project briefs."
          },
          "content_category": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "description": "The context the scan was checked against."
    },
    "details_visible": {
      "type": "boolean",
      "description": "false when you are not the document's creator - you get counts only, no claim or finding detail."
    }
  },
  "description": "The grounding envelope. check_content_grounding and get_grounding_result return exactly this shape, so one handler works for both."
}

Instructions

When to use: the user wants to know whether a document is accurate and consistent with what their company has already said - "check this against our context", "is this on-message", "fact-check this draft". It is also the natural next step after you draft something for them.

Runs a grounding scan on a document: it extracts the document's factual claims and sorts each one into supported (the context library backs it), conflict (the library says something different), or gap (the library has nothing on it). You get back the claims, the findings, and the context it was checked against.

This closes the loop for agent-driven writing - draft, ground, review, apply, re-ground - without leaving the conversation.

Three entry modes

  • content_id alone - scan a document that already exists in Marcora. The safe default.
  • content alone - hand over markdown; Marcora stores it as a new document and scans it. The new content_id comes back in the response.
  • content_id + content - replaces that document's entire body with the markdown you pass, then re-scans. This is the revise-and-re-ground path.

Passing neither is an error.

:warning: content together with content_id is a whole-document overwrite

It replaces the document's ENTIRE body - identical to update_content.

This is never a "check this section" operation. If a user asks you to ground one paragraph or section of a document that already exists, do not pass that fragment with its content_id. You would replace the whole document with the fragment and destroy the rest of it - silently, with no error and no warning.

  • To check part of an existing document: pass content_id alone and scan the document as it stands.
  • To revise and re-check: pass the full revised document, not a fragment.

Timing - read this before calling

This waits up to about 20 seconds inline. If the scan finishes inside that window you get the full result straight back. Otherwise you get status: "running" with a scan_id.

A fresh scan usually needs 120-150 seconds. When you get running, poll get_grounding_result with that scan_id every 15-30 seconds. Do not call check_content_grounding again - that starts a second, redundant scan.

:warning: Poll by scan_id, never content_id

When polling a running scan, pass the scan_id you were handed. Polling get_grounding_result by content_id returns the document's previous completed scan marked complete - so you would read a stale result and believe the new scan had already finished. Nothing errors; the answer is just quietly the wrong one.

Re-scanning an unchanged document is fast (a few seconds), because unchanged claims are reused.

Requirements

Grounding requires the Command plan with an active subscription and available AI credits.

Parameters

Parameter Type Required Description
content_id string (uuid) No* Existing document to scan. Pass it alone to scan the document as it stands - the safe default
content string No* Markdown to ground. Alone, stored as a new document. With content_id, replaces that document's entire body - pass the full document, never a fragment
title string No Only meaningful with content. Omit and the title is taken from the first line

* One of content_id or content is required.

Output

The grounding envelope: content_id, scan_id, status, link_url, summary, findings[], claims[], corpus_items[], details_visible.

Two field-level traps worth knowing:

  • confidence on each claim is a string, e.g. "0.82" - not a number.
  • details_visible: false means you are not the document's creator, so you get counts only rather than claim and finding detail.

Hand the user the link_url - it opens the document with its grounding panel.

Errors

  • Provide either 'content_id' or 'content' (400) - neither was supplied.
  • Not a valid UUID (400) - malformed content_id.
  • Content not found (404) - no such document in your team.
  • ci_not_eligible (403) - the team is not on the Command plan, has no active subscription, or is out of AI credits.

Example prompts

  • "Ground this draft against our context library"
  • "Does this blog post contradict anything we've published?"
  • "Rewrite the pricing section and re-check it"
Scroll to Top