SlideForge

Deterministic, fully editable PowerPoint from typed slide intents. 200+ layouts, brand templates.

Should I use this

Quality & Safety

A
Description quality
98%
Schema completeness
93%
Naming quality
89%
Poisoning risk
80%
Permission match
90%
Protocol compliance
100%

Findings (4)

  • HIGHTool poisoning patterns detected
  • MEDIUMTool 'create_slide' description contains placeholder textin create_slide
  • LOWTool 'browse_catalog' suggests web access but openWorldHint=falsein browse_catalog
  • INFOTool description contains placeholder or incomplete textin create_slide

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~9,342Tokens (tool definitions)
~9.7 KBTypical response size
Significant attention impact (7.30% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "slideforge": {
      "command": "uvx",
      "args": [
        "slideforge-mcp"
      ]
    }
  }
}

Runnable packages

pypislideforge-mcp5.9.0stdio

Remote endpoints

https://api.slideforge.dev/mcp/streamable-http

What it can do

Tool inventory

Tools (9)

🟒 Read-only🟑 WriteπŸ”΄ Deleteβšͺ Unknown
🟒browse_catalog(family, variant, prior_id, q, limit, ...)

Browse the PowerPoint slide catalog progressively. No args -> form overview (when-to-use, bound fields, variant counts). family=<form> -> variant one-liners. q=<text> -> ranked search. variant=/prior_id= -> example payload. type=schema + family -> a compact family-level variant chooser (not a sendable contract); type=schema + family + variant -> that variant's exact payload contract (JSON Schema, capacity, field mapping, examples). Free. Code path: type=widgets = the add_widget() catalog (name=<widget> for its contract + thumbnail); type=helpers = python-pptx helper signatures. type=themes + an uploaded theme_id -> that template's branded FURNITURE layouts (its own cover/agenda/divider/closing slides + fill schemas + previews) β€” render via create_slide(form=template_layout, theme_id, data={layout, fills}).

Input Schema

{
  "type": "object",
  "properties": {
    "family": {
      "type": "string"
    },
    "variant": {
      "type": "string"
    },
    "prior_id": {
      "type": "string"
    },
    "q": {
      "type": "string",
      "description": "Semantic search across all variants; returns ranked form/variant matches with scores."
    },
    "limit": {
      "type": "integer",
      "description": "Max results (with q= or family=)."
    },
    "offset": {
      "type": "integer",
      "description": "Pagination offset (with q= or family=)."
    },
    "type": {
      "type": "string",
      "description": "Omit for the form overview (or family=/q= to drill in). schema (+family, optionally +variant=) = schema-first discovery: family only returns a compact variant chooser; family+variant returns that variant's exact machine-readable payload contract (JSON Schema for data, capacity limits, intent-field mapping, examples). widgets = the add_widget() catalog for mode=code (name=<widget> for its contract). helpers = python-pptx helper signatures. themes = list themes (built-in + your saved); Default appears first and can be omitted, or use any returned id as theme_id. brands = your brand kits with versions (theme_id=<slug> renders the default version, <slug>@<n> pins n)."
    },
    "name": {
      "type": "string",
      "description": "Widget name (with type=widgets): returns the full contract + worked example + a rendered thumbnail."
    },
    "source": {
      "type": "string",
      "enum": [
        "all",
        "default",
        "custom",
        "saved",
        "uploaded"
      ],
      "description": "Theme source filter (with type=themes). Default all (built-in + your saved)."
    },
    "top": {
      "type": "integer",
      "description": "Max results (with type=themes)."
    },
    "theme_id": {
      "type": "string",
      "description": "With type=themes: an uploaded theme's id -> its branded furniture layouts + fill schemas (render via create_slide(form=template_layout))."
    }
  }
}
🟒plan_slide(brief, top, escalate, variant_policy)

Plan a PowerPoint slide before rendering (free): send a short brief, get ranked candidates + a separated verdict β€” route (which slide: selected|needs_confirmation|ambiguous), input (can it render: ready|extractable_from_brief|needs_structured_data) and next_action. Free (one embedding). Then call create_slide with the chosen form(+variant). route.confidence: calibrated = measured P(route correct) with label high/medium/low cut on it; retrieval_score/retrieval_margin = the raw family-aggregated classifier values (not probabilities; margin can be negative when families contest); source = jev (calibrated router, took the route at >=0.9) | classifier | structural_router (LLM-rescued). candidate_margin on the top candidate = literal gap between the two shown scores.

Input Schema

{
  "type": "object",
  "properties": {
    "brief": {
      "type": "string"
    },
    "top": {
      "type": "integer"
    },
    "escalate": {
      "type": "boolean",
      "description": "Default true: on a low-confidence route the plan runs the SAME LLM rescue create_slide would (small COGS on that tail only), so plan and create always agree. Set false for a classifier-only, fully free plan (response then flags will_escalate + create_slide_behavior)."
    },
    "variant_policy": {
      "type": "string",
      "enum": [
        "best_semantic_match",
        "production_safe"
      ],
      "description": "production_safe: if the top routed variant is draft/beta, the family's demo-safe sibling leads and route reports both best_semantic and best_production_safe."
    }
  },
  "required": [
    "brief"
  ]
}
🟑create_slide(form, form_description, headline, context, subject, ...)

