MCP Server

Reading Time: 10 minutes Goal: Connect an AI coding assistant to Instruct UI and generate Blazor components from your editor


Overview

Instruct UI exposes its Blazor code generation capabilities as a Model Context Protocol (MCP) server. AI coding assistants — Claude Code, Cursor, VS Code Copilot, and others — can connect to it directly to generate, compile, and download Blazor components without leaving the editor.


API Keys

Every request to the MCP server must be authenticated with an API key.

Format

Keys have the prefix iui_ followed by 40 random characters:

iui_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

The full key is shown only once at creation time. Copy it immediately.

Managing Keys

Manage your keys from the dashboard under Settings → API Keys.

Action How
Create Enter a name → Create → copy the key
List View all active and revoked keys
Revoke Click Revoke on any active key

Revoked keys are rejected immediately. Keys remain valid until explicitly revoked — there is no time-based expiry.


Connecting an MCP Client

The MCP server is a Streamable HTTP endpoint at:

https://instructui.com/mcp

Authentication uses a Bearer token in the Authorization header.

Claude Code

Add an entry to your project's .mcp.json (or global ~/.claude/mcp.json):

{
  "mcpServers": {
    "instructui": {
      "type": "http",
      "url": "https://instructui.com/mcp",
      "headers": {
        "Authorization": "Bearer iui_your_api_key_here"
      }
    }
  }
}

Cursor / VS Code Copilot

Use your editor's MCP settings UI and set:

  • Transport: HTTP
  • URL: https://instructui.com/mcp
  • Header: Authorization: Bearer iui_your_api_key_here

Workflow

The standard generation flow is three steps:

1. generate_blazor_component   →  returns conversation_id
2. wait_for_generation         →  blocks until done (up to 300s)
3. get_generation_result       →  returns code files

If wait_for_generation times out, call it again — it resumes waiting on the same generation.

Example prompt to your AI assistant:

Generate a MudBlazor data table with sorting, filtering, and pagination for a list of customers. Use get_generation_result to show me the files when done.


Tools

generate_blazor_component

Starts an async Blazor component generation. Returns immediately with a conversation_id.

Parameters

Name Type Required Description
prompt string Yes Text description of the UI to generate
library string No* default-blazor, mudblazor, syncfusion
css_framework string No* bootstrap, tailwind, none
image_base64 string No Base64-encoded screenshot or mockup
image_mime_type string No MIME type of the image (default: image/png)
conversation_id string No Existing ID for follow-up requests

*library and css_framework are required when starting a new generation (no conversation_id). For follow-up requests, omit them or pass the same values as the original conversation — they cannot be changed mid-conversation.

Valid library + CSS framework combinations

Library Accepted CSS frameworks
default-blazor bootstrap, tailwind, none
mudblazor bootstrap, tailwind, none
syncfusion bootstrap, tailwind

Library aliases (case-insensitive): default, defaultblazor, default blazor, mud, mudblazor, mud blazor, sf, sync fusion.

CSS framework aliases (case-insensitive): tailwindcss, tailwind css, tailwind, bootstrap, none.

Response

{
  "conversation_id": "01JNQX...",
  "status": "queued"
}

wait_for_generation

Blocks until the generation completes or fails. Uses server-sent events internally — more efficient than polling.

Parameters

Name Type Required Description
conversation_id string Yes From generate_blazor_component
timeout_seconds int No Max wait time (default: 120, max: 300)

Response (completed)

{
  "conversation_id": "01JNQX...",
  "status": "completed",
  "compile_success": true
}

Response (timed out)

{
  "conversation_id": "01JNQX...",
  "status": "generating",
  "timed_out": true,
  "progress_message": "Generation still in progress. Call again to continue waiting."
}

Response (failed)

{
  "conversation_id": "01JNQX...",
  "status": "failed",
  "error": "Generation failed"
}

get_generation_result

Returns the full generation output including all code files. Call this after wait_for_generation reports completed. If called before generation has finished, returns HTTP 404 ("No generation result found").

Parameters

Name Type Required Description
conversation_id string Yes From generate_blazor_component

Response

{
  "conversation_id": "01JNQX...",
  "status": "completed",
  "files": [
    { "name": "Components/MyDashboard.razor", "code": "...", "type": "Razor" },
    { "name": "Components/MyDashboard.razor.css", "code": "...", "type": "RazorCss" }
  ],
  "compile_success": true,
  "compile_errors": [],
  "theme": null
}

File types: Razor (.razor), RazorCss (.razor.css), CSharp (.cs), Css (.css), Js (.js)

Integration tip: Replace BlazorApp in the generated code with your project's root namespace. Pages do not include @rendermode — add it manually if your project uses interactive rendering.


