Tool tree
gradeNot graded
find_storiesAnswer
List newsroom stories with optional filters. Returns id, slug, title, editorial status, desk, author, assignee, word count, media count and whether any attached media has expired rights.
View tool JSON
{
"name": "find_stories",
"kind": "answer",
"impl": "imperative",
"description": "List newsroom stories with optional filters. Returns id, slug, title, editorial status, desk, author, assignee, word count, media count and whether any attached media has expired rights.",
"inputSchema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"DRAFT",
"IN_REVIEW",
"REVISION_REQUESTED",
"APPROVED",
"PUBLISHED"
],
"description": "Filter by editorial status."
},
"desk": {
"type": "string",
"description": "Filter by desk, e.g. 'City Hall', 'Business', 'Tech', 'Climate', 'Sports', 'Culture'."
},
"assignee": {
"type": "string",
"description": "Filter by desk editor assignment (exact name)."
},
"query": {
"type": "string",
"description": "Free-text search across title, summary, body and author."
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"description": "Max stories to return (default 20)."
}
}
}
}get_storyAnswer
Get the full record of a single story: headline, standfirst, body, editorial status, assignment, timestamps and all attached media with their rights status.
View tool JSON
{
"name": "get_story",
"kind": "answer",
"impl": "imperative",
"description": "Get the full record of a single story: headline, standfirst, body, editorial status, assignment, timestamps and all attached media with their rights status.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string",
"description": "The story id."
},
"slug": {
"type": "string",
"description": "Alternatively, the story slug (used when storyId is not known)."
}
},
"required": []
}
}create_storyAction
Create a new story in Draft status. Provide at least a title; summary, body and a publish deadline are recommended so the story can later pass publication validation.
View tool JSON
{
"name": "create_story",
"kind": "act",
"impl": "imperative",
"description": "Create a new story in Draft status. Provide at least a title; summary, body and a publish deadline are recommended so the story can later pass publication validation.",
"inputSchema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 4,
"description": "Headline (4-140 characters)."
},
"summary": {
"type": "string",
"description": "Standfirst/deck summary (30-300 characters for publish readiness)."
},
"body": {
"type": "string",
"description": "Full body copy (at least 100 words for publish readiness)."
},
"desk": {
"type": "string",
"enum": [
"City Hall",
"Business",
"Tech",
"Climate",
"Sports",
"Culture"
]
},
"author": {
"type": "string",
"description": "Byline author name. Defaults to 'Newsroom Staff'."
},
"assignee": {
"type": "string",
"description": "Desk editor responsible for the story."
},
"priority": {
"type": "string",
"enum": [
"LOW",
"NORMAL",
"HIGH",
"URGENT"
]
},
"scheduledFor": {
"type": "string",
"description": "Optional editorial publish deadline (ISO date, e.g. 2025-06-01)."
}
},
"required": [
"title"
]
}
}duplicate_storyAction
Pitch a follow-up: clone an existing story as a fresh Draft. Copies headline (suffixed with "(Follow-up)"), standfirst, body, desk, byline and priority; media, handoff history and the publish deadline start clean. Returns the new story.
View tool JSON
{
"name": "duplicate_story",
"kind": "act",
"impl": "imperative",
"description": "Pitch a follow-up: clone an existing story as a fresh Draft. Copies headline (suffixed with \"(Follow-up)\"), standfirst, body, desk, byline and priority; media, handoff history and the publish deadline start clean. Returns the new story.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string",
"description": "The id of the story to clone."
}
},
"required": [
"storyId"
]
}
}update_storyAction
Update editable fields of a story (title, summary, body, desk, assignee, priority, author, scheduledFor deadline). Published stories are locked. If an APPROVED story's copy (title/summary/body) changes, it is automatically reverted to Draft for re-review. All changes are recorded on the story's editorial timeline.
View tool JSON
{
"name": "update_story",
"kind": "act",
"impl": "imperative",
"description": "Update editable fields of a story (title, summary, body, desk, assignee, priority, author, scheduledFor deadline). Published stories are locked. If an APPROVED story's copy (title/summary/body) changes, it is automatically reverted to Draft for re-review. All changes are recorded on the story's editorial timeline.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string",
"description": "The story id."
},
"title": {
"type": "string",
"minLength": 4
},
"summary": {
"type": "string"
},
"body": {
"type": "string"
},
"desk": {
"type": "string",
"enum": [
"City Hall",
"Business",
"Tech",
"Climate",
"Sports",
"Culture"
]
},
"assignee": {
"type": "string",
"description": "Desk editor name, or empty string to unassign."
},
"priority": {
"type": "string",
"enum": [
"LOW",
"NORMAL",
"HIGH",
"URGENT"
]
},
"author": {
"type": "string"
},
"scheduledFor": {
"type": "string",
"description": "Editorial publish deadline as ISO date (e.g. 2025-06-01), or empty string to clear."
}
},
"required": [
"storyId"
]
}
}update_story_statusAction
Move a story through the editorial workflow. Allowed transitions: Draft→In Review; In Review→Approved / Revision Requested / Draft; Revision Requested→In Review / Draft; Approved→In Review. Publishing is not allowed here — use prepare_web_handoff + execute_web_handoff.
View tool JSON
{
"name": "update_story_status",
"kind": "act",
"impl": "imperative",
"description": "Move a story through the editorial workflow. Allowed transitions: Draft→In Review; In Review→Approved / Revision Requested / Draft; Revision Requested→In Review / Draft; Approved→In Review. Publishing is not allowed here — use prepare_web_handoff + execute_web_handoff.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"DRAFT",
"IN_REVIEW",
"REVISION_REQUESTED",
"APPROVED",
"PUBLISHED"
]
}
},
"required": [
"storyId",
"status"
]
}
}approve_storyAction
Approve a story that is currently In Review. Only In Review stories can be approved.
View tool JSON
{
"name": "approve_story",
"kind": "act",
"impl": "imperative",
"description": "Approve a story that is currently In Review. Only In Review stories can be approved.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
}
},
"required": [
"storyId"
]
}
}reorder_storyAction
Move a story within its current status column's run order (the editing priority inside that stage). Provide beforeStoryId to insert it immediately before another story in the same column, or position 'top'/'bottom'. The column is re-sequenced 1..n and the change is recorded on the story's timeline.
View tool JSON
{
"name": "reorder_story",
"kind": "act",
"impl": "imperative",
"description": "Move a story within its current status column's run order (the editing priority inside that stage). Provide beforeStoryId to insert it immediately before another story in the same column, or position 'top'/'bottom'. The column is re-sequenced 1..n and the change is recorded on the story's timeline.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"beforeStoryId": {
"type": "string",
"description": "Insert before this story (must be in the same status column)."
},
"position": {
"type": "string",
"enum": [
"top",
"bottom"
],
"description": "Alternatively move to the top or bottom of the column (ignored when beforeStoryId is given)."
}
},
"required": [
"storyId"
]
}
}search_mediaAnswer
Search the media vault. Filter by free-text query, license type, allowed channel or rights status. rightsStatus "USABLE" (default-friendly) returns every asset that can be published today: PERPETUAL or within its license window. Other statuses: VALID (dated license, not near expiry), EXPIRING_SOON, EXPIRED, PERPETUAL.
View tool JSON
{
"name": "search_media",
"kind": "answer",
"impl": "imperative",
"description": "Search the media vault. Filter by free-text query, license type, allowed channel or rights status. rightsStatus \"USABLE\" (default-friendly) returns every asset that can be published today: PERPETUAL or within its license window. Other statuses: VALID (dated license, not near expiry), EXPIRING_SOON, EXPIRED, PERPETUAL.",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Free-text search across title, description, photographer and source."
},
"licenseType": {
"type": "string",
"enum": [
"Staff Original",
"Rights-Managed",
"Editorial Use Only",
"Royalty-Free",
"Creative Commons BY"
]
},
"channel": {
"type": "string",
"enum": [
"web",
"print",
"social",
"broadcast"
]
},
"rightsStatus": {
"type": "string",
"enum": [
"USABLE",
"VALID",
"EXPIRING_SOON",
"EXPIRED",
"PERPETUAL"
],
"description": "USABLE = publishable today (PERPETUAL or VALID)."
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 50
}
}
}
}get_media_metadataAnswer
Get full metadata for one media asset: photographer, source, license type and notes, allowed channels, expiry, credit requirements, dimensions and which stories use it.
View tool JSON
{
"name": "get_media_metadata",
"kind": "answer",
"impl": "imperative",
"description": "Get full metadata for one media asset: photographer, source, license type and notes, allowed channels, expiry, credit requirements, dimensions and which stories use it.",
"inputSchema": {
"type": "object",
"properties": {
"mediaId": {
"type": "string"
}
},
"required": [
"mediaId"
]
}
}check_media_rightsAnswer
Check licensing/rights for web publication. Pass mediaId for a single asset, or storyId to check every asset attached to a story. Reports expired licenses, channel restrictions and missing credits.
View tool JSON
{
"name": "check_media_rights",
"kind": "answer",
"impl": "imperative",
"description": "Check licensing/rights for web publication. Pass mediaId for a single asset, or storyId to check every asset attached to a story. Reports expired licenses, channel restrictions and missing credits.",
"inputSchema": {
"type": "object",
"properties": {
"mediaId": {
"type": "string",
"description": "Check a single asset."
},
"storyId": {
"type": "string",
"description": "Check all assets attached to this story."
}
},
"required": []
}
}attach_media_to_storyAction
Attach a media asset to a story, with optional caption, alt text and primary (lead image) flag. The first attachment becomes primary automatically. Publication validation requires every attachment to carry alt text.
View tool JSON
{
"name": "attach_media_to_story",
"kind": "act",
"impl": "imperative",
"description": "Attach a media asset to a story, with optional caption, alt text and primary (lead image) flag. The first attachment becomes primary automatically. Publication validation requires every attachment to carry alt text.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"mediaId": {
"type": "string"
},
"caption": {
"type": "string",
"description": "Editorial caption shown with the image."
},
"altText": {
"type": "string",
"description": "Text alternative for screen readers, delivered as the payload's alt attribute. Required before handoff."
},
"isPrimary": {
"type": "boolean",
"description": "Mark as the lead image (demotes other primaries)."
}
},
"required": [
"storyId",
"mediaId"
]
}
}detach_media_from_storyAction
Remove a media attachment from a story. If the removed asset was the primary image, the oldest remaining attachment is promoted.
View tool JSON
{
"name": "detach_media_from_story",
"kind": "act",
"impl": "imperative",
"description": "Remove a media attachment from a story. If the removed asset was the primary image, the oldest remaining attachment is promoted.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"mediaId": {
"type": "string"
}
},
"required": [
"storyId",
"mediaId"
]
}
}replace_story_mediaAction
Replace an attached media asset in one action (e.g. swap an expired-rights image for a valid one). Detaches the old asset and attaches the new one, preserving caption and lead-image status; alt text resets because the image content changed — pass altText to set it in the same call. Returns the updated story.
View tool JSON
{
"name": "replace_story_media",
"kind": "act",
"impl": "imperative",
"description": "Replace an attached media asset in one action (e.g. swap an expired-rights image for a valid one). Detaches the old asset and attaches the new one, preserving caption and lead-image status; alt text resets because the image content changed — pass altText to set it in the same call. Returns the updated story.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"oldMediaId": {
"type": "string",
"description": "Currently attached asset to remove."
},
"newMediaId": {
"type": "string",
"description": "Replacement asset (must not already be attached)."
},
"caption": {
"type": "string",
"description": "Optional new caption; omitted keeps the existing caption."
},
"altText": {
"type": "string",
"description": "Text alternative for the new image; omitted starts without one (handoff will flag it)."
}
},
"required": [
"storyId",
"oldMediaId",
"newMediaId"
]
}
}register_media_assetAction
Register a new media asset in the vault from an external image URL (agent-supplied or wire-service imagery). The image is referenced, not downloaded. Provide full licensing metadata — license type, allowed channels, expiry and credit line — so the Handoff Engine can gate publication on rights. Returns the created asset.
View tool JSON
{
"name": "register_media_asset",
"kind": "act",
"impl": "imperative",
"description": "Register a new media asset in the vault from an external image URL (agent-supplied or wire-service imagery). The image is referenced, not downloaded. Provide full licensing metadata — license type, allowed channels, expiry and credit line — so the Handoff Engine can gate publication on rights. Returns the created asset.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "http(s) URL of the image."
},
"title": {
"type": "string",
"minLength": 3,
"description": "Vault title for the asset."
},
"photographer": {
"type": "string",
"description": "Photographer or originating agency."
},
"source": {
"type": "string",
"description": "Wire service / source name. Defaults to 'External wire'."
},
"description": {
"type": "string",
"description": "What the image shows."
},
"licenseType": {
"type": "string",
"enum": [
"Staff Original",
"Rights-Managed",
"Editorial Use Only",
"Royalty-Free",
"Creative Commons BY"
],
"description": "Defaults to 'Rights-Managed'."
},
"licenseNotes": {
"type": "string",
"description": "Free-form licensing notes/restrictions."
},
"allowedChannels": {
"type": "array",
"items": {
"type": "string",
"enum": [
"web",
"print",
"social",
"broadcast"
]
},
"description": "Channels the license permits. Defaults to ['web']."
},
"expiresAt": {
"type": "string",
"description": "License expiry as ISO date (e.g. 2027-01-31); omit for perpetual rights."
},
"creditRequired": {
"type": "boolean",
"description": "Whether attribution is mandatory (default true)."
},
"creditLine": {
"type": "string",
"description": "The required credit line, e.g. 'Photo: K. Osei / Meridian'."
},
"width": {
"type": "integer",
"description": "Image width in px, if known."
},
"height": {
"type": "integer",
"description": "Image height in px, if known."
}
},
"required": [
"url",
"title",
"photographer"
]
}
}update_story_mediaAction
Update an attachment's editorial fields on a story: caption, alt text (required for publication) and the lead-image flag. Only sent fields are changed; a caption/alt-only update never touches the lead flag.
View tool JSON
{
"name": "update_story_media",
"kind": "act",
"impl": "imperative",
"description": "Update an attachment's editorial fields on a story: caption, alt text (required for publication) and the lead-image flag. Only sent fields are changed; a caption/alt-only update never touches the lead flag.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"mediaId": {
"type": "string",
"description": "The attached media asset id."
},
"caption": {
"type": "string",
"description": "Editorial caption; empty string clears it."
},
"altText": {
"type": "string",
"description": "Text alternative for screen readers; empty string clears it. Publication validation requires one per attachment."
},
"isPrimary": {
"type": "boolean",
"description": "Explicitly set or unset the lead-image flag."
}
},
"required": [
"storyId",
"mediaId"
]
}
}suggest_alt_textAnswer
Get a deterministic alt-text suggestion for a story attachment (derived from the attachment caption, the asset description or the asset title, first sentence, max 140 chars). Use it before update_story_media to write a screen-reader-friendly alt — the same routine the editor-facing 'Suggest' button uses.
View tool JSON
{
"name": "suggest_alt_text",
"kind": "answer",
"impl": "imperative",
"description": "Get a deterministic alt-text suggestion for a story attachment (derived from the attachment caption, the asset description or the asset title, first sentence, max 140 chars). Use it before update_story_media to write a screen-reader-friendly alt — the same routine the editor-facing 'Suggest' button uses.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"mediaId": {
"type": "string",
"description": "The attached media asset id."
}
},
"required": [
"storyId",
"mediaId"
]
}
}renew_media_licensesAction
Extend the license window of one or more dated media assets in a single action (bulk renewal). Sets a new expiry date for every given asset and records an optional renewal note in each asset's license notes. Typical use: renew every EXPIRING_SOON or EXPIRED asset found via search_media before a handoff.
View tool JSON
{
"name": "renew_media_licenses",
"kind": "act",
"impl": "imperative",
"description": "Extend the license window of one or more dated media assets in a single action (bulk renewal). Sets a new expiry date for every given asset and records an optional renewal note in each asset's license notes. Typical use: renew every EXPIRING_SOON or EXPIRED asset found via search_media before a handoff.",
"inputSchema": {
"type": "object",
"properties": {
"mediaIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of the media assets to renew."
},
"expiresAt": {
"type": "string",
"description": "New license expiry date (ISO date string), e.g. '2027-09-02'."
},
"note": {
"type": "string",
"description": "Optional renewal note appended to each asset's license notes."
}
},
"required": [
"mediaIds",
"expiresAt"
]
}
}get_story_historyAnswer
Get the editorial timeline (audit trail) of a story: creation, status changes, edits, media attachments/replacements, deadline changes and handoffs, each with the actor and timestamp.
View tool JSON
{
"name": "get_story_history",
"kind": "answer",
"impl": "imperative",
"description": "Get the editorial timeline (audit trail) of a story: creation, status changes, edits, media attachments/replacements, deadline changes and handoffs, each with the actor and timestamp.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
}
},
"required": [
"storyId"
]
}
}validate_publicationAction
Run full pre-publication validation for a story: approved status, editor assigned, headline/standfirst/body quality, media attached with primary set, licenses valid, web channel allowed, credits present and alt text on every attachment. Returns a checklist with pass/fail per requirement.
View tool JSON
{
"name": "validate_publication",
"kind": "act",
"impl": "imperative",
"description": "Run full pre-publication validation for a story: approved status, editor assigned, headline/standfirst/body quality, media attached with primary set, licenses valid, web channel allowed, credits present and alt text on every attachment. Returns a checklist with pass/fail per requirement.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
}
},
"required": [
"storyId"
]
}
}prepare_web_handoffAction
Generate the web publishing payload for a validated, approved story. Fails with the validation checklist when the story is not ready. Returns the payload plus a field-level diff against the previous prepared-but-undelivered draft (server-side memory), so callers can see exactly what a re-preparation changed. Review the payload before executing the handoff.
View tool JSON
{
"name": "prepare_web_handoff",
"kind": "act",
"impl": "imperative",
"description": "Generate the web publishing payload for a validated, approved story. Fails with the validation checklist when the story is not ready. Returns the payload plus a field-level diff against the previous prepared-but-undelivered draft (server-side memory), so callers can see exactly what a re-preparation changed. Review the payload before executing the handoff.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"requestedBy": {
"type": "string",
"description": "Identifier of the requester, e.g. 'editor-agent'."
}
},
"required": [
"storyId"
]
}
}execute_web_handoffAction
Perform the simulated web handoff: re-validates the story, delivers the payload to the (simulated) web CMS and marks the story Published. Blocked if validation fails.
View tool JSON
{
"name": "execute_web_handoff",
"kind": "act",
"impl": "imperative",
"description": "Perform the simulated web handoff: re-validates the story, delivers the payload to the (simulated) web CMS and marks the story Published. Blocked if validation fails.",
"inputSchema": {
"type": "object",
"properties": {
"storyId": {
"type": "string"
},
"requestedBy": {
"type": "string",
"description": "Identifier of the requester, e.g. 'editor-agent'."
}
},
"required": [
"storyId"
]
}
}