Create one PowerPoint slide (.pptx, native, editable) from a structured intent in ONE call: pick a `form` from the menu and put your content in the typed fields (placed on the slide as given), or pass a `brief` and let the server route it. Fields tagged (per-form) bind only where the form has that slot β€” ignored-with-warning elsewhere; see each form's `binds` in browse_catalog. BLOCKED (not billed)? If an error has `can_autofix:true`, merge its `patch` into the args at `patch_target`. Unchanged retries repeat the block. New form: browse_catalog(type=schema) first. FORM MENU: agenda_list: an ordered list of sections/topics or learning objectives to walk through bar_rank_chart: bars comparing magnitudes across categories calendar_grid: events on a real calendar - week planner (day x hour) or month grid with event chips (data.events) card_grid: several equal, unordered peer blocks (features, options, pillars, a concept's defined parts, rules/guidelines/common mistakes) case_story: one named story told as evidence, proven by measured results (data.results = figures) comparison_matrix: options x criteria grid: data.columns x data.rows cycle_flow: a closed loop of ordered stages where the last feeds the first (recurring process) data_table: a plain factual table of records by fields editorial_split: two side-by-side halves: contrast (before/after, problem/solution) or copy/numbered steps beside a picture (image_src) exercise_prompt: an exercise/practice/discussion prompt: instruction + hints; optional problem items with blank answer boxes funnel: a quantity narrowing through ordered stages gantt_plan: tasks as bars across named periods on a schedule grid gauge_score: one score on a dial against a scale hero_statement: a statement slide: covers (title/image-led/exec), from->to/thesis-quote transitions, statement/contact/next-steps closings; supporting points -> takeaway_stack, contacts -> data.contacts, next steps -> data.next_steps hub_spoke: one central element with several elements connected around it image_story: a picture shown WHOLE (uncropped) + prose and up to 4 labelled blocks beside it, or a 1-6 picture/placeholder gallery (data.images) kpi_metrics: a metrics dashboard: headline metric cards; data.sections (Highlights/Risks/Asks) makes it an exec summary / QBR snapshot layer_stack: stacked layers where higher sits on, and depends on, lower linear_flow: ordered process stages read left to right (or inputs to process to outputs) maturity_staircase: ascending levels climbing to a higher state nested_magnitude: nested containment - each level contains the next org_structure: a reporting hierarchy / org tree position_map: items placed by two axes - named 2x2 cells or scatter positions pyramid_hierarchy: a triangle of stacked tiers, foundation to apex ramp_curve: a continuous rising wedge split into phases - effort or value accumulating over time section_divider: a section-break: big section number + title; blocks = agenda progress chips (emphasis=primary = current) segment_wheel: a wheel of equal segments around a center - peer categories in the round (composition, not flow) status_dashboard: initiatives/workstreams tracked by status, owner, progress strategic_fork: one origin splitting into two mutually exclusive paths, one recommended swimlane_flow: actor/function lanes by phases, task cells, handoffs across lanes swot: the four-quadrant strengths / weaknesses / opportunities / threats grid system_flow_map: architecture/system components: panels with internals (edges optional) or nodes wired by directed arrows takeaway_stack: a title plus a few supporting points, each with one line of detail (executive summary, key findings); optional closing ask timeline_roadmap: milestones/phases laid out along a time axis trend_chart: one or more series plotted over time value_chain: support bands over primary activity columns flowing into a goal arrowhead (data.support = the bands) visual_showcase: one dominant screenshot/image with numbered callouts pointing into it waterfall_bridge: a start value bridged to an end value by plus/minus contributions Exact per-form data shapes: browse_catalog(type=schema, family=<form>) β€” the generated,always-current JSON Schema + a worked example. (List-shaped forms take `blocks`: [{"label","sub","detail":[str],"emphasis"}]; structured forms take typed `data`.) Escape modes: mode=code (caller-supplied python-pptx in sandbox β€” use for forms the menu cannot express: calendars, custom diagrams); mode=status (poll a job, free). Image-led asks (photo covers, full-bleed visuals): hero_statement + image_prompt or image_src.

Input Schema

