MCP tools
On this page
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.
| Tool | Scope | Credits | What it does |
|---|---|---|---|
site.read | again) | ||
brief.create | |||
sources.check | |||
article.write | |||
article.add_languages | |||
article.read | |||
source.add | |||
export.render |
site.read #
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.
{
"type": "object",
"properties": {
"again": {
"type": "boolean"
}
},
"required": [],
"additionalProperties": false
}GET /sites/{site}, preceded by POST /sites/{site}/analyze when again is true.
brief.create #
{
"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 #
{
"type": "object",
"properties": {
"topic": {
"type": "string"
}
},
"required": [
"topic"
],
"additionalProperties": false
}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 #
{
"type": "object",
"properties": {
"briefId": {
"type": "string"
},
"supersedes": {
"type": "string"
},
"alsoNew": {
"type": "boolean"
}
},
"required": [
"briefId"
],
"additionalProperties": false
}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 #
{
"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
}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 #
{
"type": "object",
"properties": {
"articleId": {
"type": "string"
}
},
"required": [
"articleId"
],
"additionalProperties": false
}GET /articles/{id}: the Article with the wrapping described above. A language version is read by its own articleId, which languageVersions lists.
source.add #
{
"type": "object",
"properties": {
"articleId": {
"type": "string"
},
"claimId": {
"type": "string"
},
"url": {
"type": "string"
}
},
"required": [
"articleId",
"claimId",
"url"
],
"additionalProperties": false
}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 #
{
"type": "object",
"properties": {
"articleId": {
"type": "string"
},
"format": {
"type": "string",
"enum": [
"markdown",
"pdf",
"docx",
"wordpress"
]
}
},
"required": [
"articleId",
"format"
],
"additionalProperties": false
}markdownmakes the export and returns it as{ format, markdown }, the text wrapped as a single<source_text>block.pdfanddocxmake the file and return{ format, note }. The file is downloaded by a person from the article in Brenzuri.wordpressdelivers 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 withno_connection.
approval_required and export_blocked_flagged come back as tool errors.
Results, in general #
| Part | Contains |
|---|---|
content | source_text is quoted data. Then one path: value line per leaf, keys sorted. |
structuredContent | |
isError | structuredContent: { error, message, … }. |