{"$schema":"https://verifymcp.io/schemas/trust-report.json","schemaVersion":1,"license":{"name":"CC BY-NC 4.0","url":"https://creativecommons.org/licenses/by-nc/4.0/"},"generatedAt":"2026-11-06T02:17:49.846Z","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp","markdownUrl":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp.md","server":{"slug":"conformlabs-surehand-mcp","name":"Surehand MCP for Adobe After Effects","registryName":"io.github.ConformLabs/surehand-mcp","description":"Your AI works in Adobe After Effects and proves what it did: change reports, pixel proofs, QC.","registryStatus":"active","deletedAt":null,"statusMessage":null,"liveness":"live","publisher":{"class":"unknown","claimed":false}},"component":{"slug":"surehand-mcp","type":"mcpb","identifier":"https://github.com/ConformLabs/surehand-mcp/releases/download/v1.4.1/Surehand-MCP.mcpb","withdrawn":false,"url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp","version":null,"transport":"stdio","scoredAt":"2026-11-05T03:00:56.138Z"},"score":{"total":45,"tier":"low","status":"scored","weekDelta":3,"history":[{"date":"2026-11-05","total":45},{"date":"2026-11-04","total":44},{"date":"2026-11-03","total":44},{"date":"2026-11-02","total":44},{"date":"2026-11-01","total":43},{"date":"2026-10-31","total":43},{"date":"2026-10-30","total":42},{"date":"2026-10-29","total":42},{"date":"2026-10-28","total":41},{"date":"2026-10-27","total":41},{"date":"2026-10-26","total":40},{"date":"2026-10-25","total":40}]},"categories":[{"name":"Supply Chain Security","score":0,"verdict":"unverified","reasons":["No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.","Known CVEs could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none).","Install-script risk not yet assessed.","Dependency health could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none)."],"codes":[{"code":"supplychain.malware_inconclusive","args":{"reason":"ecosystem_unsupported"}},{"code":"cve.inconclusive","args":{"reason":"no_manifest_bundled"}},{"code":"installscript.inconclusive","args":{"reason":"install_surface_unavailable"}},{"code":"dephealth.inconclusive","args":{"reason":"no_manifest_bundled"}}]},{"name":"Provenance & Transparency","score":45,"verdict":"fail","reasons":["Source repository is publicly reachable at the declared URL.","Provenance check failed: no build-provenance attestation is published.","Clear OSI-approved license (MIT).","Actively maintained (last published 13 days ago).","Disclosure check failed: no security disclosure policy was found in the source repository."],"codes":[{"code":"provenance.repo_verified","args":{}},{"code":"provenance.none","args":{}},{"code":"license.osi","args":{"spdx":"MIT"}},{"code":"maintenance.recent","args":{"age_days":"13"}},{"code":"disclosure.absent","args":{}}]},{"name":"Schema Quality & AI Usability","score":75,"verdict":"fail","reasons":["100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).","AI-judged instruction clarity (good).","Context-footprint check failed: tool/resource definitions use about 6103 tokens (~179/item across 34 items; 29 tools + 5 resources), over budget; trim descriptions and params.","Usage-examples check failed: none of the tools include examples."],"codes":[{"code":"schema.descriptions","args":{"pct":"100"}},{"code":"schema.ai_quality","args":{"band":"good"}},{"code":"schema.footprint_heavy","args":{"avg":"179","items":"34","tools":"29","tokens":"6103","resources":"5"}},{"code":"schema.examples_absent","args":{}}]},{"name":"Stability & Change Management","score":37,"verdict":"partial","reasons":["Stability observed for 11 of 30 days with no destabilising changes; credit accrues until the full window elapses."],"codes":[{"code":"stability.building_history","args":{"days":"11"}}]},{"name":"Tool Coverage","score":92,"verdict":"partial","reasons":["100% of tools have a non-trivial description (not blank, and not just the tool's name).","77% of tool parameters carry a description."],"codes":[{"code":"toolquality.descriptions","args":{"pct":"100"}},{"code":"toolquality.param_docs","args":{"pct":"77"}}]},{"name":"Tool Safety","score":100,"verdict":"pass","reasons":["No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.","All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.","An AI judge read all 31 captured unit(s) of tool text and found none that tries to manipulate the model reading it."],"codes":[{"code":"toolsafety.injection_clean","args":{}},{"code":"toolsafety.destructive_declared","args":{"pct":"100","annotated":"1","destructive":"1"}},{"code":"toolsafety.manipulation_clean","args":{"units":"31","judged":"31"}}]},{"name":"Capabilities","score":100,"verdict":"pass","reasons":["Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.","Supports UI / widget rendering."],"codes":[{"code":"protocol.supported","args":{"latest":"2026-07-28","version":"2025-11-25"}},{"code":"cap.ui_supported","args":{}}]}],"inconclusive":["No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.","Known CVEs could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none).","Install-script risk not yet assessed.","Dependency health could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none)."],"malware":[],"components":[{"slug":"surehand-mcp","type":"mcpb","identifier":"https://github.com/ConformLabs/surehand-mcp/releases/download/v1.4.1/Surehand-MCP.mcpb","withdrawn":false,"score":45,"current":true,"url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp","markdownUrl":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp.md"}],"facts":[{"label":"Registry","value":"mcpb"},{"label":"Package","value":"https://github.com/ConformLabs/surehand-mcp/releases/download/v1.4.1/Surehand-MCP.mcpb"},{"label":"Transport","value":"stdio"},{"label":"SHA-256","value":"ee7482e810f3c8dcda25a1862315f1575d652842c9ce999618cb7bfc6153bd71"}],"install":{"available":true,"bundleSha256":"ee7482e810f3c8dcda25a1862315f1575d652842c9ce999618cb7bfc6153bd71"},"tools":[{"name":"ae_run_script","title":"Run ExtendScript","description":"Execute JavaScript inside After Effects (its ExtendScript scripting API) and return the result. This is the most powerful tool: anything in the After Effects scripting API is available (app, app.project, CompItem, layers, properties, render queue, File/Folder, system.callSystem...).\n- The code runs as the body of a function: use `return value` to send data back. Returned AE objects (comps, layers, properties, items) are summarized to JSON automatically.\n- `args` (the JSON you pass in `args`) and `log(...)` are available; log output is returned too.\n- Modern JavaScript is fine: let/const, arrow functions, template strings, destructuring, spread, classes, ?. and ??, for...of, plus map/filter/forEach/find/includes, Object.keys/assign and JSON (converted for AE automatically). Not available: async/await, Promise, Map/Set, generators.\n- The `aemcp` helper library is available: aemcp.findComp(idOrName), aemcp.findLayer(comp, indexOrName), aemcp.findItem(ref), aemcp.resolveProp(layer, 'Transform/Position'), aemcp.color('#ff0000'), aemcp.compInfo(comp, true), aemcp.layerInfo(layer, true), aemcp.propInfo(prop, {depth:2}), aemcp.projectInfo().\n- Collections are 1-based: app.project.item(1), comp.layer(1), prop.property(1).\n- The whole script is one undo step. Errors come back with the failing line and code around it. ae_get_scripting_guide has an API cheat sheet.","inputs":[{"name":"args","type":"object","required":false,"description":"JSON object exposed to the script as `args`."},{"name":"code","type":"string","required":true,"description":"JavaScript source; a function body, use `return` to return data."},{"name":"depth","type":"integer","required":false,"description":"How deep to serialize the returned value (default 4)."},{"name":"report","type":"boolean","required":false,"description":"List what the script changed in the project (default true). Set false for read-only queries on huge projects."},{"name":"timeoutSeconds","type":"number","required":false,"description":"Max seconds to wait for the result (default 120)."},{"name":"transpile","type":"boolean","required":false,"description":"Convert modern JS for ExtendScript (default true). Set false to send the code exactly as written."},{"name":"undoGroup","type":"string","required":false,"description":"Undo step name (default \"Surehand MCP Script\"). Pass \"\" to skip the undo group."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":511},{"name":"ae_run_script_file","title":"Run JSX file","description":"Run an existing .jsx/.jsxbin script file from disk inside After Effects (like File > Scripts > Run Script File). `args` is exposed to the script as the global AEMCP_ARGS. Returns the value of the script's last expression.","inputs":[{"name":"args","type":"object","required":false,"description":null},{"name":"path","type":"string","required":true,"description":"Absolute path to the .jsx / .jsxbin file."},{"name":"timeoutSeconds","type":"number","required":false,"description":null}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":94},{"name":"ae_status","title":"After Effects status","description":"Check the connection to After Effects: app version, OS, open project, active item, permission mode, and whether AE is busy. Lists every running After Effects instance when several are open; pass `instance` (e.g. \"2025\", \"2026\" or a port) to choose which one this session controls. Call this first if unsure AE is reachable.","inputs":[{"name":"instance","type":"string","required":false,"description":"Switch to another running After Effects: \"2026\", \"26.5\", or a bridge port. Omit to keep the current one."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":118},{"name":"ae_render_frame","title":"Preview frame","description":"Render a frame of a composition and return it as an image, so you can SEE the result. Inspection options: zoom into a region, render only some layers, show transparency on a checkerboard or a color, and compare against another time or comp as a difference image (black = identical). Large frames are downscaled to maxSize.","inputs":[{"name":"background","type":"string","required":false,"description":"\"checkerboard\" to show transparency, or a color like \"#808080\" behind the comp."},{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"compareWith","type":"object","required":false,"description":"Difference image against another time and/or comp (black where identical)."},{"name":"layers","type":"array","required":false,"description":"Render only these layers (others are hidden for the render and restored)."},{"name":"maxSize","type":"integer","required":false,"description":"Longest side in pixels of the returned image (default 1280)."},{"name":"outputPath","type":"string","required":false,"description":"Optional absolute path to also save the PNG to."},{"name":"overwrite","type":"boolean","required":false,"description":"Replace an existing file at outputPath (default false: refuse)."},{"name":"region","type":"array","required":false,"description":"Zoom into [x, y, width, height] in comp pixels (scaled up to maxSize, at most 8x)."},{"name":"time","type":"number","required":false,"description":"Time in seconds (default: the comp's current time)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":280},{"name":"ae_render_contact_sheet","title":"Preview animation (contact sheet)","description":"Render several frames of a composition into ONE image (a grid, each cell labelled with its time and frame number), so you can judge motion, timing and easing, not just a single frame. Defaults to 9 frames spread over the work area.","inputs":[{"name":"columns","type":"integer","required":false,"description":"Grid columns (default: square-ish)."},{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"end","type":"number","required":false,"description":"End time in seconds (default: work area end)."},{"name":"frames","type":"integer","required":false,"description":"Number of evenly spaced frames (default 9)."},{"name":"outputPath","type":"string","required":false,"description":"Optional absolute path to also save the PNG to."},{"name":"overwrite","type":"boolean","required":false,"description":"Replace an existing file at outputPath (default false: refuse)."},{"name":"start","type":"number","required":false,"description":"Start time in seconds (default: work area start)."},{"name":"times","type":"array","required":false,"description":"Exact times (seconds) instead of evenly spaced frames."},{"name":"width","type":"integer","required":false,"description":"Width of the returned image in pixels (default 1600)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":224},{"name":"ae_get_project_info","title":"Get project info","description":"Summary of the open project: file path, dirty state, item counts, bit depth, render queue size, active item.","inputs":[],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":35},{"name":"ae_get_comp_info","title":"Get composition info","description":"Composition settings plus a summary of its layers (index, id, name, type, timing, parent, switches). Large comps are paged: use layerOffset/layerLimit (see totalLayers / nextLayerOffset in the result).","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"includeLayers","type":"boolean","required":false,"description":"Default true."},{"name":"layerLimit","type":"integer","required":false,"description":"Max layers to return (default 150)."},{"name":"layerOffset","type":"integer","required":false,"description":"Skip this many layers (default 0)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":127},{"name":"ae_create_comp","title":"Create composition","description":"Create a new composition and (by default) open it in the viewer.","inputs":[{"name":"bgColor","type":null,"required":false,"description":"Color as \"#rrggbb\" or [r,g,b] (0-1 or 0-255)."},{"name":"duration","type":"number","required":false,"description":"Seconds, default 10."},{"name":"folder","type":null,"required":false,"description":"Project item id (number) or exact name."},{"name":"frameRate","type":"number","required":false,"description":"Default 30."},{"name":"height","type":"integer","required":false,"description":"Default 1080."},{"name":"name","type":"string","required":true,"description":null},{"name":"open","type":"boolean","required":false,"description":"Open in viewer (default true)."},{"name":"pixelAspect","type":"number","required":false,"description":"Default 1."},{"name":"width","type":"integer","required":false,"description":"Default 1920."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":142},{"name":"ae_get_layer_info","title":"Get layer info","description":"Full info for one layer: switches, timing, parent, source, transform values, effects, masks count, markers, text, and every animated/expression property.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"layer","type":null,"required":true,"description":"Layer: 1-based index (number) or exact layer name."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":89},{"name":"ae_add_layer","title":"Add layer","description":"Add a layer to a composition: solid, text, shape (empty, use ae_add_shape to draw), null, adjustment, camera, light, or an existing project item (footage/comp).","inputs":[{"name":"allCaps","type":"boolean","required":false,"description":null},{"name":"boxSize","type":"array","required":false,"description":"Paragraph (box) text size [w,h]; omit for point text."},{"name":"color","type":null,"required":false,"description":"Solid/adjustment color, or light color."},{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"direction","type":"string","required":false,"description":"Paragraph direction (AE 24+). Default: text without Hebrew/Arabic characters is set left to right whatever the user's AE type preference is."},{"name":"duration","type":"number","required":false,"description":"Layer duration in seconds (default comp duration)."},{"name":"fauxBold","type":"boolean","required":false,"description":null},{"name":"fauxItalic","type":"boolean","required":false,"description":null},{"name":"fillColor","type":null,"required":false,"description":"Color as \"#rrggbb\" or [r,g,b] (0-1 or 0-255)."},{"name":"font","type":"string","required":false,"description":"PostScript font name, e.g. \"Arial-BoldMT\", \"Helvetica\", \"Montserrat-Bold\"."},{"name":"fontSize","type":"number","required":false,"description":null},{"name":"height","type":"integer","required":false,"description":null},{"name":"item","type":null,"required":false,"description":"For type 'item': project item to add."},{"name":"justification","type":"string","required":false,"description":null},{"name":"leading","type":"number","required":false,"description":null},{"name":"lightType","type":"string","required":false,"description":null},{"name":"moveToIndex","type":"integer","required":false,"description":"Move the new layer to this 1-based index (new layers are added on top)."},{"name":"name","type":"string","required":false,"description":null},{"name":"position","type":"array","required":false,"description":null},{"name":"startTime","type":"number","required":false,"description":null},{"name":"strokeColor","type":null,"required":false,"description":"Color as \"#rrggbb\" or [r,g,b] (0-1 or 0-255)."},{"name":"strokeWidth","type":"number","required":false,"description":null},{"name":"text","type":"string","required":false,"description":"For text layers."},{"name":"threeD","type":"boolean","required":false,"description":null},{"name":"tracking","type":"number","required":false,"description":null},{"name":"type","type":"string","required":true,"description":null},{"name":"width","type":"integer","required":false,"description":"Solid size (default comp size)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":424},{"name":"ae_get_selection","title":"Get selection","description":"What the user has selected: project items, and in the active comp the selected layers and selected properties (with paths).","inputs":[],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":33},{"name":"ae_get_properties","title":"Get properties","description":"Inspect the property tree of a layer (or a sub-group via path): names, match names, values, keyframe counts, expressions. Use this to discover property paths before setting values.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"depth","type":"integer","required":false,"description":"Group depth to expand (default 2)."},{"name":"includeHidden","type":"boolean","required":false,"description":"Include NO_VALUE properties."},{"name":"keyframes","type":"boolean","required":false,"description":"Include keyframe details."},{"name":"layer","type":null,"required":true,"description":"Layer: 1-based index (number) or exact layer name."},{"name":"path","type":null,"required":false,"description":"Start at this group/property (default: the whole layer)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":148},{"name":"ae_find_properties","title":"Find properties","description":"Search every layer of a comp (or one layer) for properties whose name or match name contains the query, e.g. \"opacity\", \"blur\", \"Source Text\", \"ADBE Fill Color\". Returns ready-to-use paths. Filter to animated or expression properties.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"layer","type":null,"required":false,"description":"Layer: 1-based index (number) or exact layer name."},{"name":"limit","type":"integer","required":false,"description":"Default 100."},{"name":"onlyAnimated","type":"boolean","required":false,"description":"Only properties with keyframes."},{"name":"onlyExpressions","type":"boolean","required":false,"description":"Only properties with an expression."},{"name":"query","type":"string","required":false,"description":"Case-insensitive text to match in the property name or match name. Omit to list all matches of the filters."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":175},{"name":"ae_set_property","title":"Set property value","description":"Set the value of any property (transform, effect parameter, shape attribute, text...). If `time` is given (or the property already has keyframes) a keyframe is set at that time. Examples: path \"Transform/Opacity\" value 50; \"Transform/Position\" [960,540]; \"Transform/Scale\" [50,50]; \"Effects/Fill/Color\" \"#ff0000\".","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"layer","type":null,"required":true,"description":"Layer: 1-based index (number) or exact layer name."},{"name":"path","type":null,"required":true,"description":"Property path from the layer, \"/\"-separated display names or match names, e.g. \"Transform/Position\", \"Effects/Gaussian Blur/Blurriness\", \"ADBE Transform Group/ADBE Opacity\", \"Contents/Rectangle 1/Fil…"},{"name":"time","type":"number","required":false,"description":null},{"name":"value","type":null,"required":true,"description":"Value: number, array ([x,y] / [x,y,z] / color), string for text, or object for text style / shape path."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":245},{"name":"ae_set_keyframes","title":"Set keyframes","description":"Create keyframes on a property in one call, with optional interpolation (linear/bezier/hold) and temporal easing. Place keys by time (seconds) or frame (whole frames). Example: path \"Transform/Position\", keyframes [{time:0,value:[0,540]},{frame:24,value:[960,540],easeIn:80}].","inputs":[{"name":"clearExisting","type":"boolean","required":false,"description":"Remove existing keyframes first."},{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"easyEase","type":"boolean","required":false,"description":"Apply easy ease (33%) to all new keyframes that don't specify easing."},{"name":"keyframes","type":"array","required":true,"description":null},{"name":"layer","type":null,"required":true,"description":"Layer: 1-based index (number) or exact layer name."},{"name":"path","type":null,"required":true,"description":"Property path from the layer, \"/\"-separated display names or match names, e.g. \"Transform/Position\", \"Effects/Gaussian Blur/Blurriness\", \"ADBE Transform Group/ADBE Opacity\", \"Contents/Rectangle 1/Fil…"}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":236},{"name":"ae_set_expression","title":"Set expression","description":"Set (or clear with an empty string) an expression on a property. Returns any expression error AE reports.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"enabled","type":"boolean","required":false,"description":null},{"name":"expression","type":"string","required":true,"description":null},{"name":"layer","type":null,"required":true,"description":"Layer: 1-based index (number) or exact layer name."},{"name":"path","type":null,"required":true,"description":"Property path from the layer, \"/\"-separated display names or match names, e.g. \"Transform/Position\", \"Effects/Gaussian Blur/Blurriness\", \"ADBE Transform Group/ADBE Opacity\", \"Contents/Rectangle 1/Fil…"}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":154},{"name":"ae_get_effect_params","title":"Inspect effect parameters","description":"List an effect's parameters (names, match names, value types, defaults, min/max) WITHOUT changing your layers, so you know the exact parameter names for ae_apply_effect / ae_set_effect_params. Pass comp+layer to inspect an effect already applied (current values).","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"effect","type":null,"required":true,"description":"Match name (e.g. \"ADBE Glo2\") or display name (\"Glow\"); with comp+layer, also an index in the stack."},{"name":"layer","type":null,"required":false,"description":"Inspect the effect on this layer instead of a fresh default instance."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":145},{"name":"ae_apply_effect","title":"Apply effect","description":"Apply an effect to a layer by match name (preferred, e.g. \"ADBE Gaussian Blur 2\", \"ADBE Fill\", \"ADBE Glo2\", \"ADBE Drop Shadow\") or display name, optionally setting parameters. Returns the effect's parameters.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"effect","type":"string","required":true,"description":null},{"name":"layer","type":null,"required":true,"description":"Layer: 1-based index (number) or exact layer name."},{"name":"name","type":"string","required":false,"description":"Rename the effect instance."},{"name":"params","type":"object","required":false,"description":"Effect parameters by display name or match name, e.g. {\"Blurriness\": 20, \"Repeat Edge Pixels\": true} or {\"Color\": \"#ff0000\"}."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":171},{"name":"ae_add_shape","title":"Add shape","description":"Draw a shape (rectangle, ellipse, polygon, star, or custom path) with fill and/or stroke, on a new shape layer or an existing one. Positions are relative to the layer (new layers are centered in the comp).","inputs":[{"name":"closed","type":"boolean","required":false,"description":null},{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"fill","type":null,"required":false,"description":"Fill color; omit for no fill (unless no stroke either: defaults to white)."},{"name":"inTangents","type":"array","required":false,"description":null},{"name":"innerRadius","type":"number","required":false,"description":null},{"name":"layer","type":null,"required":false,"description":"Existing shape layer; omit to create a new one."},{"name":"name","type":"string","required":false,"description":null},{"name":"outTangents","type":"array","required":false,"description":null},{"name":"outerRadius","type":"number","required":false,"description":null},{"name":"points","type":"number","required":false,"description":"Polygon/star points."},{"name":"position","type":"array","required":false,"description":"Shape position within the layer (default [0,0])."},{"name":"roundness","type":"number","required":false,"description":"Rectangle corner roundness."},{"name":"shape","type":"string","required":true,"description":null},{"name":"size","type":"array","required":false,"description":"[w,h] for rectangle/ellipse (default 400x400)."},{"name":"stroke","type":null,"required":false,"description":"Color as \"#rrggbb\" or [r,g,b] (0-1 or 0-255)."},{"name":"strokeWidth","type":"number","required":false,"description":null},{"name":"vertices","type":"array","required":false,"description":"For 'path': [[x,y],...]."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":287},{"name":"ae_undo","title":"Undo","description":"Undo the last action(s) in After Effects (Edit > Undo).","inputs":[{"name":"steps","type":"integer","required":false,"description":null}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":30},{"name":"ae_get_layer_bounds","title":"Layer bounds","description":"Exact on-screen bounding boxes of layers in composition pixels at a time, after all transforms, parenting, 3D and the active camera (via AE's own toComp()). Also reports whether each layer is visible at that time, fully/partly/not in frame, and inside action-safe (5% margin) and title-safe (10% margin). Use it to check alignment, spacing, overlaps and safe areas with numbers.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"frame","type":"integer","required":false,"description":"Whole frame number from the comp's start (frame 0 = time 0), instead of time."},{"name":"includeExtents","type":"boolean","required":false,"description":"Include stroke widths, effects and other extents (default false = content box)."},{"name":"layers","type":"array","required":false,"description":"Layers to measure (default: all layers, up to 300)."},{"name":"selectedOnly","type":"boolean","required":false,"description":"Measure only the layers selected in After Effects."},{"name":"time","type":"number","required":false,"description":"Seconds (default: the comp's current time)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":227},{"name":"ae_get_comp_map","title":"Composition structure map","description":"Overview of how a composition is built: the tree of nested precomps (with how many times each is used), parenting chains, track mattes, and which layers/comps each expression references. Use it to understand an unfamiliar project before editing.","inputs":[{"name":"comp","type":null,"required":false,"description":"Composition: item id (number) or exact name. Omit (or \"active\") for the active/open composition."},{"name":"depth","type":"integer","required":false,"description":"How deep to follow nested precomps (default 4)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":107},{"name":"ae_batch","title":"Batch edits","description":"Run many steps in ONE call: each step is a tool with its arguments (any project/comp/layer/property/keyframe/effect/text/footage tool) or {tool: \"ae_run_script\", args: {code}}. All steps form a single undo step and return one change report. Atomic by default: if any step fails, everything is undone and you get the error of the failing step. Use it for repetitive or multi-part edits (e.g. style 30 layers, build a scene) to save round trips.","inputs":[{"name":"atomic","type":"boolean","required":false,"description":"Undo everything if a step fails (default true). false = keep successful steps and continue."},{"name":"checkpoint","type":"boolean","required":false,"description":"Save a project checkpoint before running (see ae_checkpoint)."},{"name":"name","type":"string","required":false,"description":"Undo step name shown in After Effects (default \"Surehand MCP Batch\")."},{"name":"steps","type":"array","required":true,"description":null},{"name":"verbose","type":"boolean","required":false,"description":"Return each step's full result (default: short summaries)."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":204},{"name":"ae_checkpoint","title":"Project checkpoints","description":"Safety copies of the project: save (saves the open project, then keeps a timestamped copy), list the checkpoints of this project, or restore one (opens it as a NEW file next to the original; neither the original nor an earlier restore is ever overwritten). Use before large or risky changes.","inputs":[{"name":"action","type":"string","required":true,"description":null},{"name":"discardChanges","type":"boolean","required":false,"description":"Restore even if the open project has unsaved changes (they are discarded)."},{"name":"id","type":"string","required":false,"description":"Checkpoint id to restore (from list)."},{"name":"label","type":"string","required":false,"description":"Short label for a new checkpoint."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":126},{"name":"ae_list_scripts","title":"List scripts","description":"List the user's own After Effects scripts: AE's Scripts folder (and ScriptUI Panels) plus folders configured as \"scriptFolders\" in ~/.surehand/ae/config.json, with each script's description from its header comment. Run one with ae_run_script_file.","inputs":[{"name":"nameContains","type":"string","required":false,"description":null}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":70},{"name":"ae_prove_identical","title":"Prove the render is unchanged","description":"Prove a structural change (un-precompose, bake expressions, reorder effects, simplify a rig) left the render unchanged, or show which frames and areas differ. capture: render reference frames (default: active comp, 5 frames over the work area), returns a proof id. compare: render them again and compare pixel by pixel (verdict, per-frame max difference, changed pixels, ΔE, area, difference image). run: capture, ae_batch steps, compare, in one call. For un-precompose, prove the parent comp. Only the sampled video frames are compared (alpha included; not audio, the comp background color or times between samples; 32 bpc values above 1.0 are clamped).","inputs":[{"name":"action","type":"string","required":true,"description":null},{"name":"atomic","type":"boolean","required":false,"description":"run: as ae_batch (default true: a failed step undoes everything, and nothing is compared)."},{"name":"checkpoint","type":"boolean","required":false,"description":"run: save a project checkpoint before the edits."},{"name":"comps","type":"array","required":false,"description":"capture/run: comps to prove (item id or exact name; default the active comp)."},{"name":"frames","type":"integer","required":false,"description":"capture/run: number of frames spread over each comp's work area (default 5)."},{"name":"id","type":"string","required":false,"description":"compare: the proof id from capture (default the latest proof)."},{"name":"maxSize","type":"integer","required":false,"description":"capture/run: longest rendered side in pixels (default 1920; larger comps are scaled down)."},{"name":"name","type":"string","required":false,"description":"run: undo step name."},{"name":"steps","type":"array","required":false,"description":"run: the edits, as ae_batch steps."},{"name":"times","type":"array","required":false,"description":"capture/run: exact times in seconds (snapped to frames) instead of evenly spaced frames."},{"name":"tolerance","type":"number","required":false,"description":"compare/run: allowed difference per channel, 0-255 (default 0.5: less than one 8-bit step, so only 16/32 bpc rounding is allowed; 0 = bit-identical)."},{"name":"verbose","type":"boolean","required":false,"description":"run: full result of each step."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":422},{"name":"ae_get_scripting_guide","title":"ExtendScript guide","description":"Returns the After Effects ExtendScript cheat sheet (ES3 rules, helpers, common match names). Read before writing complex ae_run_script code.","inputs":[],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":40},{"name":"ae_tools","title":"More tools","description":"Discover every After Effects tool, including ones not loaded in this chat: list them by category (one line each), or describe chosen tools (full parameters). Then run any of them with ae_call. Categories: status & app, scripts, project, comps, layers, properties & keyframes, effects, shapes & masks, text, 3D, audio, footage, files & export, checks, see & measure, essential graphics, render.","inputs":[{"name":"category","type":"string","required":false,"description":"Only list this category."},{"name":"describe","type":"array","required":false,"description":"Tool names to get full parameter details for."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":124},{"name":"ae_call","title":"Run any tool","description":"Run any After Effects tool by name with its arguments, e.g. tools listed by ae_tools that aren't loaded in this chat. Same validation, permissions, change report and activity log as calling the tool directly. Get the parameters with ae_tools {describe: [name]}.","inputs":[{"name":"args","type":"object","required":false,"description":"The tool's arguments."},{"name":"tool","type":"string","required":true,"description":"Tool name, e.g. \"ae_set_camera\"."}],"outputs":[],"hasOutputSchema":false,"hasExamples":false,"tokenEstimate":91}],"toolsTruncatedAtCapture":false,"diagnostics":{"capturedAt":"2026-11-05T03:00:56.000Z","track":"package","endpoint":null,"declaredUrl":null,"truncated":false,"tls":null,"dnssec":null,"auth":null,"httpsRedirect":null,"transports":[],"provenance":{"outcome":"none","label":"No attestation","reason":"no_attestation","reasonLabel":"No attestation published","discovery":null,"discoveryLabel":null,"sourceRepo":null,"attestationSkipped":null,"attestationSkippedLabel":null},"installScripts":[],"installScriptsTotal":null,"vulnerabilities":[],"vulnerabilitiesTotal":null,"dependencies":null},"mismatches":[],"changelog":{"trackingSince":"2026-10-25","recent":[{"id":"chg_01a1a9a6-fedf-7bb2-933c-9582af637f89","kind":"score.total_changed","summary":"Trust score (44 → 45)","materiality":"functional","direction":"improvement","scoreDelta":1,"occurredOn":"2026-11-05","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a1a9a6-fedf-7bb2-933c-9582af637f89"},{"id":"chg_01a19a34-517a-715a-8ea0-c8f2ab5b617d","kind":"score.total_changed","summary":"Trust score (43 → 44)","materiality":"functional","direction":"improvement","scoreDelta":1,"occurredOn":"2026-11-02","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a19a34-517a-715a-8ea0-c8f2ab5b617d"},{"id":"chg_01a18fe7-8eac-7d17-bd42-34e620d0dda6","kind":"score.total_changed","summary":"Trust score (42 → 43)","materiality":"functional","direction":"improvement","scoreDelta":1,"occurredOn":"2026-10-31","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a18fe7-8eac-7d17-bd42-34e620d0dda6"},{"id":"chg_01a1859a-f7e1-783b-a2f2-ce51c7799f46","kind":"score.total_changed","summary":"Trust score (41 → 42)","materiality":"functional","direction":"improvement","scoreDelta":1,"occurredOn":"2026-10-29","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a1859a-f7e1-783b-a2f2-ce51c7799f46"},{"id":"chg_01a17b4d-80c1-7d2f-ae41-643f95144ccf","kind":"score.total_changed","summary":"Trust score (40 → 41)","materiality":"functional","direction":"improvement","scoreDelta":1,"occurredOn":"2026-10-27","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a17b4d-80c1-7d2f-ae41-643f95144ccf"},{"id":"chg_01a172f4-f49d-7033-8605-f5184d2c84f1","kind":"score.first_scored","summary":"First indexed and scored","materiality":"functional","direction":"neutral","scoreDelta":null,"occurredOn":"2026-10-25","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a172f4-f49d-7033-8605-f5184d2c84f1"},{"id":"chg_01a172ee-d339-7ef1-b105-f7e94a2fb9ce","kind":"score.first_scored","summary":"First indexed and scored","materiality":"functional","direction":"neutral","scoreDelta":null,"occurredOn":"2026-10-25","url":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp#chg-chg_01a172ee-d339-7ef1-b105-f7e94a2fb9ce"}],"truncated":false,"feedUrl":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp/changelog.json"},"links":{"html":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp","markdown":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp.md","changelogJson":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp/changelog.json","changelogRss":"https://verifymcp.io/servers/conformlabs-surehand-mcp/surehand-mcp.xml","external":[{"label":"Repository","href":"https://github.com/ConformLabs/surehand-mcp"},{"label":"Website","href":"https://conformlabs.co/surehand/"}]}}