{
  "type": "object",
  "properties": {
    "form": {
      "type": "string",
      "description": "the form menu pick (see description) β€” the routing field"
    },
    "form_description": {
      "type": "string"
    },
    "headline": {
      "type": "string",
      "description": "the assertion-style slide title"
    },
    "context": {
      "type": "string",
      "description": "one-line subtitle/standfirst"
    },
    "subject": {
      "type": "string",
      "description": "central entity for forms that have one β€” hub label, org root, section #, fork origin, media label (per-form)."
    },
    "blocks": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "list: [{\"label\",\"sub\",\"detail\":[str],\"emphasis\",\"icon\":lucide-name,\"metric\":{value,label}}]"
    },
    "metric": {
      "type": "object"
    },
    "data": {
      "type": "object",
      "description": "family-specific payload β€” see the documented shapes"
    },
    "takeaway": {
      "type": "string",
      "description": "optional verdict band (per-form). Put the so-what in the headline; add only for a verdict the title can't carry β€” not every slide."
    },
    "caution": {
      "type": "string",
      "description": "one-line risk / caveat callout (per-form)."
    },
    "highlight": {
      "type": "string",
      "description": "one-line emphasis callout (per-form)."
    },
    "source_note": {
      "type": "string",
      "description": "source / footnote line (per-form)."
    },
    "date": {
      "type": "string",
      "description": "date callout (per-form)."
    },
    "notes": {
      "type": "string",
      "description": "Speaker notes for the presenter; never drawn on the slide."
    },
    "image_src": {
      "type": "string",
      "description": "https URL | asset:<id> for image-bearing forms"
    },
    "image_prompt": {
      "type": "string",
      "description": "generate an image when no image_src"
    },
    "brief": {
      "type": "string",
      "description": "prose fallback / extra context for fills"
    },
    "theme_id": {
      "type": "string",
      "description": "Optional theme id from browse_catalog(type=themes). Omit for Default (slideforge_standard)."
    },
    "name": {
      "type": "string"
    },
    "variant": {
      "type": "string",
      "description": "pin a specific variant within the form (list them via browse_catalog). Unknown variant -> rejected (not billed) with the valid list; set allow_variant_fallback to render the family default instead."
    },
    "allow_variant_fallback": {
      "type": "boolean",
      "description": "If the pinned variant is unknown, render the form's default variant (with a warning) instead of rejecting. Default false."
    },
    "variant_policy": {
      "type": "string",
      "enum": [
        "best_semantic_match",
        "production_safe"
      ],
      "description": "Routed-variant maturity policy: production_safe = if the ROUTED variant is draft/beta, render the family's demo-safe sibling instead (warning names both). Never overrides an explicit variant=. Default best_semantic_match."
    },
    "allow_low_confidence": {
      "type": "boolean",
      "description": "Brief routing only: by default a brief that doesn't match a form clearly returns status=needs_confirmation + candidates at cost:0 (no guessed render). Set true to render the top guess and bill it. Default false."
    },
    "allow_fabrication": {
      "type": "boolean",
      "description": "Brief mode only: a bare brief on a DATA form (kpi/funnel/comparison/…) returns would_fabricate, not billed, rather than INVENT numbers. Send typed fields for verbatim, or true to let the brief author them (fidelity=ai_completed). Default false."
    },
    "allow_truncation": {
      "type": "boolean",
      "description": "More items than the form holds blocks (it would drop your data); the response names the dropped count + a suggested_split. true renders the capacity subset (fidelity=verbatim_truncated). Default false."
    },
    "dry_run": {
      "type": "boolean",
      "description": "Free pre-commit check (intent or mode=code), cost:0, no PPTX: status + warnings/errors, plus fidelity_forecast (verbatim|mixed|ai_completed|would_reject) and which fields bind vs get authored. Fix errors, re-call with dry_run=false to render."
    },
    "quality_profile": {
      "type": "string",
      "enum": [
        "executive",
        "technical",
        "appendix"
      ],
      "description": "Thresholds layout.presentation_ready is judged against (executive strictest). Measurement only β€” never blocks a render or changes cost."
    },
    "min_font_pt": {
      "type": "number",
      "minimum": 6,
      "maximum": 40,
      "description": "Binding type floor for prose (exhibit furniture has its own). Type grows to meet it; content that can't fit is an unbilled min_font_not_met naming the size needed. Typical: 12."
    },
    "direction": {
      "type": "string",
      "enum": [
        "ltr",
        "rtl"
      ],
      "description": "rtl typesets AND mirrors the slide right-to-left (Arabic/Hebrew). Never inferred β€” pass it."
    },
    "imagery": {
      "type": "string",
      "enum": [
        "photo",
        "wash",
        "off"
      ],
      "description": "Cover/section-divider imagery: photo (default β€” curated stock photo, half-bleed), wash (abstract color wash), off (plain panel, no photo β€” only when asked). Content slides are never photo-decorated."
    },
    "imagery_tag": {
      "type": "string",
      "enum": [
        "general",
        "agriculture",
        "construction",
        "education",
        "energy",
        "finance",
        "government",
        "healthcare",
        "logistics",
        "manufacturing",
        "retail",
        "technology",
        "travel"
      ],
      "description": "Subject/industry: steers library photos (covers, sections, picture slides) AND the topical palette. Omit = general; `education` = teaching."
    },
    "styling": {
      "type": "string",
      "enum": [
        "topical",
        "clean"
      ],
      "description": "Topical design on default themes (default on; the note names it): designed cover + a subject palette (from imagery_tag, or the brief). clean = neutral. Pins never take it."
    },
    "force_render": {
      "type": "boolean",
      "description": "On completed_with_errors, pptx_url is null (broken slide). Set true to get it anyway. No cost/status effect."
    },
    "code": {
      "type": "string",
      "description": "Python code defining build(prs). Canvas 13.33Γ—7.5\", coords in inches. Pre-imported: Presentation, Inches, Pt, Emu, RGBColor, MSO_ANCHOR, PP_ALIGN. Helpers: add_text_box(slide, left, top, w, h, text, font_size=12, bold=False, color=None), add_box(slide, left, top, w, h, fill_color=None, line_color=None, corner_radius=0.05), add_icon, add_image (src = path or https://); theme_color(name) β†’ RGBColor. add_widget(slide, name, x, y, w, h, params=|content=, theme=THEME) draws board-grade SSG widgets/charts (cards, waterfall, gantt, funnel…) β€” names via `browse_catalog(type=widgets)`. Use font_size=, not size=; use fill_color=, not fill=. When chrome is supplied, use `build(prs, slide)` β€” chrome is pre-rendered. Helper signatures: `browse_catalog(type=helpers)`."
    },
    "job_id": {
      "type": "string",
      "description": "Previous job ID (for mode=status, or mode=code patching)"
    },
    "replacements": {
      "type": "array",
      "description": "String replacements on loaded code [{old, new}] (for mode=code with job_id)",
      "items": {
        "type": "object",
        "properties": {
          "old": {
            "type": "string",
            "description": "Exact string to find"
          },
          "new": {
            "type": "string",
            "description": "Replacement string"
          }
        },
        "required": [
          "old",
          "new"
        ]
      }
    },
    "language": {
      "type": "string",
      "enum": [
        "bg",
        "ca",
        "cs",
        "da",
        "de",
        "el",
        "en",
        "es",
        "et",
        "fi",
        "fr",
        "gl",
        "hr",
        "hu",
        "id",
        "is",
        "it",
        "ja",
        "ko",
        "lt",
        "lv",
        "nl",
        "no",
        "pl",
        "pt",
        "ro",
        "ru",
        "sk",
        "sl",
        "sr",
        "sv",
        "tr",
        "uk",
        "vi",
        "zh"
      ],
      "description": "ISO 639-1 (default en): furniture labels and authored fills follow it."
    },
    "include_preview": {
      "type": "string",
      "enum": [
        "none",
        "small",
        "default",
        "full"
      ],
      "description": "Inline-preview PAYLOAD only (not execution). Default: default (768px). none omits the inline image and returns just the URLs β€” it does NOT change sync/async. Use `wait` to control execution."
    },
    "detail": {
      "type": "string",
      "enum": [
        "compact",
        "full"
      ],
      "description": "Response verbosity. Default `compact`: status, form/variant, fidelity (verbatim|mixed|ai_completed), warnings[]/errors[] (only when present), urls, cost. `full` adds a debug object (engine internals, verify events, latency buckets)."
    },
    "verify": {
      "type": "string",
      "enum": [
        "off",
        "lint",
        "lint+vlm",
        "full"
      ],
      "description": "mode=code. Default `lint`: static geometry + content checks, no LLM. `lint+vlm` adds a VLM second look (~+3s); a blank render is then an unbilled error, not a billed warning. `off` skips checks."
    },
    "wait": {
      "type": "string",
      "enum": [
        "auto",
        "true",
        "false"
      ],
      "description": "AI-image slides block ~10-15s; `false` returns a job_id to poll, not block (mode=brief)."
    },
    "logo_id": {
      "type": "string",
      "description": "Optional brand logo (from upload_asset purpose=logo) drawn as chrome on content slides; covers/section breaks stay clean."
    },
    "mode": {
      "type": "string",
      "enum": [
        "safe",
        "brief",
        "code",
        "status"
      ],
      "description": "Default: structured intent / brief. safe = validate-then-render in ONE call (renders + bills only if faithful; else an unbilled invalid report with the fix β€” recommended, no dry_run round-trip). code = python-pptx escape. status = poll."
    }
  }
}
🟑create_deck(slides, theme_id, name, styling, imagery, ...)

