Skip to main content
Glama

HiggsHole

A self-hosted AI image and video generation console with a browsable media library, backed by the OpenRouter API and exposed to local AI agents over MCP.

Status: implemented. Web UI, REST API, MCP server and systemd unit are in place and covered by an offline test suite. See the design specification.

What it does

  • Text-to-image, text-to-video, image-to-image and image-to-video generation through a single OpenRouter API key

  • Model picker built from OpenRouter's live capability catalogue — no hardcoded model list, so new models appear without a code change

  • Generated media stored on local disk with metadata embedded in the files themselves, browsable and playable in the web UI

  • Any result can be fed back in as a reference for an edit or improvement pass, with the lineage recorded

  • An MCP server (stdio) exposing the same functionality to locally running AI agents

  • Spend controls: provider-enforced key limits, a local ledger of actual costs, and a daily cap

Related MCP server: openrouter-image-gen-mcp

What it deliberately does not do

  • No prompt rewriting — prompts are passed to the provider verbatim

  • No authentication — intended for a trusted LAN

  • No multi-user support

  • No batch generation — n is fixed at 1 so every generation has its own cost record

Quick start

uv sync
uv run pytest -q          # the whole suite, offline and free
uv run higgshole          # serves http://127.0.0.1:8077

The suite makes no network requests and costs nothing: a socket-blocking fixture enforces that rather than trusting convention. The single billable test is opt-in behind HIGGSHOLE_LIVE_TESTS and skipped by default.

MCP tools

Eleven tools, each a thin translation of one REST call — see docs/mcp.md for client registration:

Tool

Behaviour

list_models

Image and video models with capability constraints

generate_image

Synchronous; returns the finished asset

generate_video

Returns a job ID immediately — does not block

get_job

Status, with optional bounded long-polling

upload_asset

Ingests a local file, returning a reusable asset ID

list_media

Browse with filters

get_media

Full metadata for one item, including lineage

delete_media

Removes a generation, its files and its thumbnails

list_projects

Enumerate projects

create_project

Create a project

get_budget

Provider-authoritative credit plus local cap status

Every asset-returning tool provides both the local filesystem path and the HTTP URL, since agents run on the same host. Costs are strings or null — never 0 to represent an unknown cost.

Design notes

The specification records several verified corrections to OpenRouter's published documentation, including the true job-status enumeration, the unreliability of client-side video cost estimation, and the ephemerality of result URLs. These were established against the live API and its OpenAPI specification rather than the prose docs, which contradict it in places.

Requirements

  • Python 3.12+

  • ffmpeg / ffprobe

  • An OpenRouter API key

Runs anywhere Python and ffmpeg run. A systemd unit is provided for boot-time startup on Linux — see docs/deployment.md — but nothing in the architecture depends on it.

Configuration

Everything is configured through environment variables, readable from a .env file — see .env.example for the full list with defaults. By default the app writes under ${XDG_DATA_HOME:-~/.local/share}/higgshole and ${XDG_STATE_HOME:-~/.local/state}/higgshole and binds to 127.0.0.1, so a fresh clone runs unprivileged with no setup.

Exposing it to your local network is a deliberate act: change HIGGSHOLE_BIND_HOST. There is no authentication, by design.

If you set a daily spend cap, also set a credit limit on the OpenRouter key itself. That limit is enforced provider-side and is the only guard that cannot be defeated by a bug in this application.

Licence

MIT

Available Tools

11 tools
create_projectC

Create a project and return its slug.

Inputs: name (required).

delete_mediaB

Delete a generation together with its files and thumbnails.

Inputs: generation_id (required).

generate_imageA

Generate one image synchronously and return the finished asset with both its local filesystem path and its HTTP URL. Blocks until the image exists. Batch generation is not supported.

Inputs: model (required), prompt (required), n, seed, +7 more.

generate_videoA

Submit a video generation job and return its ID immediately. Does NOT wait for the render; poll with get_job.

Inputs: model (required), prompt (required), seed, project, +7 more.

get_budgetA

Provider-authoritative remaining credit plus local daily-cap status. Amounts are strings or null; null means the cost is unknown, never zero.

Inputs: no named parameters.

get_jobA

Fetch a generation's current state, optionally long-polling for up to wait_seconds. Returns the finished asset once the state is COMPLETE.

Inputs: generation_id (required), wait_seconds.

get_mediaB

Full metadata for one generation, including its input lineage.

Inputs: generation_id (required).

list_mediaB

Browse the library with optional project, kind, model and date filters.

Inputs: kind, limit, model, offset, +3 more.

list_modelsA

List available image and video models with their capability constraints. Read this before generating: supported resolutions, durations, aspect ratios and reference-image slots differ per model.

Inputs: kind.

list_projectsB

List projects. 'unsorted' always exists.

Inputs: no named parameters.

upload_assetA

Ingest a local file into a project's uploads directory and return an asset ID usable as an image reference or a video frame.

Inputs: path (required), project.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 11 tools

    Disambiguation5/5

    Each tool targets a distinct resource and action: models, projects, image/video generation, job polling, asset upload, media browsing, and budget. No overlapping purposes.

    Naming Consistency5/5

    All tool names follow the verb_noun pattern in snake_case, e.g., list_models, generate_image, get_job. Consistent and predictable.

    Tool Count5/5

    11 tools cover the core domain of media generation, project management, asset handling, and budget info without unnecessary bloat or omissions.

    Completeness4/5

    Core generation workflows are fully covered, but missing delete_project, list/delete uploaded assets, and get_project are minor gaps that agents can work around.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers