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_resultto 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_generationhas a maximum timeout of 300 seconds per call; call again if it times out.list_conversationsreturns at most 50 items per page.- Credits are validated upfront and deducted during generation.