Create a complete PowerPoint presentation (.pptx): a whole multi-slide deck, native and editable, in one call. `slides` is a list of create_slide intents (same form menu + data shapes β€” see create_slide). Slides fill in parallel and merge into one themed PPTX with page numbers. Include furniture: a hero_statement cover, section_divider breaks, and a closing (hero_statement variant=contact_closing via blocks-free slots). BLOCKED (not billed)? If an error has `can_autofix:true`, merge its `patch` into the args at `patch_target`. Unchanged retries repeat the block. New form: browse_catalog(type=schema) first. Also: mode=assemble merges existing slide job_ids as-rendered (free; theme_id does NOT re-theme them β€” render with create_deck(slides=[…], theme_id=…) for a unified theme); mode=fork clones a deck (free). Polling: deck_id == job_id β€” manage_account(action=job, job_id=<deck_id>).

Input Schema

{
  "type": "object",
  "properties": {
    "slides": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "each item is a create_slide intent (same form menu, typed fields, and data shapes as create_slide)."
    },
    "theme_id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "styling": {
      "type": "string",
      "enum": [
        "topical",
        "clean"
      ],
      "description": "Deck-level topical-design switch, inherited by every slide (a slide-level styling wins). See create_slide.styling."
    },
    "imagery": {
      "type": "string",
      "enum": [
        "photo",
        "wash",
        "off"
      ],
      "description": "Deck-level imagery mode, inherited by every slide (a slide-level imagery wins). See create_slide.imagery."
    },
    "imagery_tag": {
      "type": "string",
      "enum": [
        "general",
        "agriculture",
        "construction",
        "education",
        "energy",
        "finance",
        "government",
        "healthcare",
        "logistics",
        "manufacturing",
        "retail",
        "technology",
        "travel"
      ],
      "description": "Deck-level subject declaration, inherited by every slide (a slide-level imagery_tag wins). Declare it once for a whole deck. See create_slide.imagery_tag."
    },
    "direction": {
      "type": "string",
      "enum": [
        "ltr",
        "rtl"
      ],
      "description": "Deck-level writing direction, inherited by every slide (a slide-level direction wins) β€” set it once for an Arabic/Hebrew deck. Covers/dividers rendered on an UPLOADED brand template keep that template's own layout direction. See create_slide.direction."
    },
    "force_render": {
      "type": "boolean",
      "description": "IGNORED (deck-level). pptx_url is always returned when at least one slide rendered, so there is nothing to force. Still meaningful on create_slide."
    },
    "allow_partial": {
      "type": "boolean",
      "description": "IGNORED. A deck bills per rendered slide and always returns its pptx; slides that failed or rendered badly are free and named in repair_actions."
    },
    "strict_policy": {
      "type": "object",
      "properties": {
        "reject_ai_completed": {
          "type": "boolean",
          "description": "Reject slides whose content was fully AI-completed."
        },
        "reject_mixed": {
          "type": "boolean",
          "description": "Reject slides with mixed verbatim and AI-completed content."
        },
        "reject_truncated": {
          "type": "boolean",
          "description": "Reject slides with truncated supplied content."
        },
        "reject_ignored_fields": {
          "type": "boolean",
          "description": "Reject slides whose supplied fields were not rendered (fidelity=partial / field_ignored)."
        },
        "reject_field_warnings": {
          "type": "boolean",
          "description": "Reject slides carrying any field-binding warning (field_ignored, input_shape_hint, normalized, variant_fallback, form_rerouted)."
        },
        "reject_draft_variants": {
          "type": "boolean",
          "description": "Reject slides rendered by a draft-maturity variant (see each slide's variant_maturity warning)."
        },
        "min_font_pt": {
          "type": "number",
          "description": "Reject slides whose reported minimum font size is below this point size."
        },
        "max_density": {
          "type": "string",
          "enum": [
            "good",
            "medium",
            "high"
          ],
          "description": "Reject slides whose quality.density is above this level."
        }
      },
      "description": "Optional CI-style gate for automated report pipelines. dry_run returns policy_result; render returns rejected/cost:0 if the policy fails."
    },
    "job_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Slide job IDs to merge (for mode=assemble)"
    },
    "deck_id": {
      "type": "string",
      "description": "Existing deck ID (for mode=fork, or mode=render to update)"
    },
    "title": {
      "type": "string",
      "description": "Deck title (PowerPoint metadata)"
    },
    "language": {
      "type": "string",
      "enum": [
        "bg",
        "ca",
        "cs",
        "da",
        "de",
        "el",
        "en",
        "es",
        "et",
        "fi",
        "fr",
        "gl",
        "hr",
        "hu",
        "id",
        "is",
        "it",
        "ja",
        "ko",
        "lt",
        "lv",
        "nl",
        "no",
        "pl",
        "pt",
        "ro",
        "ru",
        "sk",
        "sl",
        "sr",
        "sv",
        "tr",
        "uk",
        "vi",
        "zh"
      ],
      "description": "ISO 639-1 (default en) for every slide: furniture labels and authored fills follow it."
    },
    "mode": {
      "type": "string",
      "enum": [
        "render",
        "assemble",
        "fork"
      ],
      "description": "Default render. assemble/fork are free deck plumbing."
    },
    "dry_run": {
      "type": "boolean",
      "description": "Deck-level free pre-flight (cost:0, NO render/PPTX): returns a per-slide validation manifest [{i, form, fidelity_forecast, status, errors}] so you can fix bad slides before spending. A deck is one artifact, so validation is all-or-nothing β€” put dry_run here, not on individual slides. Resend without dry_run to render."
    },
    "logo_id": {
      "type": "string",
      "description": "Optional brand logo (from upload_asset purpose=logo) applied as chrome to every content slide in the deck."
    }
  },
  "required": []
}
πŸ”΄edit_slide(job_id, patch)

