PrismPoster Creator Tools MCP
OfficialProvides platform frame sizes and sourced safe-area calculations for Instagram Reels, including pixel insets and source URLs for the published guidelines.
Provides platform frame specifications and safe-area behavior for TikTok video, explicitly reporting when no fixed safe area is published rather than inventing one.
creator-tools
Zero-dependency TypeScript utilities for video and social creators: aspect-ratio maths, tap tempo, subtitle parsing and conversion, platform frame sizes with sourced safe areas, encoding calculators, colour-palette extraction, GIF encoding, image metadata, and C2PA / AI-provenance detection.
No runtime dependencies. No network calls. Works in the browser, in Node, and in a worker. Every number it returns is one you could check by hand — and where a platform doesn't publish a number, it says so instead of inventing one.
npm install @prismposter/creator-toolsWhy this exists
Most of these calculations are scattered across blog posts that quote each other,
and a surprising number of the quoted figures are wrong. The one that started
this library: every "TikTok safe area" pixel table on the open web is invented.
TikTok publishes an overlay template, not a fixed inset — the occluded zone
varies with frame dimensions, caption length, and which ad formats are running.
There is no correct constant, so this library returns null for it and explains
why, rather than shipping a plausible-looking number.
That's the rule the whole package follows:
Derived numbers are derived. A 9:16 frame at 1080 wide is 1920 tall because that's what the ratio says. Every size in
social-sizesis asserted against its own declared ratio by the test suite.Quoted numbers name their source. Every safe area links the first-party page it was read from.
safeAreaSourceUrl(placement)returns that URL.Unknown is a value, not a blank. A platform that publishes nothing gets an explicit
kind: 'unpublished'with the reason attached.
Related MCP server: media-engine
Modules
aspect-ratio
Ratio arithmetic for frames about to be encoded. Handles non-integral cinema ratios (2.39:1) the same way it handles 16:9.
import {
simplifyRatio, cropToRatio, padToRatio, alignToBlock,
} from '@prismposter/creator-tools/aspect-ratio';
simplifyRatio({ width: 1920, height: 1080 }); // { w: 16, h: 9 }
cropToRatio({ width: 1920, height: 1080 }, { w: 9, h: 16 });
// { result: { width: 608, height: 1080 },
// removed: { top: 0, right: 656, bottom: 0, left: 656 },
// areaKept: 0.3167 }
// Codecs want even dimensions; H.264 chroma subsampling makes an odd
// width an encoder error or a silent rescale.
alignToBlock({ width: 1081, height: 607 }); // { width: 1082, height: 608 }
alignToBlock({ width: 1080, height: 1920 }, 16); // { width: 1088, height: 1920 }An odd crop remainder always goes to the bottom/right edge. That's arbitrary, but it's consistent — splitting it differently per call is how a batch of clips ends up a pixel out of register with each other.
social-sizes
Platform frames and safe areas, with sources.
import {
getPlacement, frameSize, safeAreaPx, safeAreaBox, safeAreaSourceUrl,
} from '@prismposter/creator-tools/social-sizes';
const reels = getPlacement('instagram-reels')!;
frameSize(reels); // { width: 1080, height: 1920 }
safeAreaPx(reels); // { top: 269, bottom: 672, left: 65, right: 65 }
safeAreaBox(reels); // { width: 950, height: 979 }
safeAreaSourceUrl(reels); // Meta's Reels ads-guide page
const tiktok = getPlacement('tiktok-video')!;
safeAreaPx(tiktok); // null — and that is the correct answer
tiktok.safeArea.reason; // explains why no fixed table can be rightMeta publishes Reels and Stories as 14% top, 35% bottom, 6% each side. On a 1080×1920 frame that's 269 / 672 / 65 px. The bottom third is not a typo.
safeAreaPx returning null is meaningful — surface it to your user as "this
platform publishes no fixed safe area". Don't substitute zeros, and don't borrow
another platform's numbers.
subtitles
SRT, WebVTT, and ASS/SSA parsing, conversion, and timing edits. Everything routes
through one neutral Cue shape rather than converting format-to-format: six
formats would otherwise need thirty converters, each a place a rounding rule can
quietly differ.
import { convert, parse, shift, scale, deoverlap }
from '@prismposter/creator-tools/subtitles';
const { output, warnings } = convert(srtText, 'vtt');
// Fix subtitles authored against a different frame rate.
scale(parse(srtText).cues, 23.976 / 25);
// Nudge everything 500ms later; cues pushed before zero clamp to zero.
shift(cues, 500);
// Clip overlaps so only one cue is ever on screen.
deoverlap(cues);Parsing is tolerant: a malformed block produces a warning and is skipped, rather
than costing you the other 899 cues in the file. UTF-8 BOMs and CRLF endings are
handled. VTT NOTE/STYLE blocks and inline tags (<v Roger>, <i>) are
stripped; ASS override blocks ({\an8}) are too.
ASS stores centiseconds, so an ASS round-trip is lossy below 10 ms. convert()
tells you so in warnings rather than letting you discover it later.
tempo
Tap tempo and the beat arithmetic an edit timeline needs.
import { estimateTempo, beatMs, noteMs, beatGrid, snapToBeat }
from '@prismposter/creator-tools/tempo';
estimateTempo(tapTimestamps);
// { bpm: 128.02, taps: 16, spreadMs: 8.4, discarded: 1 }
beatMs(120); // 500
noteMs(120, 'quarter', { triplet: true }); // 333.333
beatGrid(120, 10_000); // [0, 500, 1000, … 10000]
snapToBeat(480, 120); // { timeMs: 500, deltaMs: 20 }The estimator takes the median of a trailing window, not the mean. A tap sequence has two failure modes a mean handles badly: the first taps run late while the user finds the beat, and one missed tap creates an interval at roughly double the true period. Outliers are discarded against the median, because a mean would already have been dragged far enough to keep the bad interval inside tolerance.
spreadMs tells you how much to trust the result — under ~20 ms is a steady
tapper, over ~60 ms means the estimate is soft. beatGrid computes each position
from its index rather than accumulating, so a long sequence cannot drift.
encoding
File size, bitrate, timecode, and frame counts.
import { fileSizeBytes, targetBitrateKbps, bitsPerPixel, toDropFrame }
from '@prismposter/creator-tools/encoding';
fileSizeBytes(60, 8_000); // 60_000_000 bytes
targetBitrateKbps(120, 50_000_000); // kbps to hit a 50 MB cap
bitsPerPixel(1920, 1080, 30, 8_000); // 0.1286
toDropFrame(1_800, 29.97); // '00:01:00;02'Unit convention, stated once: bitrates are decimal (1 Mbps = 1,000,000
bits/s, as every encoder and platform spec means it) and file sizes are binary
(1 MiB = 1,048,576 bytes, as every OS reports it). Mixing the two is why online
calculators disagree by about 5%. formatBytesBinary and formatBytesDecimal
are separate functions so the choice is always explicit.
Drop-frame timecode skips labels, never frames: numbers 00 and 01 are omitted at the start of each minute except every tenth. That's what keeps 29.97 timecode matching wall clock, which non-drop drifts from by ~3.6 s per hour.
palette
Median-cut colour quantisation, plus the contrast maths for putting text on what it returns.
import { extractPalette, toHex, readableTextOn } from '@prismposter/creator-tools/palette';
const swatches = extractPalette(pixels, 5); // pixels: { r, g, b }[]
swatches.map(toHex); // ['#1b2430', '#3f6d8e', ...]
readableTextOn(swatches[0]); // { onColour: 'black' | 'white', ratio: 8.7 }The box split is chosen at the widest gap along the dominant axis, not at the median pixel count. The textbook median split gives every box the same number of pixels, which is exactly wrong for a photograph: a large flat sky gets subdivided repeatedly while a small saturated accent -- the one colour a designer actually wants -- is averaged into its neighbour and disappears. Splitting at the gap keeps it.
When the source has fewer distinct colours than requested slots you get fewer swatches. Padding the result with near-duplicates would be a palette that lies about the image.
provenance
Is there provenance on this file, and does it say the asset was AI-generated?
import { inspectProvenance } from '@prismposter/creator-tools/provenance';
inspectProvenance(bytes);
// { hasC2paManifest: true, hasIptcSourceType: true, hasProvenance: true,
// declaresAiGenerated: true, declaresCapture: false,
// digitalSourceTypes: ['.../digitalsourcetype/trainedAlgorithmicMedia'],
// assertionLabels: ['c2pa.actions.v2', 'c2pa.claim.v2'],
// manifestOffset: 41, signatureVerified: false }Two markings are in circulation and they are constantly confused:
A C2PA manifest -- a cryptographically signed Content Credential in a JUMBF box.
An IPTC digital source type -- a plain XMP/EXIF string with no signature at all, which anyone can write with
exiftool.
A file can carry either, both, or neither. They are reported separately because they carry entirely different weight, and a great many "AI detector" write-ups treat the second as though it were the first.
It does not verify the signature. signatureVerified is always false,
deliberately. Proving a manifest is valid needs the full C2PA trust list and
certificate-chain validation -- that is what
c2patool and c2pa-node are for, and
you should use them when trust is the question. This answers the cheaper question
those are overkill for, and which is often impossible in a serverless runtime that
cannot ship a native binary: is a credential present, and what does it claim?
That is the check you want when triaging an upload queue and routing only the
interesting files on to a real verifier.
A present manifest is not a trusted manifest. Anyone can sign anything with a self-signed certificate, including a lie.
image-metadata
Read what a file says about itself -- and, more usefully, notice when it says nothing.
import { readImageMetadata, isStripped } from '@prismposter/creator-tools/image-metadata';
const meta = readImageMetadata(bytes);
meta.format; // 'jpeg' | 'png' | 'webp' | 'gif' | ...
meta.fields; // parsed EXIF / XMP / text fields
isStripped(meta);Most platforms strip metadata on upload, so an image with none is the normal case
rather than a suspicious one. isStripped exists so you can tell a user that
instead of showing them an empty table.
gif
An animated GIF encoder: global palette, LZW, sub-blocks, the lot.
import { encodeGif, buildGlobalPalette, indexFrame } from '@prismposter/creator-tools/gif';
const palette = buildGlobalPalette(frames, 256);
const bytes = encodeGif({ width, height, palette, frames });GIF allows 256 colours and one global palette across every frame, so the
quantiser matters more than the encoder does -- which is why it shares
palette's median cut rather than carrying its own.
mcp (Model Context Protocol Server)
@prismposter/creator-tools ships a zero-dependency MCP stdio server so AI
assistants (Claude Desktop, Cursor, Windsurf, Cline) can query verified
platform safe areas, aspect-ratio crops, bitrates, and subtitle conversions
without hallucinating pixel dimensions.
Add to claude_desktop_config.json or .cursor/mcp.json:
{
"mcpServers": {
"prismposter-creator-tools": {
"command": "npx",
"args": ["-y", "@prismposter/creator-tools"]
}
}
}Exposed MCP tools:
get_social_media_placement— exact frame size, safe-area insets in pixels, usable box, and first-party documentation URL (instagram-reels,youtube-shorts,tiktok-video, etc.)list_social_media_placements— list all placements (or filter by platform)calculate_aspect_ratio— simplify ratios, align to codec macroblocks, and compute centre-crop / letterbox plansestimate_video_bitrate— encoded file size (bytes, MiB, MB), target bitrate for a size cap, and bits-per-pixel densityconvert_subtitles— parse and convert between SRT, WebVTT, and ASS/SSA with timing shiftestimate_tempo— median-window BPM estimation from tap timestamps and beat durations
Design rules
Pure functions, no side effects, no I/O. Everything is synchronous and deterministic.
Invalid input returns
null, it does not throw. These functions sit behind text inputs where a half-typed value is normal, not exceptional.Rounding happens once, at the boundary. Sizes are whole pixels because that's what an encoder takes.
nullmeans "no answer exists", and is always distinguishable from zero.A wrong type still throws. Rule 2 is about values a user could type. It is not a licence to guess what a caller meant by handing a string to a function that reads bytes.
Development
npm install
npm test # 173 tests
npm run typecheck
npm run buildContributions welcome — see CONTRIBUTING.md. The bar for a new constant is a first-party source; the bar for a new function is a test that would fail without it.
The same maths, as browser tools
Every module here backs a free tool at prismposter.com/tools -- no account, no upload, no email. If you want the answer rather than the function, start there:
Who maintains this
PrismPoster is an AI content workspace -- image, video, remake, character and music studios that share one project, one asset library, and one timeline you can actually finish in.
This library is the boring half of that product: the arithmetic underneath the
studios, extracted because it is genuinely reusable and because a subtitle parser
is not a competitive advantage. provenance exists for the same reason in
reverse -- building AI disclosure into a media product meant learning where the
C2PA tooling is thin, and a dependency-free presence check was the piece that
kept being missing.
License
MIT © PrismLabs OÜ
Available Tools
6 toolscalculate_aspect_ratioA
Simplify pixel dimensions to their aspect ratio, align to codec macroblocks, and optionally compute centre-crop and letterbox/pad plans for a target ratio.
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | Frame width in pixels. | |
| height | Yes | Frame height in pixels. | |
| blockSize | No | Optional codec block alignment (default 2). | |
| targetRatioH | No | Optional target aspect ratio height term (e.g. 16). | |
| targetRatioW | No | Optional target aspect ratio width term (e.g. 9). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description bears the full burden. It discloses the computed capabilities but never states that this is a pure, side-effect-free calculation, nor does it describe the shape of the result (ratio value, alignment result, crop/pad rectangles). For a no-annotation tool this leaves real gaps, even if risk is low.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence with no filler, front-loading the core operation and appending optional capabilities last. It is appropriately sized for the tool's scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With five parameters and no output schema, the description should explain what comes back (reduced ratio, aligned dimensions, crop rectangle, pad rectangle). It covers what is computed but not the return structure, leaving an agent guessing at result fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description loosely maps features to parameters (macroblock alignment -> blockSize, crop/pad plans -> targetRatioW/H) but adds no format, default, or interaction detail beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('simplify') and resource ('pixel dimensions') and enumerates three concrete sub-functions: ratio reduction, codec macroblock alignment, and crop/pad planning. It is unambiguous about what the tool does, though it never states that the primary output is the reduced ratio itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'optionally' signals that the crop/letterbox planning is conditional, which implicitly ties it to the targetRatio parameters. However, there is no explicit guidance on when to use this tool versus doing the math elsewhere, nor any stated preconditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_subtitlesA
Parse and convert subtitle files between SRT, WebVTT (vtt), and SubStation Alpha (ass), with optional timing offset in milliseconds.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes | Raw subtitle file content (SRT, VTT, or ASS). | |
| shiftMs | No | Optional timing offset in milliseconds (positive delays, negative advances). | |
| toFormat | Yes | Target subtitle format. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It confirms the operation is a parse-and-transform and restates the offset semantics, but says nothing about failure behavior on unsupported/malformed input or the shape of the returned content. For a stateless transformation this is a moderate rather than severe gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tightly-packed sentence, front-loaded with the core operation and then the qualifiers. No padding or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Parameters are fully covered by the schema, but there is no output schema and no annotations, so the description should ideally say what the tool returns (converted subtitle text) and how it behaves on invalid input. As written, an agent knows what to send but not what comes back.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters, including the shiftMs sign convention and the toFormat enum, are already fully documented. The description only echoes the offset concept and adds no syntax or constraint detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (parse and convert) and names the three concrete formats, so the purpose is unmistakable. Minor ambiguity: it says 'subtitle files' while the input is raw file content, which could mislead an agent into passing a path, though the schema corrects this.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the operation itself (convert subtitle content between formats with an optional offset). There is no explicit when-to-use/when-not statement, and the listed siblings are unrelated utilities so no alternatives need naming. Adequate but with no real guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
estimate_tempoA
Estimate BPM from tap timestamps in milliseconds, or compute beat duration in ms for a known BPM.
| Name | Required | Description | Default |
|---|---|---|---|
| bpm | No | Optional known BPM to calculate quarter-note beat duration in ms. | |
| timestampsMs | No | Optional list of monotonic tap timestamps in milliseconds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of disclosure. It conveys that this is a pure computation over supplied numbers, but is silent on minimum tap count, precision/rounding, and what is returned if neither or both inputs are supplied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with zero filler, front-loading the primary output (BPM) and following with the reverse calculation. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-optional-parameter pure computation with no output schema, the description covers both modes and their output units. It falls slightly short of complete because the zero-required-parameter design leaves the neither-input case unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented in the schema. The description restates the units and the quarter-note qualification on bpm, but adds no syntax or edge-case meaning beyond the schema (e.g., how many timestamps are required, whether ordering matters). Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Estimate') and two precisely defined computations: BPM from tap timestamps, or beat duration in ms from a known BPM. An agent can tell exactly what this tool produces and in which units, and the siblings listed (placement listings, aspect ratio, bitrate, subtitles) are unrelated enough that no differentiation is needed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'or' construction implicitly documents the two modes and which input selects each: supply timestamps to get BPM, supply bpm to get beat duration. What is missing is an explicit exclusivity/empty-input rule, since both parameters are optional and neither is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
estimate_video_bitrateA
Calculate encoded video file size (bytes, MiB, MB) from duration and bitrate, target bitrate for a file-size cap, and bits-per-pixel density.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | Optional frame rate for bits-per-pixel. | |
| widthPx | No | Optional frame width in pixels for bits-per-pixel. | |
| heightPx | No | Optional frame height in pixels for bits-per-pixel. | |
| totalKbps | No | Total bitrate (video + audio) in kbps (decimal). | |
| durationSec | Yes | Clip duration in seconds. | |
| targetBytes | No | Optional file-size cap in bytes to compute max kbps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. 'Calculate' implies a pure, side-effect-free computation, and naming the three outputs adds useful disclosure, but it never confirms statelessness, error behavior for missing inputs, or output units/keys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; every clause corresponds to a real capability. It is dense to the point of being a run-on, which slightly hurts scannability but wastes nothing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain returns; it names the quantities but not the response shape or what is omitted/returned when optional inputs are absent. For a six-parameter calculator with zero annotations, one more clause on input requirements and output form would close the gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by mapping parameter groups to specific computed results (duration+totalKbps→file size, targetBytes→max kbps, fps/width/height→bits-per-pixel). That linkage is meaning the schema does not provide on its own.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Uses a specific verb ('Calculate') followed by three concrete outputs: encoded file size from duration and bitrate, target bitrate for a file-size cap, and bits-per-pixel density. An agent can immediately tell this is a video bitrate/size calculator rather than the aspect-ratio or tempo calculators among the siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The three described modes imply when each set of parameters is relevant (size from bitrate, kbps from targetBytes, density from fps/width/height), but the description never states this explicitly or says which inputs are required versus optional. No exclusions or alternative tools are named, though with these siblings little differentiation is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_social_media_placementA
Get exact frame dimensions, aspect ratio, first-party safe-area insets (px), usable box, and official documentation URL for a social media placement (e.g. instagram-reels, tiktok-video, youtube-shorts). Optionally pass sourceWidth and sourceHeight to get crop and letterbox plans.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Placement ID (e.g. instagram-reels, instagram-story, instagram-feed-portrait, tiktok-video, youtube-shorts, youtube-video, youtube-channel-banner, linkedin-video, x-video, facebook-reels). | |
| sourceWidth | No | Optional source frame width in pixels to calculate crop/pad fit. | |
| sourceHeight | No | Optional source frame height in pixels to calculate crop/pad fit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It makes clear this is a lookup that returns reference geometry rather than mutating anything, but it never states that it is read-only/non-destructive, nor does it describe behavior for invalid ids, units on source dimensions, or whether the optional plan computation changes the response shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the primary returned fields, followed by the optional-parameter behavior. No filler or restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must convey return values, and it does so concretely (dimensions, ratio, insets in px, usable box, doc URL). It is only mildly incomplete on error/unknown-id behavior and on whether the optional plan fields are additive or replace the base fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds real meaning by saying the two source dimensions are meant to be passed together to produce 'crop and letterbox plans' — the schema only vaguely mentions 'crop/pad fit' per-parameter, so the pairing and the plan output are new information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and a precise resource (a single social media placement), then enumerates the exact fields returned: frame dimensions, aspect ratio, safe-area insets in px, usable box, and doc URL. The example IDs and the singular scope clearly separate it from list_social_media_placements.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear usage condition for the optional parameters: passing sourceWidth and sourceHeight yields crop and letterbox plans. It does not say how to discover a valid id (presumably via the list sibling) or what happens for unknown ids, so it falls short of explicit when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_social_media_placementsA
List all social media video and image placements with dimensions, aspect ratios, safe-area pixel insets, and first-party source URLs. Optionally filter by platform.
| Name | Required | Description | Default |
|---|---|---|---|
| platform | No | Optional platform filter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the burden; 'List' plus the enumerated read-only fields implicitly signals a safe, non-mutating read. It does not mention pagination, result-set size, ordering, or authentication requirements, which are the main unknowns for a listing tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler: the resource and its returned fields come first, followed by the optional filter. Every clause earns its place and nothing is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-required-parameter listing tool with full schema coverage and no output schema, the description covers what the tool returns (dimensions, aspect ratios, safe-area insets, source URLs), which is exactly the information the output schema would otherwise supply. The only gap is sibling differentiation against get_social_media_placement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter has an explicit enum, so the schema already documents platform filtering fully. The description's 'Optionally filter by platform' confirms optionality but adds no meaning beyond the schema's own description, which is the correct baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('social media video and image placements') and enumerates the returned attributes, so the agent knows exactly what comes back. It does not explicitly contrast itself with the singular sibling get_social_media_placement, leaving that distinction to be inferred from the names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Optionally filter by platform' establishes that the filter is discretionary and the unfiltered call is valid, which is genuine usage guidance. However, there is no statement about when to prefer this over get_social_media_placement (single placement retrieval) or any indication of scope limits.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.3.0- First observed
calculate_aspect_ratio - First observed
convert_subtitles - First observed
estimate_tempo - First observed
estimate_video_bitrate - First observed
get_social_media_placement - First observed
list_social_media_placements
TDQS
Scored across 6 tools
get_social_media_placement vs list_social_media_placements is a clear single-item vs collection split, and bitrate/subtitle/tempo tools are distinct. The main overlap is that calculate_aspect_ratio duplicates the crop/letterbox planning already offered inside get_social_media_placement, which could cause an agent to pick the wrong entry point.
Every tool follows a strict snake_case verb_noun pattern (get_, list_, calculate_, estimate_, convert_) with the noun naming the resource. No mixed conventions or vague verbs.
Six tools is well within the comfortable range and each covers a distinct creator-workflow concern (placement specs, ratio math, bitrate math, subtitles, tempo). Nothing feels padded or missing for the stated scope.
Coverage is uneven: placement lookup and ratio/bitrate math form a coherent trio, but there is no tool to validate a given asset against a placement's safe area (only raw numbers are returned), and estimate_tempo is an isolated audio helper that only accepts tap timestamps, not audio analysis. Subtitle conversion is one-way in spirit—no format detection or validation of malformed files is exposed.
Maintenance
Related MCP Connectors
Hosted MCP tools for FFmpeg-style video and audio processing through FFMPEG API.
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
MCP server for the FFmpeg Micro video transcoding API — create, monitor, download transcodes.
FFmpeg Micro - The FFmpeg Api - www.ffmpeg-micro.com Transcode videos from n8n or Make using FFmpeg in the cloud. MCP Server: https://github.com/ffmpeg-micro/ffmpeg-micro-mcp/
Related MCP Servers
- AlicenseAqualityAmaintenanceAn MCP server (stdio + HTTP/SSE) that fetches video transcripts/subtitles via yt-dlp, with pagination for large responses. Supports YouTube, Twitter/X, Instagram, TikTok, Twitch, Vimeo, Facebook, Bilibili, VK, Dailymotion. Whisper fallback — transcribes audio when subtitles are unavailable (local or OpenAI API). Works with Cursor and other MCP host824MIT
- AlicenseNot gradedqualityDmaintenanceMCP server exposing headless ffmpeg operations for video, audio, and image processing via auto-generated typed tools, enabling agentic media file manipulation.GPL 3.0
- AlicenseAqualityCmaintenanceAn MCP server that assembles CapCut International projects by reading and writing local project files, adding captions, subtitles, overlays, and more so editors start with a mostly-done timeline. It includes tools for inspecting projects, restyling captions, importing subtitles, and rendering alpha-channel overlays via Remotion.81MIT
- AlicenseNot gradedqualityAmaintenanceA self-hosted MCP server that connects AI clients to local media-generation backends like ComfyUI and Blender, and provides built-in utilities for video/audio analysis, editing, subtitles, speech, and scene detection via a persistent file cache.1Apache 2.0