Skip to main content
Glama
PrismPoster

PrismPoster Creator Tools MCP

Official
by PrismPoster

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-tools

Why 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-sizes is 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 right

Meta 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:

  1. A C2PA manifest -- a cryptographically signed Content Credential in a JUMBF box.

  2. 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 plans

  • estimate_video_bitrate — encoded file size (bytes, MiB, MB), target bitrate for a size cap, and bits-per-pixel density

  • convert_subtitles — parse and convert between SRT, WebVTT, and ASS/SSA with timing shift

  • estimate_tempo — median-window BPM estimation from tap timestamps and beat durations

Design rules

  1. Pure functions, no side effects, no I/O. Everything is synchronous and deterministic.

  2. Invalid input returns null, it does not throw. These functions sit behind text inputs where a half-typed value is normal, not exceptional.

  3. Rounding happens once, at the boundary. Sizes are whole pixels because that's what an encoder takes.

  4. null means "no answer exists", and is always distinguishable from zero.

  5. 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 build

Contributions 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 tools
calculate_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
widthYesFrame width in pixels.
heightYesFrame height in pixels.
blockSizeNoOptional codec block alignment (default 2).
targetRatioHNoOptional target aspect ratio height term (e.g. 16).
targetRatioWNoOptional target aspect ratio width term (e.g. 9).

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
inputYesRaw subtitle file content (SRT, VTT, or ASS).
shiftMsNoOptional timing offset in milliseconds (positive delays, negative advances).
toFormatYesTarget subtitle format.

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
bpmNoOptional known BPM to calculate quarter-note beat duration in ms.
timestampsMsNoOptional list of monotonic tap timestamps in milliseconds.

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoOptional frame rate for bits-per-pixel.
widthPxNoOptional frame width in pixels for bits-per-pixel.
heightPxNoOptional frame height in pixels for bits-per-pixel.
totalKbpsNoTotal bitrate (video + audio) in kbps (decimal).
durationSecYesClip duration in seconds.
targetBytesNoOptional file-size cap in bytes to compute max kbps.

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesPlacement 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).
sourceWidthNoOptional source frame width in pixels to calculate crop/pad fit.
sourceHeightNoOptional source frame height in pixels to calculate crop/pad fit.

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
platformNoOptional platform filter.

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

  1. 6 tool updatesv0.3.0
    • First observedcalculate_aspect_ratio
    • First observedconvert_subtitles
    • First observedestimate_tempo
    • First observedestimate_video_bitrate
    • First observedget_social_media_placement
    • First observedlist_social_media_placements

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness3/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    An 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 host
    8
    24
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An 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.
    8
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A 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.
    1
    Apache 2.0