Change a slide you already rendered, in place and free: the job keeps its id and links. Send the job_id and a patch of the fields to change. Never runs a model: a brief or a picture request is refused (make a new slide for those). The response carries the slide's full current spec as `intent`. Up to 20 edits per slide.

Input Schema

{
  "type": "object",
  "properties": {
    "job_id": {
      "type": "string",
      "description": "the rendered slide's job_id"
    },
    "patch": {
      "type": "object",
      "description": "the slide fields to change (same fields as create_slide). A field left out keeps its value, a field sent as null is removed, a list replaces the whole list, `data` merges key by key. Send only `notes` to add or replace speaker notes without a re-render.",
      "properties": {
        "form": {
          "type": "string",
          "description": "the form menu pick (see description) β€” the routing field"
        },
        "headline": {
          "type": "string",
          "description": "the assertion-style slide title"
        },
        "context": {
          "type": "string",
          "description": "one-line subtitle/standfirst"
        },
        "subject": {
          "type": "string",
          "description": "central entity for forms that have one β€” hub label, org root, section #, fork origin, media label (per-form)."
        },
        "blocks": {
          "type": "array",
          "items": {
            "type": "object"
          },
          "description": "list: [{\"label\",\"sub\",\"detail\":[str],\"emphasis\",\"icon\":lucide-name,\"metric\":{value,label}}]"
        },
        "metric": {
          "type": "object"
        },
        "data": {
          "type": "object",
          "description": "family-specific payload β€” see the documented shapes"
        },
        "takeaway": {
          "type": "string",
          "description": "optional verdict band (per-form). Put the so-what in the headline; add only for a verdict the title can't carry β€” not every slide."
        },
        "caution": {
          "type": "string",
          "description": "one-line risk / caveat callout (per-form)."
        },
        "highlight": {
          "type": "string",
          "description": "one-line emphasis callout (per-form)."
        },
        "source_note": {
          "type": "string",
          "description": "source / footnote line (per-form)."
        },
        "date": {
          "type": "string",
          "description": "date callout (per-form)."
        },
        "notes": {
          "type": "string",
          "description": "Speaker notes for the presenter; never drawn on the slide."
        },
        "image_src": {
          "type": "string",
          "description": "https URL | asset:<id> for image-bearing forms"
        },
        "theme_id": {
          "type": "string"
        },
        "variant": {
          "type": "string",
          "description": "pin a specific variant within the form (list them via browse_catalog). Unknown variant -> rejected with the valid list; null unpins."
        },
        "allow_variant_fallback": {
          "type": "boolean",
          "description": "If the pinned variant is unknown, render the form's default variant (with a warning) instead of rejecting. Default false."
        },
        "variant_policy": {
          "type": "string",
          "enum": [
            "best_semantic_match",
            "production_safe"
          ],
          "description": "Routed-variant maturity policy: production_safe = if the ROUTED variant is draft/beta, render the family's demo-safe sibling instead (warning names both). Never overrides an explicit variant=. Default best_semantic_match."
        },
        "allow_truncation": {
          "type": "boolean",
          "description": "More items than the form holds blocks (it would drop your data); the response names the dropped count + a suggested_split. true renders the capacity subset (fidelity=verbatim_truncated). Default false."
        },
        "quality_profile": {
          "type": "string",
          "enum": [
            "executive",
            "technical",
            "appendix"
          ],
          "description": "Thresholds layout.presentation_ready is judged against (executive strictest). Measurement only β€” never blocks a render or changes cost."
        },
        "min_font_pt": {
          "type": "number",
          "minimum": 6,
          "maximum": 40,
          "description": "Binding type floor for prose. Content that can't fit is refused as min_font_not_met naming the size needed. Typical: 12."
        },
        "direction": {
          "type": "string",
          "enum": [
            "ltr",
            "rtl"
          ],
          "description": "rtl typesets AND mirrors the slide right-to-left (Arabic/Hebrew). Never inferred β€” pass it."
        },
        "imagery": {
          "type": "string",
          "enum": [
            "photo",
            "wash",
            "off"
          ],
          "description": "Cover/section-divider imagery: photo (default β€” curated stock photo, half-bleed), wash (abstract color wash), off (plain panel, no photo β€” only when asked). Content slides are never photo-decorated."
        },
        "imagery_tag": {
          "type": "string",
          "enum": [
            "general",
            "agriculture",
            "construction",
            "education",
            "energy",
            "finance",
            "government",
            "healthcare",
            "logistics",
            "manufacturing",
            "retail",
            "technology",
            "travel"
          ],
          "description": "Subject/industry: steers library photos (covers, sections, picture slides) AND the topical palette. Omit = general; `education` = teaching."
        },
        "styling": {
          "type": "string",
          "enum": [
            "topical",
            "clean"
          ],
          "description": "Topical design on default themes (default on; the note names it): designed cover + a subject palette (from imagery_tag, or the brief). clean = neutral. Pins never take it."
        }
      },
      "additionalProperties": true
    }
  },
  "required": [
    "job_id",
    "patch"
  ]
}
πŸ”΄edit_deck(job_id, slides)

