Slides and Shapes¶
Reference for the slide tool (add-blank, get-count, delete, duplicate, move-to, set-background-color, get-background-color, visibility, sections, comments, import) and the shape tool (add-rectangle, add-text-box, add-text-effect, add-auto-shape, add-line, add-connector, add-attached-connector, get-count, delete, set-position, set-size, align, distribute, merge, plus the fill/line/rotation/flip/z-order/shadow/glow/ reflection/soft-edge/bevel/group/name/alt-text/hyperlink formatting actions below).
Slide Actions¶
| Tool | Action | Parameters | Notes |
|---|---|---|---|
slide | add-blank | presentation_session_id | Adds a blank slide at the end. No insert-at-index. |
slide | get-count | presentation_session_id | Returns current slide count (slideCount). Call before/after mutations to confirm state. |
slide | inspect | presentation_session_id, optional max_slides (default 20, max 100), optional max_text_chars_per_slide (default 500, max 2000) | Returns a bounded overview of slide names, layouts, shape counts, and text previews. It scans at most 200 shapes per slide; each preview reports whether text was truncated by its character or scan limit. omittedSlideCount reports slides beyond the limit. Set the text limit to 0 for metadata only. |
slide | delete | presentation_session_id, slide_index (1-based) | Removes the slide; later slides shift down by one index. |
slide | duplicate | presentation_session_id, slide_index | Inserts a copy of the slide immediately after the source. Returns the duplicate's new slideIndex and total slideCount. |
slide | move-to | presentation_session_id, slide_index, to_position | Moves a slide to a new 1-based position, renumbering the rest. Returns the slide's new slideIndex. |
slide | set-background-color | presentation_session_id, slide_index, red, green, blue | Sets a solid per-slide background color, overriding the slide master for that slide only. Returns colorRgb and followsMasterBackground: false. |
slide | get-background-color | presentation_session_id, slide_index | Returns the slide's background colorRgb and followsMasterBackground. |
slide | set-gradient-background | presentation_session_id, slide_index, red1, green1, blue1, red2, green2, blue2, gradient_style?, gradient_variant? | Sets a two-color gradient per-slide background, overriding the slide master for that slide only. gradient_style is one of msoGradientHorizontal (default), msoGradientVertical, msoGradientDiagonalUp, msoGradientDiagonalDown, msoGradientFromCorner, msoGradientFromTitle, msoGradientFromCenter. gradient_variant is 1-4 (default 1). |
slide | get-gradient-background | presentation_session_id, slide_index | Returns colorRgb, colorRgb2, gradientStyleName, gradientVariant. Fails if the slide's current background fill is solid (not a gradient). |
slide | add-section | presentation_session_id, section_index, section_name (optional) | Adds a new section before section_index (pass sectionCount + 1 to append). Returns the new sectionIndex and total sectionCount. |
slide | rename-section | presentation_session_id, section_index, section_name | Renames an existing section. |
slide | delete-section | presentation_session_id, section_index, delete_slides (optional, default false) | Deletes a section. If delete_slides is true, its slides are deleted too; otherwise they're kept and merged into a neighboring section. PowerPoint disallows deleting section 1 unless delete_slides is true — delete/reorder other sections first if you need to remove the first one's boundary without losing its slides. |
slide | get-section-count | presentation_session_id | Returns the current number of sections (sectionCount, 0 if none exist). |
slide | get-section-name | presentation_session_id, section_index | Returns a section's name (sectionName). |
slide | list-comments | presentation_session_id, slide_index | Lists legacy comments exposed by native PowerPoint COM. Modern threaded comments are not available through this API. |
slide | add-comment | presentation_session_id, slide_index, author, initials, text, optional left/top | Adds a legacy comment. PowerPoint may replace author details with the signed-in Office identity. |
slide | delete-comment | presentation_session_id, slide_index, comment_index | Deletes one legacy comment by 1-based index. |
slide | clear-comments | presentation_session_id, slide_index | Deletes all legacy comments on the slide. |
slide | set-hidden | presentation_session_id, slide_index, hidden | Excludes the slide from slide-show playback when hidden is true; the slide remains in the deck and editable. Returns hidden. |
slide | set-display-master-shapes | presentation_session_id, slide_index, display | Shows or hides shapes inherited from the slide master. This does not control headers, footers, or the slide background. Returns displaysMasterShapes. |
slide | import-from-file | presentation_session_id, source_file_path, destination_slide_index, optional source range | Inserts an inclusive 1-based source range after the destination slide; it never replaces destination slides. |
Slides always append at the end via add-blank — there is no "insert blank at position N" action; use add-blank then move-to if you need a blank slide inserted mid-deck. See deck-builder.md for planning multi-slide order.
MCP clients can use slide_read for the explicitly read-only slide actions, including inspect, get-count, and background, section, comment, and tag queries. The original slide tool remains available unchanged. pptcli continues to use pptcli slide <action>.
Sections¶
Sections group contiguous ranges of slides for organizational purposes (visible in PowerPoint's slide thumbnail panel) — they do not affect slide content or rendering. A slide's section membership is purely positional (determined by where the slide sits between section boundaries), so reordering slides with move-to can move them into a different section.
slide(action: "add-section", presentation_session_id: ..., section_index: 1, section_name: "Introduction")
slide(action: "add-section", presentation_session_id: ..., section_index: 2, section_name: "Deep Dive")
→ splits the deck into two sections at the current slide count boundary
slide(action: "get-section-count", presentation_session_id: ...) → sectionCount: 2
slide(action: "rename-section", presentation_session_id: ..., section_index: 2, section_name: "Details")
Shape Actions¶
| Tool | Action | Parameters | Notes |
|---|---|---|---|
shape | add-rectangle | presentation_session_id, slide_index, left, top, width, height | Plain rectangle, no fill/line color parameters — style comes from PowerPoint's theme default. Returns shapeIndex. |
shape | add-text-box | presentation_session_id, slide_index, left, top, width, height, text | Creates the text box AND sets its initial text in one call. Returns shapeIndex. |
shape | add-text-effect | presentation_session_id, slide_index, preset_effect, text, font_name, font_size, left, top, optional bold/italic | Adds editable WordArt using msoTextEffect1 through msoTextEffect50. PowerPoint determines the shape's width and height. Returns shapeIndex and shapeCount. |
shape | add-auto-shape | presentation_session_id, slide_index, shape_type, left, top, width, height | Adds any non-rectangle built-in shape (oval, diamond, arrow, star bracket, etc.) by its MsoAutoShapeType name. Returns shapeIndex and echoes shapeTypeName. See "Auto Shape Types" below for the supported name list. |
shape | add-line | presentation_session_id, slide_index, begin_x, begin_y, end_x, end_y | Straight line between two points. Returns shapeIndex and echoes beginX/beginY/endX/endY. |
shape | add-connector | presentation_session_id, slide_index, connector_type, begin_x, begin_y, end_x, end_y | Adds a connector shape (msoConnectorStraight, msoConnectorElbow, or msoConnectorCurve) between two points. Free-floating — not glued to other shapes. Returns shapeIndex and echoes connectorTypeName. |
shape | add-attached-connector | presentation_session_id, slide_index, connector_type, begin_shape_index, begin_connection_site, end_shape_index, end_connection_site | Adds a connector whose endpoints stay attached to connection sites on two existing shapes, so it follows them when they move. Shape indexes and connection sites are 1-based; each site must be within the selected shape's ConnectionSiteCount. Returns shapeIndex and echoes connectorTypeName. |
shape | get-count | presentation_session_id, slide_index | Number of shapes currently on the slide (shapeCount). |
shape | delete | presentation_session_id, slide_index, shape_index (1-based) | Removes one shape; later shapes on that slide shift down by one index. |
shape | set-position | presentation_session_id, slide_index, shape_index, left, top | Moves an existing shape. |
shape | set-size | presentation_session_id, slide_index, shape_index, width, height | Resizes an existing shape. |
shape | list-placeholders | presentation_session_id, slide_index | Returns each native placeholder's shape index, type, name, bounds, alt text, and content state. |
shape | set-placeholder-text | presentation_session_id, slide_index, shape_index, text | Replaces text in a native text placeholder; rejects ordinary shapes. |
shape | set-placeholder-image | presentation_session_id, slide_index, shape_index, image_path | Places an image in a compatible picture/content placeholder while preserving its native geometry and metadata. |
shape | get-link-info | presentation_session_id, slide_index, shape_index | Returns a linked picture's full source path; linkAutoUpdate is null because some PowerPoint builds reject reads of that typed property. |
shape | update-link | presentation_session_id, slide_index, shape_index | Refreshes a linked picture immediately from its current source file. |
shape | break-link | presentation_session_id, slide_index, shape_index | Permanently removes the file link while retaining the current picture. |
shape | set-link-auto-update | presentation_session_id, slide_index, shape_index, auto_update | Enables or disables automatic refresh; PowerPoint errors propagate to the MCP or CLI boundary. |
All position/size values are points (see deck-builder.md for the 960×540pt 16:9 reference).
Align and Distribute¶
Use shape(action: "align", ..., shape_indexes: [3, 1, 2], align_cmd: "msoAlignTops") to align a selection. align_cmd accepts msoAlignLefts, msoAlignCenters, msoAlignRights, msoAlignTops, msoAlignMiddles, or msoAlignBottoms. Names are case-insensitive; numeric enum values are rejected.
By default, alignment uses the selection's original bounding rectangle and needs two shapes. Set relative_to_slide: true to use slide bounds; this also allows one shape. Array order does not choose an anchor shape.
Use shape(action: "distribute", ..., shape_indexes: [3, 1, 2], distribute_cmd: "msoDistributeHorizontally") for equal horizontal edge gaps, or msoDistributeVertically for vertical gaps. At least three shapes are required. By default the outer shapes retain the selection's original span. With relative_to_slide: true, equal gaps include the margins at both slide edges. This spaces edges, not centers: unequal-sized shapes have unequal center distances.
Both actions require presentation_session_id, slide_index, and distinct 1-based top-level shape_indexes. Invalid indexes, duplicates, or commands fail before any movement. The result returns the total slide shapeCount. No shapes are resized or regrouped. Groups are treated as whole top-level shapes; rotated shapes use native PowerPoint geometry. This is not collision avoidance: insufficient space can produce overlap. Export the slide to verify the result after arranging it.
Shape Formatting Actions¶
| Tool | Action | Parameters | Notes |
|---|---|---|---|
shape | set-fill | presentation_session_id, slide_index, shape_index, red, green, blue (each 0-255) | Sets a solid fill color. Returns colorRgb. |
shape | get-fill | presentation_session_id, slide_index, shape_index | Returns the current fill color as colorRgb. |
shape | set-line | presentation_session_id, slide_index, shape_index, plus optional red/green/blue, weight, dash_style, visible | All formatting params are optional and independently applied — pass only what you want to change. red/green/blue must be passed together to set the line color. dash_style is an MsoLineDashStyle name (see below). Returns the shape's full line state (colorRgb, lineWeight, dashStyleName, visible). |
shape | get-line | presentation_session_id, slide_index, shape_index | Returns the current line color, weight, dash style, and visibility. |
shape | copy-formatting | presentation_session_id, slide_index, source_shape_index, target_shape_index | Applies PowerPoint's native Format Painter from the source shape to the target shape. Copies appearance without replacing the target's content, position, or size. Both shapes must be on the same slide. Returns the target shapeIndex. |
shape | duplicate | presentation_session_id, slide_index, shape_index | Creates an identical, independently editable copy of a shape on the same slide, immediately in front of the original in z-order. Returns the new shape's shapeIndex. |
shape | copy-to-slide | presentation_session_id, slide_index, shape_index, target_slide_index | Copies a shape to another slide in the same presentation via PowerPoint's native copy/paste, producing an independently editable copy. Both slides must be in the same open presentation and target_slide_index must differ from slide_index (use duplicate for a same-slide copy). Uses the shared Windows clipboard: concurrent calls made through this server are serialized automatically, but this cannot prevent an unrelated application or a manual copy/paste on the same desktop session from replacing the clipboard contents in between — a best-effort check fails the operation if paste did not produce exactly one shape. Returns the new shape's shapeIndex on target_slide_index. |
shape | set-rotation | presentation_session_id, slide_index, shape_index, degrees | Sets rotation in degrees clockwise from upright. Returns rotation. |
shape | get-rotation | presentation_session_id, slide_index, shape_index | Returns the current rotation in degrees. |
shape | set-3d-rotation | presentation_session_id, slide_index, shape_index, optional rotation_x/rotation_y/rotation_z | Sets one or more axes of 3D rotation. At least one axis is required; omitted axes remain unchanged. X and Y must be between -90 and 90 degrees. Z rotates the shape around its Z axis and is tracked separately from the shape's 2D rotation. Returns all three axes. |
shape | get-3d-rotation | presentation_session_id, slide_index, shape_index | Returns rotationX, rotationY and rotationZ in degrees. |
shape | flip | presentation_session_id, slide_index, shape_index, direction (horizontal or vertical) | Flips the shape in place. Returns flipDirection. |
shape | set-z-order | presentation_session_id, slide_index, shape_index, z_order_command | Moves the shape's stacking position. z_order_command is one of bring-to-front, send-to-back, bring-forward, send-backward. Returns zOrderCommand. |
shape | set-shadow | presentation_session_id, slide_index, shape_index, visible, plus optional red/green/blue, transparency (0-1), blur, offset_x, offset_y (points) | Turns the shape's drop shadow on/off. When visible is true, the optional color/formatting parameters set an "offset" style shadow — any omitted parameter uses PowerPoint's default. Returns visible and, when visible, colorRgb, transparency, blur, offsetX, offsetY. |
shape | get-shadow | presentation_session_id, slide_index, shape_index | Returns visible and, if visible, colorRgb/transparency/blur/offsetX/offsetY. |
shape | set-glow | presentation_session_id, slide_index, shape_index, red, green, blue, radius, transparency (optional, 0-1) | Applies a glow effect. A radius of 0 removes the glow. Returns colorRgb, glowRadius, transparency. |
shape | get-glow | presentation_session_id, slide_index, shape_index | Returns the shape's current glow colorRgb, glowRadius, transparency. |
shape | set-reflection | presentation_session_id, slide_index, shape_index, visible, plus optional transparency (0-1), size (% of shape height), blur | Turns a reflection effect on/off. Returns visible and, when visible, transparency, reflectionSize, blur. |
shape | get-reflection | presentation_session_id, slide_index, shape_index | Returns visible and, if visible, transparency/reflectionSize/blur. |
shape | set-soft-edge | presentation_session_id, slide_index, shape_index, radius | Sets the soft edge (feathered edge) radius in points. A radius of 0 removes it. Returns softEdgeRadius. |
shape | get-soft-edge | presentation_session_id, slide_index, shape_index | Returns the shape's current soft edge softEdgeRadius. |
shape | set-bevel | presentation_session_id, slide_index, shape_index, bevel_type, plus optional depth, inset (points) | Applies a 3D bevel to the shape's top edge. bevel_type is an MsoBevelType name (e.g. msoBevelCircle, msoBevelSoftRound, msoBevelRelaxedInset, or msoBevelNone to remove). Returns bevelTypeName, bevelDepth, bevelInset. |
shape | get-bevel | presentation_session_id, slide_index, shape_index | Returns the shape's current bevelTypeName, bevelDepth, bevelInset. |
shape | group | presentation_session_id, slide_index, shape_indexes (JSON array of 1-based indices, at least 2) | Groups multiple shapes into one. Returns the new total shapeCount on the slide — not the grouped shape's index (see NoPIA note below). |
shape | ungroup | presentation_session_id, slide_index, shape_index | Splits a group back into its member shapes. Returns ungroupedShapeCount (members produced) and the new total shapeCount. |
shape | merge | presentation_session_id, slide_index, shape_indexes (JSON array of unique 1-based indices, at least 2), merge_type | Merges shapes with PowerPoint's MsoMergeCmd: msoMergeUnion, msoMergeCombine, msoMergeIntersect, msoMergeSubtract, or msoMergeFragment. Returns mergeTypeName, mergedShapeCount, and the new total shapeCount. Inputs are consumed and replaced by the result; msoMergeFragment can produce multiple shapes. |
shape | set-name | presentation_session_id, slide_index, shape_index, name | Sets the shape's name (as shown in PowerPoint's Selection Pane). Returns name. |
shape | get-name | presentation_session_id, slide_index, shape_index | Returns the shape's current name. |
shape | set-alt-text | presentation_session_id, slide_index, shape_index, alt_text | Sets the shape's alternative text (accessibility description). Returns altText. |
shape | get-alt-text | presentation_session_id, slide_index, shape_index | Returns the shape's current alternative text. |
shape | set-hyperlink | presentation_session_id, slide_index, shape_index, address, screen_tip (optional) | Sets the shape's mouse-click hyperlink to address (URL or file path). screen_tip sets hover tooltip text. Returns hasHyperlink, hyperlinkAddress, hyperlinkScreenTip. |
shape | get-hyperlink | presentation_session_id, slide_index, shape_index | Returns hasHyperlink and, if present, hyperlinkAddress/hyperlinkScreenTip. |
shape | remove-hyperlink | presentation_session_id, slide_index, shape_index | Removes the shape's mouse-click hyperlink, if any (no-op if none is set). Returns hasHyperlink: false. |
Finding a just-grouped shape's index: group does not return the new group shape's own shapeIndex — reading .Index off a freshly-created COM group object is unreliable in this codebase's NoPIA late-binding setup. If the shapes you grouped were the last shapes added to the slide (highest indices, nothing added after them), the resulting group occupies the new, smaller shapeCount as its index (since grouping N shapes always removes N-1 from the slide's shape list). Otherwise, call shape(action: "get-count", ...) before and after grouping and inspect via a follow-up read if you need to confirm which index now holds the group.
Hyperlinks¶
set-hyperlink/get-hyperlink/remove-hyperlink manage a shape's mouse-click action — clicking the shape at presentation time navigates to address (an absolute URL like "https://example.com", or a local file path). There is no separate mouse-hover hyperlink action, and no text-run-level hyperlink (a whole-shape hyperlink is the only granularity this tool surface exposes) — to make specific words within a text box clickable, put that text in its own shape.
address is normalized by PowerPoint itself (e.g. "https://example.com" round-trips as "https://example.com/" with a trailing slash) — compare against the returned hyperlinkAddress rather than assuming an exact byte-for-byte match of what you passed in.
shape(action: "set-hyperlink", presentation_session_id: ..., slide_index: ..., shape_index: ...,
address: "https://example.com", screen_tip: "Visit our site")
shape(action: "get-hyperlink", presentation_session_id: ..., slide_index: ..., shape_index: ...)
→ hasHyperlink: true, hyperlinkAddress: "https://example.com/", hyperlinkScreenTip: "Visit our site"
shape(action: "remove-hyperlink", presentation_session_id: ..., slide_index: ..., shape_index: ...)
→ hasHyperlink: false
Linked Pictures¶
File links are separate from click hyperlinks. Add a linked picture with image(action: "add-picture", ..., link_to_file: true), then use get-link-info, update-link, set-link-auto-update, or break-link on that picture's 1-based shape index. break-link retains the picture as an embedded shape. Link operations on rectangles, text boxes, embedded pictures, or other non-linked shapes return a validation error. Unexpected PowerPoint errors from typed link members propagate to the MCP or CLI boundary.
Dash Styles (dash_style for set-line)¶
Must match a real MsoLineDashStyle enum member name exactly: msoLineSolid, msoLineSquareDot, msoLineRoundDot, msoLineDash, msoLineDashDot, msoLineDashDotDot, msoLineLongDash, msoLineLongDashDot.
Z-Order Commands (z_order_command for set-z-order)¶
bring-to-front, send-to-back, bring-forward, send-backward. (PowerPoint's Word-only z-order members — bring/send relative to text — are intentionally not exposed here.)
Auto Shape Types¶
shape_type for add-auto-shape must match a real MsoAutoShapeType enum member name exactly (case-sensitive, mso-prefixed PascalCase) — this is a curated subset (not the full Office enum):
| Category | shape_type values |
|---|---|
| Basic | msoShapeRectangle, msoShapeRoundedRectangle, msoShapeOval, msoShapeDiamond, msoShapeParallelogram, msoShapeTrapezoid, msoShapeIsoscelesTriangle, msoShapeRightTriangle, msoShapeHexagon, msoShapeOctagon, msoShapeRegularPentagon, msoShapeCross |
| Arrows | msoShapeRightArrow, msoShapeLeftArrow, msoShapeUpArrow, msoShapeDownArrow, msoShapeLeftRightArrow, msoShapeUpDownArrow |
| Brackets/braces | msoShapeLeftBracket, msoShapeRightBracket, msoShapeLeftBrace, msoShapeRightBrace |
| Decorative/misc | msoShapeCan, msoShapeCube, msoShapeBevel, msoShapeFoldedCorner, msoShapeSmileyFace, msoShapeDonut, msoShapeNoSymbol, msoShapeBlockArc, msoShapeHeart, msoShapeLightningBolt, msoShapeSun, msoShapeMoon, msoShapeArc, msoShapePlaque |
Passing an unrecognized string returns success: false — double-check spelling rather than guessing variants (e.g. star/callout shapes are not in this curated set).
For lines and connectors, connector_type must be one of msoConnectorStraight, msoConnectorElbow, or msoConnectorCurve.
Shape Indexing Within a Slide¶
shape_index is 1-based and reflects the order shapes were added to that slide (and any built-in placeholders from the applied layout, if present). After adding several shapes, use shape(action: "get-count", ...) to confirm the current total before referencing an index you didn't just create yourself — don't assume index 1 is always the title.
shape(action: "add-text-box", presentation_session_id: ..., slide_index: 1, ..., text: "Title") → shapeIndex 1 (assuming a blank slide)
shape(action: "add-rectangle", presentation_session_id: ..., slide_index: 1, ...) → shapeIndex 2
shape(action: "add-text-box", presentation_session_id: ..., slide_index: 1, ..., text: "Body") → shapeIndex 3
shape(action: "get-count", presentation_session_id: ..., slide_index: 1) → 3 → confirms the count before further edits
Building a Text Box + Table/Chart Combo Slide¶
Tables and charts are added by their own domain tools (table(action: "add-table", ...), chart(action: "add-chart", ...) — see tables.md and charts.md) but they are shapes on the slide like any other, and share the same shape_index numbering with rectangles and text boxes added on that slide. Track the returned shapeIndex from each add call (or re-check with shape(action: "get-count", ...)) so subsequent position/size/format calls target the right shape.
Repositioning and Resizing¶
Use shape(action: "set-position", ...) / shape(action: "set-size", ...) for targeted layout fixes instead of deleting and re-adding a shape:
CORRECT — nudge a shape that overlaps another after visual verification
shape(action: "set-position", presentation_session_id: ..., slide_index: ..., shape_index: ..., left: 500, top: 120)
AVOID — delete and recreate to move a shape
shape(action: "delete", presentation_session_id: ..., slide_index: ..., shape_index: ...)
shape(action: "add-rectangle", presentation_session_id: ..., slide_index: ..., left: 500, top: 120, width: ..., height: ...)
Deleting and recreating loses the shape's text content and any formatting already applied to it — prefer targeted set-position/set-size (see anti-patterns.md).