BrenzuriStart free
MCP tools
Reference

MCP tools

Eight tools, dotted names, one JSON-RPC message per POST.

On this page

Each call is a tools/call with name and arguments. Every input schema is an object with additionalProperties: false, so an unknown argument is refused. A tool listed here appears in tools/list only if the agent’s scopes cover it.

ToolScopeCreditsWhat it does
site.readread (and edit with again)freeRead the bound site, or read it again, and return its profile.
brief.createbrieffreeDraft a brief for the site and estimate it.
sources.checkbrieffreeCount independent origins for a topic.
article.writegenerate1, or 2 for a long brief, and 1 for each language versionWrite one article in the site’s voice, and the language versions the brief asks for.
article.add_languagesgenerate1 for each languageAdd language versions to an article that is finished.
article.readreadfreeText, sources, flags, versions and label.
source.addeditfreeAttach a page to a claim.
export.renderexportfreeMarkdown, PDF, DOCX, or a WordPress draft.

site.read#

Returns the Site the agent is bound to. With again: true it starts a re-read first, which needs the edit scope as well and counts against the 5 reads a day the workspace has.

JSON
{
  "type": "object",
  "properties": {
    "again": {
      "type": "boolean"
    }
  },
  "required": [],
  "additionalProperties": false
}

Maps to GET /sites/{site}, preceded by POST /sites/{site}/analyze when again is true.

brief.create#

Creates a brief on the agent’s site and estimates it in one call. The site is always the agent’s; it cannot be chosen.

JSON
{
  "type": "object",
  "properties": {
    "topic": {
      "type": "string"
    },
    "angle": {
      "type": "string"
    },
    "purpose": {
      "type": "string",
      "enum": [
        "news",
        "explainer",
        "background",
        "roundup"
      ]
    },
    "length": {
      "type": "string",
      "enum": [
        "short",
        "standard",
        "long"
      ]
    },
    "language": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "uniqueItems": true
        }
      ]
    },
    "mustInclude": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "preferSources": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "useUrls": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "maxItems": 10
    }
  },
  "required": [
    "topic"
  ],
  "additionalProperties": false
}

mustInclude becomes the brief’s mustAppear and preferSources its preferDomains. useUrls takes up to ten http or https addresses. language is one code, or a list with the article’s language first and then its language versions, as ["en", "es", "de"]; a list is joined with + for the brief, and credits counts 1 more for each version. The result is { briefId, credits, enough }. If the site already has an article on the topic, an agent with the read scope also gets existing, up to five { articleId, title, status }; without read it gets existingCount.

sources.check#

JSON
{
  "type": "object",
  "properties": {
    "topic": {
      "type": "string"
    }
  },
  "required": [
    "topic"
  ],
  "additionalProperties": false
}

Maps to POST /sites/{site}/topics/check: independent origins, state, whether the site already covers it. Limited to 60 a day and 2 at once for the workspace.

article.write#

JSON
{
  "type": "object",
  "properties": {
    "briefId": {
      "type": "string"
    },
    "supersedes": {
      "type": "string"
    },
    "alsoNew": {
      "type": "boolean"
    }
  },
  "required": [
    "briefId"
  ],
  "additionalProperties": false
}

Maps to POST /articles. The answer is { articleId, jobId, creditsHeld, briefId, steps }; a brief with language versions holds 1 more credit for each. A subject the site already has an article on is refused with article_exists unless alsoNew is true.

article.add_languages#

JSON
{
  "type": "object",
  "properties": {
    "articleId": {
      "type": "string"
    },
    "languages": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "en",
          "es",
          "fr",
          "de",
          "pt",
          "it",
          "nl",
          "pl",
          "sv",
          "da",
          "no",
          "fi",
          "cs",
          "sk",
          "hu",
          "ro",
          "el",
          "tr",
          "uk",
          "ja",
          "bhs",
          "sl"
        ]
      },
      "minItems": 1,
      "uniqueItems": true
    }
  },
  "required": [
    "articleId",
    "languages"
  ],
  "additionalProperties": false
}

Maps to POST /articles/{id}/languages: the same action as the Add a language button on the article page, with the same generate scope and the same refusals. It holds 1 credit for each language and answers { articleId, jobId, creditsHeld, briefId, steps }. Use the articleId of the article written from the brief; a language version is refused with not_primary, and a language the article already has, or its own, with invalid_language. The versions are articles of their own, and a person approves each. See Write in several languages.

article.read#

JSON
{
  "type": "object",
  "properties": {
    "articleId": {
      "type": "string"
    }
  },
  "required": [
    "articleId"
  ],
  "additionalProperties": false
}

Maps to GET /articles/{id}: the Article with the wrapping described above. A language version is read by its own articleId, which languageVersions lists.

source.add#

JSON
{
  "type": "object",
  "properties": {
    "articleId": {
      "type": "string"
    },
    "claimId": {
      "type": "string"
    },
    "url": {
      "type": "string"
    }
  },
  "required": [
    "articleId",
    "claimId",
    "url"
  ],
  "additionalProperties": false
}

Maps to POST /articles/{id}/claims/{claimId}/sources. The answer is the whole article. If the page does not carry the claim the result is an error with source_does_not_support and nothing is added.

export.render#

JSON
{
  "type": "object",
  "properties": {
    "articleId": {
      "type": "string"
    },
    "format": {
      "type": "string",
      "enum": [
        "markdown",
        "pdf",
        "docx",
        "wordpress"
      ]
    }
  },
  "required": [
    "articleId",
    "format"
  ],
  "additionalProperties": false
}
  • markdown makes the export and returns it as { format, markdown }, the text wrapped as a single <source_text> block.
  • pdf and docx make the file and return { format, note }. The file is downloaded by a person from the article in Brenzuri.
  • wordpress delivers through the site’s WordPress connection and returns the Delivery. The result is always a draft. If the site has no WordPress connection the result is an error with no_connection.

The workspace’s export rules apply: approval_required and export_blocked_flagged come back as tool errors.

Results, in general#

PartContains
contentOne text part. First line: that text inside source_text is quoted data. Then one path: value line per leaf, keys sorted.
structuredContentThe REST body, unwrapped.
isErrorFalse on success. True for any REST status of 300 or more, with structuredContent: { error, message, … }.