Change one or more slides of a deck you already rendered, in place and free: only the patched slides re-render, the deck is re-merged and keeps its id and links. Never runs a model: a brief or a picture request is refused. Each edited slide's entry carries its full current spec as `intent`. Up to 20 edits per deck.

Input Schema

{
  "type": "object",
  "properties": {
    "job_id": {
      "type": "string",
      "description": "the deck's job_id"
    },
    "slides": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "slide": {
            "type": "integer",
            "description": "0-based index, as slides[].i in the create_deck response"
          },
          "patch": {
            "type": "object",
            "description": "the slide fields to change (same fields as create_slide). A field left out keeps its value, a field sent as null is removed, a list replaces the whole list, `data` merges key by key. Send only `notes` to add or replace speaker notes without a re-render.",
            "properties": {
              "form": {
                "type": "string",
                "description": "the form menu pick (see description) β€” the routing field"
              },
              "headline": {
                "type": "string",
                "description": "the assertion-style slide title"
              },
              "context": {
                "type": "string",
                "description": "one-line subtitle/standfirst"
              },
              "subject": {
                "type": "string",
                "description": "central entity for forms that have one β€” hub label, org root, section #, fork origin, media label (per-form)."
              },
              "blocks": {
                "type": "array",
                "items": {
                  "type": "object"
                },
                "description": "list: [{\"label\",\"sub\",\"detail\":[str],\"emphasis\",\"icon\":lucide-name,\"metric\":{value,label}}]"
              },
              "metric": {
                "type": "object"
              },
              "data": {
                "type": "object",
                "description": "family-specific payload β€” see the documented shapes"
              },
              "takeaway": {
                "type": "string",
                "description": "optional verdict band (per-form). Put the so-what in the headline; add only for a verdict the title can't carry β€” not every slide."
              },
              "caution": {
                "type": "string",
                "description": "one-line risk / caveat callout (per-form)."
              },
              "highlight": {
                "type": "string",
                "description": "one-line emphasis callout (per-form)."
              },
              "source_note": {
                "type": "string",
                "description": "source / footnote line (per-form)."
              },
              "date": {
                "type": "string",
                "description": "date callout (per-form)."
              },
              "notes": {
                "type": "string",
                "description": "Speaker notes for the presenter; never drawn on the slide."
              },
              "image_src": {
                "type": "string",
                "description": "https URL | asset:<id> for image-bearing forms"
              },
              "theme_id": {
                "type": "string"
              },
              "variant": {
                "type": "string",
                "description": "pin a specific variant within the form (list them via browse_catalog). Unknown variant -> rejected with the valid list; null unpins."
              },
              "allow_variant_fallback": {
                "type": "boolean",
                "description": "If the pinned variant is unknown, render the form's default variant (with a warning) instead of rejecting. Default false."
              },
              "variant_policy": {
                "type": "string",
                "enum": [
                  "best_semantic_match",
                  "production_safe"
                ],
                "description": "Routed-variant maturity policy: production_safe = if the ROUTED variant is draft/beta, render the family's demo-safe sibling instead (warning names both). Never overrides an explicit variant=. Default best_semantic_match."
              },
              "allow_truncation": {
                "type": "boolean",
                "description": "More items than the form holds blocks (it would drop your data); the response names the dropped count + a suggested_split. true renders the capacity subset (fidelity=verbatim_truncated). Default false."
              },
              "quality_profile": {
                "type": "string",
                "enum": [
                  "executive",
                  "technical",
                  "appendix"
                ],
                "description": "Thresholds layout.presentation_ready is judged against (executive strictest). Measurement only β€” never blocks a render or changes cost."
              },
              "min_font_pt": {
                "type": "number",
                "minimum": 6,
                "maximum": 40,
                "description": "Binding type floor for prose. Content that can't fit is refused as min_font_not_met naming the size needed. Typical: 12."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "ltr",
                  "rtl"
                ],
                "description": "rtl typesets AND mirrors the slide right-to-left (Arabic/Hebrew). Never inferred β€” pass it."
              },
              "imagery": {
                "type": "string",
                "enum": [
                  "photo",
                  "wash",
                  "off"
                ],
                "description": "Cover/section-divider imagery: photo (default β€” curated stock photo, half-bleed), wash (abstract color wash), off (plain panel, no photo β€” only when asked). Content slides are never photo-decorated."
              },
              "imagery_tag": {
                "type": "string",
                "enum": [
                  "general",
                  "agriculture",
                  "construction",
                  "education",
                  "energy",
                  "finance",
                  "government",
                  "healthcare",
                  "logistics",
                  "manufacturing",
                  "retail",
                  "technology",
                  "travel"
                ],
                "description": "Subject/industry: steers library photos (covers, sections, picture slides) AND the topical palette. Omit = general; `education` = teaching."
              },
              "styling": {
                "type": "string",
                "enum": [
                  "topical",
                  "clean"
                ],
                "description": "Topical design on default themes (default on; the note names it): designed cover + a subject palette (from imagery_tag, or the brief). clean = neutral. Pins never take it."
              }
            },
            "additionalProperties": true
          }
        },
        "required": [
          "slide",
          "patch"
        ]
      }
    }
  },
  "required": [
    "job_id",
    "slides"
  ]
}
🟑translate_deck(target_language, source_language, job_id, pptx_url, pptx_base64, ...)