get_generation_status

Polls the status of a generation without blocking. Use as an alternative to wait_for_generation.

Parameters

Name Type Required Description
conversation_id string Yes From generate_blazor_component

Response (in-progress)

{
  "conversation_id": "01JNQX...",
  "status": "generating",
  "compile_success": null,
  "error": null,
  "timed_out": null,
  "progress_message": null
}

Response (completed)

{
  "conversation_id": "01JNQX...",
  "status": "completed",
  "compile_success": true,
  "error": null,
  "timed_out": null,
  "progress_message": null
}

Response (failed)

{
  "conversation_id": "01JNQX...",
  "status": "failed",
  "compile_success": false,
  "error": "Generation failed",
  "timed_out": null,
  "progress_message": null
}

Recommended polling interval: 2–3 seconds.


download_as_project

Downloads a complete runnable Blazor project scaffold with the generated components embedded. Returns a base64-encoded zip.

Parameters

Name Type Required Description
conversation_id string Yes From generate_blazor_component
type string Yes wasm (WebAssembly) or server (Blazor Server) — case-insensitive

Response

{
  "filename": "MyDashboard_Project.zip",
  "content_base64": "UEsDBBQ...",
  "content_type": "application/zip"
}

download_as_zip

Downloads only the generated code files without a project scaffold.

Parameters

Name Type Required Description
conversation_id string Yes From generate_blazor_component

Response

{
  "filename": "InstructUI_Files.zip",
  "content_base64": "UEsDBBQ...",
  "content_type": "application/zip"
}

get_credit_balance

Returns your current credit balance and plan details.

Parameters: None

Response

{
  "credits_remaining": 192.5,
  "plan_name": "Team",
  "usage_this_month": 7.5
}

list_conversations

Lists your recent conversations. Useful for finding a conversation_id to continue from a previous session.

Parameters

Name Type Required Description
limit int No Max results (default: 20, max: 50)
offset int No Pagination offset (default: 0)

Response

{
  "conversations": [
    {
      "conversation_id": "01JNQX...",
      "title": "Dashboard with sales charts",
      "library": "mudblazor",
      "css_framework": "None",
      "created_at": "2026-03-17T10:00:00Z",
      "updated_at": "2026-03-17T10:05:00Z",
      "status": "completed"
    }
  ],
  "total_count": 14
}

REST API

The same capabilities are available as plain HTTP endpoints for non-MCP integrations (CI pipelines, custom scripts). All endpoints require the same Authorization: Bearer iui_... header.

Endpoint Method Equivalent tool
/api/mcp/generate POST generate_blazor_component
/api/mcp/generation/{id}/status GET get_generation_status
/api/mcp/generation/{id}/result GET get_generation_result
/api/mcp/generation/{id}/events GET SSE stream
/api/mcp/generation/{id}/download-project?type=wasm GET download_as_project
/api/mcp/generation/{id}/download-zip GET download_as_zip
/api/mcp/credits GET get_credit_balance
/api/mcp/conversations?limit=20&offset=0 GET list_conversations

POST /api/mcp/generate

Request body (JSON, snake_case):

{
  "prompt": "A data table with sorting and pagination",
  "library": "mudblazor",
  "css_framework": "none",
  "image_base64": null,
  "image_mime_type": null
}

For follow-ups:

{
  "conversation_id": "01JNQX...",
  "prompt": "Add a search bar above the table"
}

SSE Stream (`/api/mcp/generation/

Streams text/event-stream events until generation reaches a terminal state. Heartbeats are sent every 15 seconds to keep connections alive through proxies.

event: status
data: {"conversation_id":"01JNQX...","status":"generating"}

event: heartbeat
data: {"timestamp":"2026-03-17T10:00:30Z"}

event: status
data: {"conversation_id":"01JNQX...","status":"completed","compile_success":true}

Error Reference

Scenario Result
Missing or invalid API key HTTP 401
Insufficient credits Error: "Not enough credits"
Invalid library value Error listing supported values
Invalid css_framework value Error listing supported values
Invalid library + CSS framework combination Error listing valid frameworks for the chosen library
library/css_framework mismatch on follow-up Error: must match original values or be omitted
Unknown or inaccessible conversation_id Error: "Conversation not found"
Generation already in progress HTTP 409
Compilation failed after max retries status: failed, compile_errors populated

Concurrency & Limits

  • Only one generation per conversation can run at a time. Start additional conversations for parallel work.
  • wait_for_generation has a maximum timeout of 300 seconds per call; call again if it times out.
  • list_conversations returns at most 50 items per page.
  • Credits are validated upfront and deducted during generation.