Skip to main content
Glama

Scenic MCP

Scenic MCP

Model Context Protocol (MCP) server for Scenic GUI applications

Version: 1.0.0

Enable AI assistants to interact with Scenic GUI applications through keyboard input, mouse control, and visual feedback. Perfect for automated testing, AI-driven development workflows, and accessibility tools.

Features

  • šŸŽ¹ Keyboard Input - Send text and special keys with modifier support (Ctrl, Shift, Alt, Cmd)

  • šŸ–±ļø Mouse Control - Move cursor and click at specific coordinates

  • šŸ“ø Visual Feedback - Inspect viewport structure and capture screenshots

  • šŸ¤– MCP Integration - Works with Claude Desktop, Claude Code, and other MCP clients

Quick Start

1. Add to your Scenic app's mix.exs

Note this is still not actually published to hex so you need to clone it and add it as a local dep for now.

defp deps do [ {:scenic_mcp, "../scenic_mcp"} ] end

2. Configure your viewport and driver

Scenic MCP requires named viewport and driver processes. Update your supervision tree:

# In your application.ex def start(_type, _args) do children = [ {Scenic, scenic_viewport_config()} ] Supervisor.start_link(children, strategy: :one_for_one) end defp scenic_viewport_config do [ name: :main_viewport, # Required! size: {800, 600}, default_scene: MyApp.RootScene, drivers: [ [ name: :scenic_driver, # Required! module: Scenic.Driver.Local, window: [title: "My App"], on_close: :stop_system ] ] ] end

Note that name here defines the atom which will become the registered process name for the ViewPort and Driver processes. We need to know this in order to find the pid of this process in order to interact with the ViewPort, and our solution was to look for this specific name main_viewport so you need to set this in your config as above for ScenicMCP to work.

Viewport name: :main_viewport Driver name: :scenic_driver

Optional: Custom process names

If you need different process names, configure them:

# config/config.exs config :scenic_mcp, viewport_name: :my_custom_viewport, driver_name: :my_custom_driver, port: 9999

3. Install TypeScript dependencies

cd scenic_mcp npm install npm run build

4. Configure Claude Code or Claude Desktop

Using Claude Code CLI (Recommended)

claude mcp add scenic-mcp /path/to/scenic_mcp/dist/index.js claude mcp list # Verify installation

Manual Configuration

Edit ~/.claude.json:

{ "projects": { "/path/to/your/project": { "mcpServers": { "scenic-mcp": { "type": "stdio", "command": "/path/to/scenic_mcp/dist/index.js", "args": [], "env": {} } } } } }

Optional: Tidewave MCP Configuration

Tidewave provides runtime introspection for Elixir/Phoenix apps (logs, SQL queries, code evaluation, docs). If your project includes Tidewave (Flamelex/Quillex do), add this to the same project config:

{ "projects": { "/path/to/your/project": { "mcpServers": { "scenic-mcp": { "type": "stdio", "command": "/path/to/scenic_mcp/dist/index.js", "args": [], "env": {} }, "tidewave": { "type": "http", "url": "http://localhost:4000/tidewave/mcp" } } } } }

5. Start your Scenic app

cd your_scenic_app iex -S mix

You should see:

āœ… ScenicMCP successfully started on port 9999

Usage

Available Tools

Connection & Status

  • connect_scenic - Establish connection to running Scenic app

  • get_scenic_status - Check connection status and server info

User Input

  • send_keys - Send keyboard input (text, special keys, modifiers)

  • send_mouse_move - Move cursor to coordinates

  • send_mouse_click - Click at coordinates (left/right/middle button)

Visual Feedback

  • inspect_viewport - Get text description of viewport structure

  • take_screenshot - Capture PNG screenshot (path or base64)

Examples

Text Input

send_keys({ text: "Hello, World!" })

Special Keys

send_keys({ key: "enter" }) send_keys({ key: "escape" }) send_keys({ key: "tab" })

Keyboard Shortcuts

send_keys({ key: "s", modifiers: ["ctrl"] }) // Ctrl+S (Save) send_keys({ key: "c", modifiers: ["cmd"] }) // Cmd+C (Copy on Mac) send_keys({ key: "z", modifiers: ["ctrl", "shift"] }) // Ctrl+Shift+Z (Redo)

Mouse Control

send_mouse_move({ x: 100, y: 200 }) send_mouse_click({ x: 150, y: 250, button: "left" }) send_mouse_click({ x: 300, y: 100, button: "right" }) // Right-click

Visual Inspection

inspect_viewport() // Get component structure take_screenshot({ format: "path" }) // Save to /tmp take_screenshot({ filename: "app_state.png", format: "base64" // Get base64 data })

Architecture

AI Agent (Claude Desktop/Code) ↓ stdio TypeScript MCP Server (this package) ↓ TCP (port 9999) Elixir GenServer (ScenicMcp.Server) ↓ function calls Scenic Driver Process ↓ input events Your Scenic Application

How It Works

  1. TypeScript MCP Server handles MCP protocol via stdio

  2. TCP Bridge maintains persistent connection to Elixir

  3. Elixir GenServer receives JSON commands over TCP

  4. Tool Handlers interact with Scenic viewport and driver

  5. Driver injects input events into your application

Configuration

Available Options

# config/config.exs config :scenic_mcp, # TCP port for MCP server (default: 9999) port: 9999, # Viewport process name (default: :main_viewport) viewport_name: :main_viewport, # Driver process name (default: :scenic_driver) driver_name: :scenic_driver, # Application name for logging (default: "Unknown") app_name: "MyApp"