Translate a PowerPoint (.pptx) deck preserving all formatting. Supports 35 languages (Latin, Cyrillic, Greek, Chinese, Japanese, Korean). Provide job_id (from a previous create_slide/create_deck), pptx_url, or pptx_base64.

Input Schema

{
  "type": "object",
  "properties": {
    "target_language": {
      "type": "string",
      "enum": [
        "en",
        "de",
        "fr",
        "es",
        "it",
        "pt",
        "nl",
        "sv",
        "da",
        "no",
        "fi",
        "is",
        "pl",
        "cs",
        "sk",
        "hu",
        "ro",
        "hr",
        "sl",
        "et",
        "lt",
        "lv",
        "ru",
        "uk",
        "bg",
        "sr",
        "tr",
        "ca",
        "gl",
        "id",
        "vi",
        "el",
        "zh",
        "ja",
        "ko"
      ],
      "description": "Target language (required)"
    },
    "source_language": {
      "type": "string",
      "description": "Source language or 'auto' (default auto)"
    },
    "job_id": {
      "type": "string",
      "description": "Source: previous slide/deck job ID (preferred β€” no file transfer needed)"
    },
    "pptx_url": {
      "type": "string",
      "description": "Source: HTTPS URL to .pptx"
    },
    "pptx_base64": {
      "type": "string",
      "description": "Source: Base64-encoded .pptx (max ~10 MB)"
    },
    "include_notes": {
      "type": "boolean",
      "description": "Translate speaker notes (default false)"
    },
    "include_tables": {
      "type": "boolean",
      "description": "Translate table cells (default true)"
    },
    "concise_mode": {
      "type": "boolean",
      "description": "Prefer shorter translations for tight text boxes"
    },
    "name": {
      "type": "string",
      "description": "Job name"
    },
    "include_preview": {
      "type": "string",
      "enum": [
        "none",
        "small",
        "default"
      ],
      "description": "Wait+embed preview (default=wait)"
    }
  },
  "required": [
    "target_language"
  ]
}
πŸ”΄upload_asset(purpose, data, filename, prompt, size, ...)

Upload assets for PowerPoint (.pptx) generation: company template, logo, image, or document β€” or AI-generate an image. Purposes: β€’ logo β€” company logo for chrome (PNG/JPG/SVG, max 5MB) β†’ logo_id β€’ image β€” image for the Image component (max 10MB) β†’ asset_id β€’ theme β€” company template PPTX β†’ theme_id; slides with it render NATIVELY on the template (masters/layouts/chrome) β€’ generate_image β€” AI-generate via `prompt` β†’ asset_id β€’ translate β€” PPTX to translate β†’ deck job_id (requires `target_language`) β€’ pdf β€” PDF β†’ editable slides; pass `target_language` to also translate β€’ recreate β€” image OF a slide β†’ editable PPTX slide (honest annotate/preserve fallback). Use `image` to just place a picture Files >3MB (pdf/translate/theme) β€” and recreate on chat hosts β€” omit `data`: a drop-zone appears in the result card; bytes never pass through the agent.

Input Schema

