MCP Server
Ideon exposes a Model Context Protocol (MCP) endpoint that allows AI agents to read and manipulate your canvas programmatically. Any MCP-compatible client — Claude Code, Cursor, Windsurf, or custom integrations — can connect and interact with your projects.
Overview
The MCP server provides:
- 14 tools for managing projects, blocks, links, kanban tasks, and search
- 3 resources for contextual information about your canvas
- Intelligent block placement that avoids overlap and respects spatial layout
- Real-time sync — changes made by AI agents appear instantly for connected collaborators
- Permission enforcement — respects existing project roles (owner/editor/viewer)
Authentication
The MCP server authenticates via your existing Ideon API keys.
Generating an API Key
- Open your account page and navigate to the Developers tab.
- Click "Generate new key".
- Enter a name for the key (e.g. "Claude Code", "Cursor") and confirm.
- A modal appears with the full key (format:
sk-ideon-...). Copy it.
Security Notes
- Keys are hashed with SHA-256 before storage — Ideon never stores the raw key.
- Each key is scoped to the user who created it — all MCP operations run with that user's permissions.
- You can revoke a key at any time from the same Developers tab. It stops working immediately.
- Rate limited to 60 requests per minute per key (sliding window).
Client Configuration
Claude Code / Claude Desktop
Add to your MCP configuration file (~/.claude/mcp.json or project-level):
{
"mcpServers": {
"ideon": {
"url": "https://your-ideon-instance.com/api/mcp",
"headers": {
"Authorization": "Bearer sk-ideon-your-api-key-here"
}
}
}
}
Cursor
Add to your Cursor MCP settings (.cursor/mcp.json):
{
"mcpServers": {
"ideon": {
"url": "https://your-ideon-instance.com/api/mcp",
"headers": {
"Authorization": "Bearer sk-ideon-your-api-key-here"
}
}
}
}
Generic MCP Client
Any client supporting the Streamable HTTP transport can connect:
- Endpoint:
POST /api/mcp - Transport: Streamable HTTP (stateless, JSON-RPC over HTTP)
- Auth Header:
Authorization: Bearer sk-ideon-... - Content-Type:
application/json
Available Tools
Projects
| Tool | Description |
|---|---|
list_projects | List all projects accessible by the authenticated user (max 100) |
get_project | Get project metadata including block count, link count, and bounding box |
Blocks
| Tool | Description |
|---|---|
list_blocks | List all blocks in a project (max 200) with type, position, and content preview |
get_block | Get full block details (content, data, metadata, position) |
create_block | Create a new block with intelligent placement |
update_block | Update block content, data, metadata, position, or dimensions |
delete_block | Delete a block and cascade-delete connected links |
create_blocks_batch | Create up to 50 blocks in a single atomic operation (auto grid layout) |
Links
| Tool | Description |
|---|---|
list_links | List all links (connections) between blocks |
create_link | Create a connection between two blocks |
delete_link | Remove a connection |
Kanban
| Tool | Description |
|---|---|
list_kanban_tasks | List columns and tasks in a kanban block |
create_kanban_task | Add a new task to a kanban column |
move_kanban_task | Move a task between columns |
Search
| Tool | Description |
|---|---|
search_blocks | Case-insensitive search across block content and metadata (max 50 results) |
Resources
MCP resources provide contextual information to help AI agents understand your workspace:
| Resource URI | Description |
|---|---|
canvas://project/{id}/overview | Text summary: block counts by type, link count, bounding box |
canvas://project/{id}/graph | Full graph structure as JSON (blocks + links) |
canvas://help | Static guide covering block types, placement practices, and examples |
Block Placement
When creating blocks, the AI agent can control positioning in several ways:
Relative placement (recommended)
Use anchorBlockId + direction to place a new block near an existing one:
anchorBlockId: "existing-block-id"
direction: "right" | "left" | "up" | "down"
The placement engine automatically avoids collisions with a 40px minimum gap.
Explicit position
Provide exact position: { x, y } coordinates. No collision detection is applied.
Automatic placement
If neither anchor nor position is specified, blocks are placed to the right of the existing canvas content.
Batch placement
create_blocks_batch arranges blocks in a grid (max 5 columns) with uniform spacing.
Permissions
MCP operations respect the same roles as the Ideon UI:
| Role | Read | Write |
|---|---|---|
| Owner | ✓ | ✓ |
| Editor | ✓ | ✓ |
| Viewer | ✓ | ✗ |
Write operations include: create_block, update_block, delete_block, create_blocks_batch, create_link, delete_link, create_kanban_task, move_kanban_task.
Rate Limiting
Each API key is limited to 60 requests per 60-second sliding window.
Response headers on every request:
X-RateLimit-Limit: 60X-RateLimit-Remaining: <n>X-RateLimit-Reset: <unix-timestamp>
When rate-limited, the server returns HTTP 429 with a Retry-After header indicating seconds to wait.
Error Codes
| Code | Meaning |
|---|---|
-32001 | Authentication failed (invalid or missing API key) |
-32002 | Permission denied (insufficient role) |
-32003 | Resource not found (project, block, or link) |
-32004 | Validation error (invalid block type, content too long, etc.) |
-32602 | Invalid parameters (schema validation failed) |
-32603 | Internal server error |
Constraints
- Maximum request body size: 1 MB
- Maximum block content: 100,000 characters
- Block width: 100–2000 px
- Block height: 50–2000 px
- Batch size: 1–50 blocks per call
- Link label: max 200 characters
- Search query: 1–200 characters
- Self-links are not allowed
- Core blocks cannot be moved, resized, or deleted
Example Workflow
A typical AI agent workflow:
- Discover — call
list_projectsto find the target project - Orient — read
canvas://project/{id}/overviewfor a quick summary - Explore — call
list_blocksto understand the spatial layout - Act — create blocks near relevant existing content using
anchorBlockId - Connect — use
create_linkto represent relationships
Agent: "I'll add three related notes about the authentication flow."
→ list_blocks(projectId) — finds the "Auth" block at (200, 100)
→ create_blocks_batch(projectId, [
{ blockType: "text", content: "Login flow...", anchorBlockId: "auth-block" },
{ blockType: "text", content: "Token refresh..." },
{ blockType: "text", content: "Session management..." }
])
→ create_link(projectId, "new-block-1", "auth-block", label: "implements")