Multiple Scenic Apps

If you're running multiple Scenic apps, configure unique ports:

# In flamelex/config/config.exs config :scenic_mcp, port: 9999, app_name: "Flamelex" # In quillex/config/config.exs config :scenic_mcp, port: 9997, app_name: "Quillex" # In your_test/config/test.exs config :scenic_mcp, port: 9996, app_name: "Test"

Connect to specific ports:

connect_scenic({ port: 9997 }) // Connect to Quillex

Development

Build TypeScript

npm run build # One-time build npm run dev # Watch mode for development

Bundle for Distribution

npm run bundle # Copies dist/* to priv/mcp_server/

Run Tests

# Elixir tests mix test # Test specific file mix test test/scenic_mcp/server_test.exs

Project Structure

scenic_mcp/ ā”œā”€ā”€ lib/ │ ā”œā”€ā”€ scenic_mcp.ex # Module documentation │ └── scenic_mcp/ │ ā”œā”€ā”€ application.ex # OTP application │ ā”œā”€ā”€ config.ex # Configuration management │ ā”œā”€ā”€ server.ex # TCP server (GenServer) │ └── tools.ex # Tool handlers ā”œā”€ā”€ src/ │ ā”œā”€ā”€ index.ts # MCP server entry point │ ā”œā”€ā”€ connection.ts # TCP connection management │ └── tools.ts # Tool definitions ā”œā”€ā”€ test/ │ └── scenic_mcp/ │ └── server_test.exs # Integration tests └── dist/ # Compiled TypeScript

Troubleshooting

Port Already in Use

Error: Port 9999 is already in use!

Solution: Configure a different port in your config.exs:

config :scenic_mcp, port: 9998

Cannot Find Viewport

Error: Unable to find Scenic viewport process ':main_viewport'

Solutions:

  1. Ensure your viewport is named: name: :main_viewport in your Scenic config

  2. Or configure the expected name: config :scenic_mcp, viewport_name: :your_name

  3. Verify your Scenic app is running: Process.whereis(:main_viewport)

Cannot Find Driver

Error: Unable to find Scenic driver process ':scenic_driver'

Solutions:

  1. Ensure your driver is named: name: :scenic_driver in your driver config

  2. Or configure the expected name: config :scenic_mcp, driver_name: :your_name

  3. Check driver started: Process.whereis(:scenic_driver)

Connection Timeout

Error: Command timeout after 5000ms

Solutions:

  1. Check if Scenic app is running

  2. Verify correct port: connect_scenic({ port: YOUR_PORT })

  3. Check firewall settings (should allow localhost:9999)

Tests Failing

If tests fail with connection errors:

  1. Ensure no other apps are using test ports (9996-9998)

  2. Run tests with: mix test --trace for detailed output

  3. Check that scenic_driver_local dependency is properly compiled

Security Considerations

āš ļø Important Security Notes:

  • Scenic MCP binds to localhost only - not accessible from external networks

  • No authentication - anyone with local access can control your app

  • Intended for development and testing environments only

  • Do not expose the TCP port (9999) to untrusted networks

  • Do not use in production without additional security measures

See SECURITY.md for detailed security guidelines.

Integration Guide

See docs/INTEGRATION.md for step-by-step integration instructions, including:

  • Adding Scenic MCP to existing applications

  • Common patterns and best practices

  • Testing strategies

  • Example implementations

API Reference

Error Handling

All tool functions return consistent error structures:

{ "error": "Descriptive error message with context and potential solutions" }

Success responses include a status field:

{ "status": "ok", "message": "Operation completed successfully", ...additional data... }

Contributing

Contributions are welcome! Please:

  1. Fork the repository

  2. Create a feature branch

  3. Add tests for new functionality

  4. Ensure mix test passes

  5. Submit a pull request

Requirements

  • Elixir ~> 1.14

  • Erlang/OTP 24+

  • Node.js >= 18.0

  • Scenic ~> 0.11

  • Claude Desktop or Claude Code (for MCP client)

License

MIT License - see LICENSE for details

Related Projects

  • Scenic - 2D UI framework for Elixir

  • MCP - Model Context Protocol specification

  • Tidewave - Elixir/Phoenix MCP tools

Changelog

See CHANGELOG.md for version history.

Support


Made with ā¤ļø for the Elixir and Scenic communities

Related MCP Servers

  • -
    security
    F
    license
    -
    quality
    A demonstration implementation of the Model Context Protocol server that facilitates communication between AI models and external tools while maintaining context awareness.
    Last updated -
    • Linux
    • Apple
  • -
    security
    F
    license
    -
    quality
    Implements a Model Context Protocol server that provides context from CucumberStudio to AI assistants, enabling them to fetch data and generate or modify test scenarios, features, and other CucumberStudio resources.
    Last updated -
  • -
    security
    F
    license
    -
    quality
    A Model Context Protocol server that enables integration with the TESS API, allowing users to list and manage agents, execute agents with custom messages, and manage files through natural language interfaces.
    Last updated -
  • A
    security
    F
    license
    A
    quality
    A Model Context Protocol server that enables generating and executing Elisp code in a running Emacs process, allowing AI assistants to control and interact with Emacs.
    Last updated -
    2
    30

View all related MCP servers

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/scenic-contrib/scenic_mcp_experimental'

If you have feedback or need assistance with the MCP directory API, please join our Discord server