web-interface-provisioner-mcp
Orchestrate and present custom front-end web applications locally, utilizing standard web technologies (HTML, CSS, JavaScript) for rapid prototyping and iteration of software housed within a designated workspace directory.
Author

michaelneale
Quick Info
Actions
Tags
Goose Web App Fabricator
This MCP (Model Context Protocol) utility furnishes users with the capability to devise, maintain, and host interactive web interfaces that leverage the Goose framework for backend communication, data interaction, and auxiliary services.
Installation Guide
Initiate installation within the Goose environment by clicking here 🪿 🪿🪿🪿🪿🪿🪿🪿🪿🪿
Core Capabilities
- Generate novel web projects based on high-level directives
- Persistent storage for artifacts within
~/.config/goose/app-maker-apps(each project isolated in a subdirectory) - On-demand local hosting of generated applications
- Automated launch of hosted applications in the default web browser (headless mode preferred where feasible)
- Cataloging of all currently available user-created web interfaces
- Enable construction of applications capable of utilizing Goose as a generalized persistence layer
Operational Demonstrations
Data Retrieval via Goose Infrastructure (Reusing Existing Extensions)
Goose maintains a registry of your deployed applications:
Expedient Application Scaffolding
Displaying Structured Data (Lists or Tabular Formats)
Local Source Execution Notes
eg within the Goose environment:
# Execute directly from the source repository
uv --directory $PWD run python main.py
CRITICAL NOTE: This MCP currently mandates execution within the Goose desktop application due to its reliance on internal Goose APIs (goose-server/goosed).
Development and Distribution Workflow
Optional: Environment Setup using uv for Building
uv venv .venv
source .venv/bin/activate
uv pip install build
python -m build
Deployment Steps
- Increment the version number within
pyproject.toml:
[project]
version = "x.y.z" # Update this value
- Perform the package construction:
# Clear any prior build artifacts
rm -rf dist/*
python -m build
- Upload artifacts to the Python Package Index (PyPI):
# Install twine if it is not yet present
uv pip install twine
# Transmit package archives to PyPI
python -m twine upload dist/*
Internal Mechanics
This utility facilitates the hosting of front-end interfaces while simultaneously permitting them to communicate with the core Goose system via goosed within their isolated session contexts.
Architectural Overview
The architecture employs a non-blocking, asynchronous request-response mechanism enabling client web applications to transmit queries to Goose and receive results without stalling the primary processing thread. This is accomplished via the synergistic combination of:
- A dedicated synchronous receiving endpoint on the server infrastructure.
- Asynchronous scripting logic implemented in the client-side JavaScript.
- A robust storage system paired with thread coordination primitives.
Web Interface Directory Structure
Applications are initialized (or retrieved) based on predefined templates and resources. Each application resides in its unique folder under ~/.config/goose/app-maker-apps adhering to the following layout:
app-name/
├── goose-app-manifest.json # Metadata defining the application
├── index.html # Primary entry point file
├── style.css # Cascading Style Sheets for presentation
├── script.js # Application logic scripts
└── goose_api.js # Interface library enabling access to Goose backend services
└── ... # Supplementary application assets
The goose-app-manifest.json file encapsulates vital application metadata, specifically:
- name: Human-readable title for display
- type: Categorization of the application structure (e.g., "static", "react", etc.)
- description: Succinct summary of the application's purpose
- created: Timestamp marking the time of initial creation
- files: Inventory list of all contained resources
1. Client-Side Transaction Sequence
When the client-side code requires data from the Goose backend:
┌─────────┐ ┌─────────────────────┐ ┌───────────────────┐ ┌──────────────────────┐
│ User │────▶│ requestFunction() │────▶│ Goose Backend API │────▶│ Blocking Listener │
│ Action │ │ (text/list/tabular) │ │ (/reply endpoint) │ │ Endpoint │
└─────────┘ └─────────────────────┘ └───────────────────┘ └──────────────────────┘
│
▲
│
└──────Synchronous Return Path (Response Received)───────────┘
- An interaction triggers a client action (e.g., button click).
- The relevant client function (
gooseRequestText,gooseRequestList, orgooseRequestTable) is invoked. - This function generates a unique identifier (
responseId) and transmits a command to Goose, instructing it to invokeapp_responseusing this ID. - Subsequently, the function halts execution by calling
waitForResponse(responseId), which begins polling the/wait_for_response/{responseId}URL. - This specific URL handler pauses the current thread until the result is populated or a predetermined wait time elapses.
- Upon availability, the resultant data is delivered back to the client context for visualization.
2. Server-Side Result Handling
Processing flow on the host server:
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
│ HTTP Handler │────▶│ app_response │────▶│ Result Synchronization │
│ (Thread Awaiting)│◀────│ (Result Storage) │◀────│ (Wakes up Blocked Await)│
└──────────────────┘ └──────────────────┘ └──────────────────────┘
- The server endpoint responding to
/wait_for_response/{responseId}utilizes synchronization primitives (condition variables) to pause until data is ready. - After Goose successfully processes the external request, it executes the
app_responseroutine, passing the payload and the associatedresponseId. - The
app_responseroutine commits the data to an internal map (app_responses) and signals any threads currently suspended on the associated condition variable. - The paused HTTP request thread is then released, transmitting the fetched result back to the waiting client.
3. Thread Synchronization Mechanism
The system relies on Python's threading.Condition objects for managing concurrency:
- If a request is made for data that has not yet materialized, a dedicated condition variable is instantiated for that
responseId. - The thread handling the incoming HTTP request enters a waiting state, conditioned on the timeout (defaulting to 30 seconds).
- When the processing completes on the Goose side, the condition is triggered.
- If the imposed time limit is reached before a response materializes, an indication of failure or timeout is transmitted instead.
Essential Building Blocks
Client-Side Invocation Routines
gooseRequestText(query): Initiates a query expecting a textual reply.gooseRequestList(query): Initiates a query expecting an array/list structure.gooseRequestTable(query, columns): Initiates a query expecting structured data requiring specified column headers.waitForResponse(responseId): A synchronous utility for polling and retrieving the result identified byresponseId.
Server-Side Handlers
app_response(response_id, string_data, list_data, table_data): The function responsible for logging the received payload and activating waiting threads.- HTTP Listener for
/wait_for_response/{responseId}: Manages the blocking I/O operation until the associated result is ready for dispatch.