{
  "type": "object",
  "properties": {
    "purpose": {
      "type": "string",
      "enum": [
        "logo",
        "image",
        "theme",
        "brand",
        "generate_image",
        "translate",
        "pdf",
        "recreate"
      ],
      "description": "Asset type (required). brand = a .pptx/.potx corporate template imported as your brand kit (theme is the same thing under its old name)."
    },
    "data": {
      "type": "string",
      "description": "Base64-encoded file content. Required for logo/image/theme/translate. Optional for pdf β€” omit to get a drop-zone (recommended for files >3MB)."
    },
    "filename": {
      "type": "string",
      "description": "Original filename (for type detection)"
    },
    "prompt": {
      "type": "string",
      "description": "Image description (required when purpose=generate_image)"
    },
    "size": {
      "type": "string",
      "enum": [
        "1024x1024",
        "1792x1024",
        "1024x1792"
      ],
      "description": "Image dimensions for generate_image (default 1024Γ—1024)"
    },
    "quality": {
      "type": "string",
      "enum": [
        "draft",
        "balanced",
        "premium"
      ],
      "description": "draft = Flux Schnell. balanced (default) = Gemini Flash Image. premium = GPT Image 2. Overridden by `model`."
    },
    "model": {
      "type": "string",
      "description": "Explicit gateway model ID. Overrides `quality`."
    },
    "position": {
      "type": "string",
      "description": "Logo position: top-left / top-right / bottom-left / bottom-right"
    },
    "theme_name": {
      "type": "string",
      "description": "Name for extracted theme (purpose=theme)"
    },
    "theme_id": {
      "type": "string",
      "description": "For purpose=recreate: the brand kit or built-in theme to render the recreated slide in β€” your kit slug, `slug@version`, or a built-in id. Omit to keep the look of the source image."
    },
    "job_id": {
      "type": "string",
      "description": "For purpose=brand: keep the look a recreate rendered in β€” pass that recreate's job_id and its exact kit is saved as yours (no upload, no charge)."
    },
    "target_language": {
      "type": "string",
      "enum": [
        "en",
        "de",
        "fr",
        "es",
        "it",
        "pt",
        "nl",
        "sv",
        "da",
        "no",
        "fi",
        "is",
        "pl",
        "cs",
        "sk",
        "hu",
        "ro",
        "hr",
        "sl",
        "et",
        "lt",
        "lv",
        "ru",
        "uk",
        "bg",
        "sr",
        "tr",
        "ca",
        "gl",
        "id",
        "vi",
        "el",
        "zh",
        "ja",
        "ko"
      ],
      "description": "Required for purpose=translate. Optional for purpose=pdf — chains pdf→pptx→translate in one call."
    }
  },
  "required": [
    "purpose"
  ]
}
πŸ”΄manage_account(action, job_id, limit, status, include_children, ...)

SlideForge account for PowerPoint generation: balance, job history, feedback, data controls. All free. Actions: status (balance+plan), usage (spend breakdown), jobs (history), job (single job detail β€” slide jobs include `quality_warnings[]`; deck jobs add `slides_completed/slides_failed/failed_slides[]`), feedback (submit), feedback_list (read your reports back: status + resolution), onboarding (capabilities overview), download_url (fresh short-TTL PPTX link for an owned job β€” when a result carries no inline URL), security_status (retention + access-model + deletion posture), delete_job (irreversible: job + versions + files) Action delete_asset irreversibly deletes a user-owned uploaded/generated image asset.

Input Schema

{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "status",
        "usage",
        "jobs",
        "job",
        "download_url",
        "feedback",
        "feedback_list",
        "onboarding",
        "brand_report",
        "reports",
        "security_status",
        "delete_job",
        "delete_asset"
      ],
      "description": "Operation (required). feedback β†’ report a defect or request against a render; pass job_id so it is actionable, and ask the user before filing. feedback_list β†’ read YOUR OWN filed reports back, with `status` and the `resolution` written when one was acted on: check it before working around a defect you reported earlier, because it may already be fixed. brand_report β†’ the per-token fidelity report for one of your brand kits (pass theme_id). reports β†’ list report types. delete_job is irreversible. delete_asset is irreversible for user-owned image assets."
    },
    "job_id": {
      "type": "string",
      "description": "Job ID (for action=job, action=download_url and action=delete_job)"
    },
    "limit": {
      "type": "integer",
      "description": "Max rows (action=jobs default 10; action=feedback_list default 50, max 100)"
    },
    "status": {
      "type": "string",
      "description": "Filter β€” action=jobs: queued/generating/complete/failed; action=feedback_list: open/resolved"
    },
    "include_children": {
      "type": "boolean",
      "description": "For action=jobs: include deck child slides (each carries parent_deck_id) so a deck's slides are discoverable by listing. Default false (parents only). Deck rows roll child cost up to the deck."
    },
    "message": {
      "type": "string",
      "description": "What went wrong or what you want, in the user's own words (for action=feedback)."
    },
    "category": {
      "type": "string",
      "enum": [
        "layout",
        "typography",
        "contrast",
        "content",
        "icons",
        "images",
        "theme",
        "chrome",
        "consistency",
        "bug",
        "feature_request",
        "testimonial",
        "general",
        "other"
      ],
      "description": "Feedback category (action=feedback to file under it, action=feedback_list to filter by it). The first nine are slide-quality categories β€” pair them with job_id."
    },
    "severity": {
      "type": "string",
      "enum": [
        "bug",
        "quality",
        "suggestion"
      ],
      "description": "For action=feedback: `bug` = it is broken, `quality` = it rendered but reads poorly, `suggestion` = a request. Defaults to suggestion, so file real defects explicitly or they are triaged as wishes."
    },
    "days": {
      "type": "integer",
      "description": "Lookback period (for action=usage, default 30)"
    },
    "detail": {
      "type": "boolean",
      "description": "For action=status only: default false masks identity fields; true returns full email/user_id diagnostics for the authenticated user."
    },
    "include_preview": {
      "type": "string",
      "enum": [
        "none",
        "small",
        "default",
        "full"
      ],
      "description": "Preview (for action=job)"
    },
    "slug": {
      "type": "string",
      "description": "Report slug (for action=reports β€” returns one report's full metadata; omit to list all)."
    },
    "asset_id": {
      "type": "string",
      "description": "Image asset ID (for action=delete_asset). Logos are content-addressed/shared and are not deleted by this action."
    }
  },
  "required": [
    "action"
  ]
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded9 tools
verifiedversion not recorded9 tools
verifiedversion not recorded9 tools
verifiedversion not recorded9 tools
verifiedversion not recorded7 tools
verifiedversion not recorded7 tools