Metadata-Version: 2.5
Name: slidefast-mcp
Version: 0.2.1
Summary: MCP server and CLI for the Slidefast API - create AI-powered carousels
Project-URL: Homepage, https://slidefast.io
Project-URL: Documentation, https://slidefast.io/docs/mcp
Project-URL: Support, https://slidefast.io/docs/mcp
Author-email: Slidefast <hello@slidefast.io>
License-Expression: MIT
License-File: LICENSE
Keywords: ai,carousel,cli,mcp,presentations,slidefast,slides
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.11
Requires-Dist: httpx>=0.25.0
Requires-Dist: mcp[cli]<2,>=1.2.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyjwt<3,>=2.8.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# Slidefast MCP Server

<!-- mcp-name: io.slidefast/slidefast -->

An MCP (Model Context Protocol) server **and a `slidefast` CLI** that wrap the
[Slidefast](https://slidefast.io) public API, so AI assistants and shell scripts can create,
edit, review, export and publish AI carousels through the same client.

## Features

- **Create presentations** - Start new presentations with custom themes
- **AI-powered slide generation** - Chat with AI to generate and modify slides
- **Projects** - Scope every list and create call to one client workspace
- **Client review links** - No-login approval URLs, with the comment thread (Agency plan)
- **Export options** - Export to PDF, PNG ZIP, or individual slide PNGs
- **Full CRUD operations** - Get, update, and delete presentations
- **Sharing and metadata** - Enable share links and generate social metadata
- **Theme, brand kit and media management** - Manage themes and library images
- **Social publishing** - Post carousels to LinkedIn, TikTok (draft or live), Facebook Pages and Instagram
- **Rate limit monitoring** - Check your API usage

## Installation

### Option 1: Local Mode (stdio transport)

Install the package:

```bash
pip install slidefast-mcp
# or with uv
uv pip install slidefast-mcp
```

Or run directly with uvx (no install needed):

```bash
uvx slidefast-mcp
```

### Option 2: Remote Mode (Streamable HTTP)

Connect to the hosted server at `https://mcp.slidefast.io/mcp` (no installation required). OAuth-capable clients discover Slidefast's OAuth 2.1 server automatically and open browser sign-in on first use.

## Configuration

### Getting Your API Key

1. Go to [slidefast.io](https://slidefast.io)
2. Sign in to your account
3. Navigate to Settings > API Keys
4. Create a new API key

### Claude Desktop Configuration

#### Local Mode

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```json
{
  "mcpServers": {
    "slidefast": {
      "command": "uvx",
      "args": ["slidefast-mcp"],
      "env": {
        "SLIDEFAST_API_KEY": "sk-sf-your-api-key"
      }
    }
  }
}
```

Or if installed via pip:

```json
{
  "mcpServers": {
    "slidefast": {
      "command": "slidefast-mcp",
      "env": {
        "SLIDEFAST_API_KEY": "sk-sf-your-api-key"
      }
    }
  }
}
```

#### Remote Mode

```json
{
  "mcpServers": {
    "slidefast": {
      "url": "https://mcp.slidefast.io/mcp"
    }
  }
}
```

Legacy clients without OAuth discovery may continue to send `Authorization: Bearer sk-sf-your-api-key`.

### Claude Code Configuration

For Claude Code CLI, add to your MCP settings:

```json
{
  "mcpServers": {
    "slidefast": {
      "command": "uvx",
      "args": ["slidefast-mcp"],
      "env": {
        "SLIDEFAST_API_KEY": "sk-sf-your-api-key"
      }
    }
  }
}
```

## CLI

The same package installs a `slidefast` command. It talks to the same public API with the
same key, and every subcommand takes `--json` for machine-readable output.

```bash
uv tool install slidefast-mcp     # or: pipx install slidefast-mcp

slidefast auth login --api-key sk-sf-...   # verified, then stored in ~/.slidefast/config.json
slidefast projects list
slidefast presentations create "5 hiring myths"
slidefast chat <deck-id> "8-slide carousel on hiring myths for founders"
slidefast chat <deck-id> "tighten slide 3"            # dry run: prints unsaved suggestions
slidefast chat <deck-id> "tighten slide 3" --apply    # writes it
slidefast review-link <deck-id> create                # client approval URL
slidefast presentations export <deck-id> --format pdf
slidefast publish <deck-id> --platform linkedin
```

Global flags, accepted before or after the subcommand: `--json`, `--project <uuid>`,
`--api-key`, `--base-url`. Exit codes: 0 success, 1 API or config error, 2 bad usage.

## Projects

Presentations, themes, brand kits and social accounts all live inside a **project** (one per
client). List and create calls resolve a project in this order:

1. the API key's **pin**, if it has one (set in the dashboard under Settings > API Keys). A
   pinned key is a hard boundary: a conflicting `project_id` is rejected with 403.
2. the per-call `project_id` argument (`X-Project-Id` header), for unpinned keys.
3. the account's default project.

Every project-scoped tool takes an optional `project_id`, deliberately per call rather than a
stateful "active project" - agent callers are stateless and often concurrent. Row access by id
is never project-scoped, so reading a deck you own always works.

## Available Tools

| Tool | Description |
|------|-------------|
| `slidefast_check_rate_limit` | Check your API usage and limits |
| `slidefast_get_usage` | Get monthly usage stats by resource |
| `slidefast_get_me` | Get the authenticated user profile |
| `slidefast_list_projects` | List projects (client workspaces) |
| `slidefast_create_project` | Create a project |
| `slidefast_get_active_project` | Which project this call would act in |
| `slidefast_list_presentations` | List presentations with pagination, sorting, and tag filters |
| `slidefast_create_presentation` | Create a new presentation |
| `slidefast_get_presentation_tags` | List distinct presentation tags |
| `slidefast_get_presentation` | Get presentation by ID |
| `slidefast_update_presentation` | Update presentation (title, slides, theme, tags, status) |
| `slidefast_duplicate_presentation` | Duplicate a presentation |
| `slidefast_delete_presentation` | Delete a presentation |
| `slidefast_enable_share` | Enable public sharing for a presentation |
| `slidefast_disable_share` | Disable public sharing for a presentation |
| `slidefast_generate_share_metadata` | Generate platform-specific social metadata |
| `slidefast_update_share_metadata` | Manually update metadata for one platform |
| `slidefast_chat` | Chat with AI to generate/modify slides |
| `slidefast_get_chat_history` | Get conversation history |
| `slidefast_clear_chat_history` | Clear conversation history |
| `slidefast_translate_slides` | Translate slides to another language |
| `slidefast_export_png_zip` | Export all slides as PNG ZIP (returns download URL) |
| `slidefast_export_pdf` | Export as PDF (returns download URL) |
| `slidefast_export_slide_png` | Export single slide as PNG (returns download URL) |
| `slidefast_list_themes` | List themes |
| `slidefast_create_theme` | Create a theme |
| `slidefast_get_theme` | Get a theme |
| `slidefast_update_theme` | Update a theme |
| `slidefast_delete_theme` | Delete a theme |
| `slidefast_duplicate_theme` | Duplicate a theme |
| `slidefast_set_default_theme` | Set the default theme |
| `slidefast_get_brand_kit` | The project's colours, fonts and logos |
| `slidefast_list_library_images` | List library images |
| `slidefast_search_library_images` | Semantic search over library images |
| `slidefast_upload_library_image` | Upload a base64-encoded image to the library |
| `slidefast_generate_background_image` | Generate AI background photos into the library |
| `slidefast_delete_library_image` | Delete a library image |
| `slidefast_upload_presentation_image` | Upload a base64-encoded image for slides |
| `slidefast_get_social_connections` | Which platforms are connected, and the targets you can publish to |
| `slidefast_publish_linkedin` | Publish a carousel to a LinkedIn profile or Page (**public**) |
| `slidefast_publish_tiktok` | Publish a carousel to TikTok — **draft to the creator's inbox by default** |
| `slidefast_publish_meta` | Publish a carousel to a Facebook Page or Instagram (**public**) |
| `slidefast_list_social_posts` | History of every publish attempt |
| `slidefast_get_social_post` | Poll one publish attempt to completion |
| `slidefast_get_tiktok_publish_status` | Ask TikTok directly about a `publish_id` |
| `slidefast_get_review_link` | The deck's client review link, or null |
| `slidefast_create_review_link` | Create a no-login client approval URL (Agency plan) |
| `slidefast_rotate_review_link` | New token, killing the URL already sent |
| `slidefast_revoke_review_link` | Revoke the review link |
| `slidefast_get_review_thread` | Review status plus every client comment |

## Social Publishing

Publishing is asynchronous. A publish tool returns a social post record straight away with
`status: "pending"`; poll `slidefast_get_social_post` until it reads `published` or `failed`.

**What goes public, and what does not:**

| Tool | Result |
|------|--------|
| `slidefast_publish_tiktok` with `mode="MEDIA_UPLOAD"` (default) | **Draft.** The slides land in the creator's TikTok inbox. Nothing is public until they post it from the TikTok app. |
| `slidefast_publish_tiktok` with `mode="DIRECT_POST"` | **Live immediately.** Requires a `privacy_level` from `creator_info.privacy_level_options`. |
| `slidefast_publish_linkedin` | **Live immediately.** LinkedIn has no draft mode. |
| `slidefast_publish_meta` | **Live immediately.** Facebook and Instagram have no draft mode here. |

Call `slidefast_get_social_connections` first: it returns the LinkedIn profile and Page targets,
the connected TikTok accounts with the privacy options a direct post may use, and the Facebook
Page / Instagram `destination_id` values. Access tokens are never returned.

Connecting an account is a browser OAuth flow and cannot be done over the API or MCP. An
unconnected platform answers `409` with a `connect_url` — pass that URL to the user so they can
click Connect in the Slidefast web app.

Publishing is rate limited to 12 attempts per hour, and every attempt is recorded in
`slidefast_list_social_posts` whether it succeeded or not. Pass the same `idempotency_key` when
retrying so a flaky connection cannot post twice.

## Chat: dry run vs apply

`slidefast_chat` (and `slidefast chat`) takes a `mode`:

- **`default`** - a dry run for *edits*. Changes to existing slides come back as
  `suggestions[]` and are **not** saved. Re-send the same message with `mode="apply"` to
  commit them.
- **`apply`** - the edits are written and returned as `changes[]`.
- **The exception**: a turn that writes a *whole deck* ("make me a carousel about X") is saved
  in either mode, because a creation is not a proposal. The response says
  `slides_generated: true`.

Each turn costs one AI message against the monthly quota in both modes.

## Tool Parameter Notes

MCP clients can pass structured objects directly for `slides`, `theme`, `display_settings`, `slides_context`, and theme payloads. Legacy JSON strings are still accepted for compatibility.

Image upload tools accept base64-encoded image bytes plus `filename` and `content_type`. For example:

```json
{
  "image_base64": "iVBORw0KGgo...",
  "filename": "brand-mark.png",
  "content_type": "image/png"
}
```

`slidefast_chat` supports `slide_count`, `emoji_mode`, `hook_categories`, and `mode`. Use `mode: "apply"` when you want suggested edits applied directly to the presentation.

## Usage Examples

### Create a Presentation and Generate Slides

```
User: Create a presentation about climate change and generate 5 slides

Claude: I'll create a presentation and generate slides about climate change.

[Uses slidefast_create_presentation to create "Climate Change" presentation]
[Uses slidefast_chat with the message "Create 5 slides about climate change, its causes, effects, and solutions"]
```

### Export a Presentation

```
User: Export my presentation as PDF

Claude: I'll export your presentation as a PDF.

[Uses slidefast_export_pdf with the presentation ID]
[Returns: { url: "https://cdn.slidefast.io/exports/.../presentation.pdf", filename: "My Presentation.pdf", size: 123456 }]
```

### Modify Existing Slides

```
User: Make the second slide more engaging

Claude: I'll ask the AI to improve the second slide.

[Uses slidefast_chat with "Make slide 2 more engaging with better copy"]
```

### Send a Carousel to TikTok as a Draft

```
User: Send my latest carousel to TikTok so I can review it before posting

Claude: I'll upload it to your TikTok inbox as a draft — nothing will be public.

[Uses slidefast_get_social_connections to confirm TikTok is connected]
[Uses slidefast_publish_tiktok with the default mode="MEDIA_UPLOAD"]
[Uses slidefast_get_social_post to poll until status is "published"]
[Reports: the draft is waiting in your TikTok inbox — open the app to post it]
```

### Publish to a LinkedIn Page

```
User: Post this carousel on our company page

Claude: That will go live on the Page immediately — confirming before I post.

[Uses slidefast_get_social_connections to find the organization target]
[Uses slidefast_publish_linkedin with destination_type="organization" and the organization_id]
[Uses slidefast_get_social_post to poll, then returns the external_post_url]
```

## Slide Types

When creating or modifying slides, these types are available:

- `cover` - Title/cover slide
- `content` - General content slide
- `quote` - Quote with attribution
- `cta` - Call-to-action slide
- `stat` - Statistics highlight
- `comparison` - Side-by-side comparison
- `steps` - Step-by-step process
- `feature` - Feature highlight
- `bullet-list` - Bulleted list
- `big-text` - Large text emphasis

## Theme Configuration

Themes require these fields (all colors in #RRGGBB format):

```json
{
  "id": "custom-theme",
  "name": "My Theme",
  "background": "#FFFFFF",
  "accent": "#3B82F6",
  "text": "#1F2937",
  "textSecondary": "#6B7280",
  "borderColor": "#E5E7EB"
}
```

## Self-Hosting the Remote Server

To run your own remote MCP server:

1. Clone the repository
2. Build the Docker image:
   ```bash
   cd slidefast-mcp
   docker build -t slidefast-mcp .
   ```
3. Run the container:
   ```bash
   docker run -p 8080:8080 slidefast-mcp
   ```

Or add to your docker-compose:

```yaml
services:
  mcp:
    build:
      context: ./slidefast-mcp
    ports:
      - "8080:8080"
    environment:
      - SLIDEFAST_API_BASE_URL=https://slidefast.io/api/v1/public
```

The remote server exposes:

- `GET /health` for container and load balancer checks
- `POST /mcp` for Streamable HTTP MCP clients

For remote mode, clients should send the Slidefast API key as:

```http
Authorization: Bearer sk-sf-your-api-key
```

For local stdio mode, set `SLIDEFAST_API_KEY`.

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `SLIDEFAST_API_KEY` | Your Slidefast API key | Required for local mode |
| `SLIDEFAST_API_BASE_URL` | API base URL | `https://slidefast.io/api/v1/public` |
| `HOST` | Server host (remote mode) | `0.0.0.0` |
| `PORT` | Server port (remote mode) | `8080` |

## Development

```bash
# Clone the repo
git clone https://github.com/lorisalx/slidefast-mcp.git
cd slidefast-mcp

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest
# or, when using uv:
uv run pytest

# Run locally
SLIDEFAST_API_KEY=sk-sf-xxx slidefast-mcp
```

## Troubleshooting

- `No API key found`: set `SLIDEFAST_API_KEY` for stdio mode, or send `Authorization: Bearer sk-sf-...` for remote mode.
- `Authentication failed`: the key is missing, malformed, revoked, or belongs to another environment.
- `Payment required` / `402`: the account has reached a plan limit for presentations, exports, assets, or AI messages.
- `Rate limit exceeded` / `429`: wait for the API key rate limit window to reset or use `slidefast_check_rate_limit`.
- Export tools return public CDN URLs when successful. These URLs are public, not expiring signed URLs.

## License

MIT License - see [LICENSE](LICENSE) for details.

## Links

- [Slidefast](https://slidefast.io) - AI-powered presentation creator
- [MCP Protocol](https://modelcontextprotocol.io) - Model Context Protocol specification
- [FastMCP](https://gofastmcp.com) - FastMCP framework documentation
