sia-vision-mcp-server
Version:
Enhanced v2 MCP server with improved error handling, validation, and comprehensive tool schemas for SIA.Vision storytelling platform
365 lines • 15.8 kB
JavaScript
// Enhanced v2 core tools for SIA Vision storytelling platform
// All tools proxy execution to Firebase Functions with comprehensive validation
export const v2CoreTools = [
{
name: 'node_create',
description: 'Create a new content node in the hierarchical story structure. Supports storyworlds, series, episodes, scenes, characters, locations, assets, and boards. Returns nodeId, storyworldId, and hierarchyPath for the created node.',
inputSchema: {
type: 'object',
properties: {
storyworldId: {
type: 'string',
description: 'Required for all nodes except STORYWORLD. Must be a valid ObjectId of an existing storyworld.'
},
nodeType: {
type: 'string',
enum: ['STORYWORLD', 'SERIES', 'EPISODE', 'SCENE', 'CHARACTER', 'LOCATION', 'ASSET', 'BOARD'],
description: 'Type of content node to create. Determines available parent relationships and capabilities.'
},
title: {
type: 'string',
minLength: 1,
maxLength: 200,
description: 'Display title for the node. Should be descriptive and unique within the parent context.'
},
parentId: {
type: 'string',
description: 'Optional parent node ID for hierarchical organization. Must be compatible with nodeType hierarchy rules.'
},
content: {
type: 'string',
description: 'Initial content/description for the node. Can be updated later via node_update.'
},
metadata: {
type: 'object',
description: 'Additional structured data for the node (e.g., genre, tags, custom properties).'
},
idempotencyKey: {
type: 'string',
description: 'Optional key to prevent duplicate creation. If provided, identical requests will return the existing node.'
}
},
required: ['nodeType', 'title']
}
},
{
name: 'node_update',
description: 'Update mutable fields on an existing node including title, content, and metadata. Preserves hierarchical relationships and version control. Use for iterative content development.',
inputSchema: {
type: 'object',
properties: {
nodeId: {
type: 'string',
description: 'ObjectId of the node to update. Must be accessible by the current user.'
},
title: {
type: 'string',
minLength: 1,
maxLength: 200,
description: 'New title for the node. Will update display name across all references.'
},
content: {
type: 'string',
description: 'Updated content/description. Supports markdown and rich text formatting.'
},
metadata: {
type: 'object',
description: 'Updated metadata object. Will merge with existing metadata, replacing matching keys.'
}
},
required: ['nodeId']
}
},
{
name: 'node_delete',
description: 'Delete a node and its descendants; cleans up associated documents',
inputSchema: {
type: 'object',
properties: {
nodeId: { type: 'string' }
},
required: ['nodeId']
}
},
{
name: 'get_content_hierarchy',
description: 'Retrieve the complete hierarchical structure of a storyworld including series, episodes, scenes, and content statistics. Essential for understanding story organization before making changes.',
inputSchema: {
type: 'object',
properties: {
storyworld_id: {
type: 'string',
description: 'ObjectId of the storyworld to retrieve. Must be accessible by the current user.'
},
include_counts: {
type: 'boolean',
default: true,
description: 'Whether to include statistics (episode counts, scene counts) at each hierarchy level.'
},
max_depth: {
type: 'number',
default: 4,
enum: [1, 2, 3, 4],
description: 'Maximum depth to traverse: 1=storyworld only, 2=+series, 3=+episodes, 4=+scenes (recommended).'
}
},
required: ['storyworld_id']
}
},
{
name: 'reorder_nodes',
description: 'Reorder sibling nodes by assigning new order keys',
inputSchema: {
type: 'object',
properties: {
nodeIds: { type: 'array', items: { type: 'string' } },
orderKeys: { type: 'array', items: { type: 'string' } },
},
required: ['nodeIds', 'orderKeys']
}
},
{
name: 'move_node',
description: 'Move a node to a new parent and/or position',
inputSchema: {
type: 'object',
properties: {
nodeId: { type: 'string' },
newParentId: { type: 'string' },
newOrderKey: { type: 'string' },
},
required: ['nodeId']
}
},
{
name: 'nodes_get',
description: 'Query nodes by storyworld, parent, and type with ordering and field selection',
inputSchema: {
type: 'object',
properties: {
storyworldId: { type: 'string' },
parentId: { type: 'string' },
nodeTypes: { type: 'array', items: { type: 'string' } },
fields: { type: 'array', items: { type: 'string' } },
limit: { type: 'number', default: 100 },
orderBy: { type: 'string', enum: ['orderKey', 'createdAt', 'updatedAt'], default: 'orderKey' },
orderDirection: { type: 'string', enum: ['asc', 'desc'], default: 'asc' }
},
required: ['storyworldId']
}
},
{
name: 'document_ensure',
description: 'Ensure a TipTap document exists for a node (excludes STORYWORLD and BOARD types)',
inputSchema: {
type: 'object',
properties: {
nodeId: { type: 'string' }
},
required: ['nodeId']
}
},
{
name: 'get_document_view',
description: 'Retrieve the current view of a script document with addressable blocks',
inputSchema: {
type: 'object',
properties: { document_id: { type: 'string' } },
required: ['document_id']
}
},
{
name: 'apply_document_patch',
description: 'Apply RFC-6902 JSON Patch operations to modify scene documents with version control. Supports adding text blocks, image blocks, and other TipTap content. Always include a version test operation to prevent conflicts.',
inputSchema: {
type: 'object',
properties: {
document_id: {
type: 'string',
description: 'ObjectId of the document to modify. Must be accessible by the current user.'
},
version: {
type: 'number',
minimum: 1,
description: 'Current version number of the document. Operation will fail if version has changed.'
},
ops: {
type: 'array',
minItems: 1,
items: {
type: 'object',
properties: {
op: {
type: 'string',
enum: ['test', 'add', 'remove', 'replace', 'move', 'copy'],
description: 'Type of patch operation. Always start with "test" operation for version validation.'
},
path: {
type: 'string',
description: 'JSON Pointer path to the target location (e.g., "/content/0", "/content/-").'
},
value: {
description: 'Value to set/add. For image blocks, include src, alt, assetId, and dimensions.'
},
from: {
type: 'string',
description: 'Source path for move/copy operations.'
}
},
required: ['op', 'path']
},
description: 'Array of JSON Patch operations to apply sequentially. First operation should test version.'
}
},
required: ['document_id', 'version', 'ops']
}
},
{
name: 'update_document',
description: 'Update a document content with version control (RFC-6902 compatible)',
inputSchema: {
type: 'object',
properties: {
documentId: { type: 'string' },
content: {},
version: { type: 'number' }
},
required: ['documentId', 'content', 'version']
}
},
{
name: 'create_relationship',
description: 'Create a relationship between two nodes within a storyworld',
inputSchema: {
type: 'object',
properties: {
storyworldId: { type: 'string' },
sourceId: { type: 'string' },
targetId: { type: 'string' },
relType: {
type: 'string',
enum: [
'related_to', 'contains', 'belongs_to', 'next_in_sequence', 'references', 'referenced_by',
'appears_in', 'character_appears_in', 'located_in', 'uses_asset', 'derived_from', 'generates', 'parent_child'
]
},
metadata: { type: 'object' }
},
required: ['storyworldId', 'sourceId', 'targetId', 'relType']
}
},
{
name: 'get_relationships',
description: 'Get relationships for a node or storyworld',
inputSchema: {
type: 'object',
properties: {
storyworldId: { type: 'string' },
nodeId: { type: 'string' },
relType: { type: 'string' },
direction: { type: 'string', enum: ['source', 'target', 'both'], default: 'both' },
includeNodes: { type: 'boolean', default: false },
limit: { type: 'number', default: 100 }
},
required: ['storyworldId']
}
},
{
name: 'get_related_nodes',
description: 'Get nodes related to a specific node via relationships',
inputSchema: {
type: 'object',
properties: {
nodeId: { type: 'string' },
relType: { type: 'string' },
direction: { type: 'string', enum: ['source', 'target', 'both'], default: 'both' },
depth: { type: 'number', default: 1, maximum: 3 },
includeContent: { type: 'boolean', default: false }
},
required: ['nodeId']
}
},
{
name: 'asset_upload_and_create',
description: 'Upload a base64-encoded file to Firebase Storage and create an ASSET node with metadata. Supports images, documents, and media files. Returns assetId, storagePath, and download URL for integration into documents.',
inputSchema: {
type: 'object',
properties: {
storyworldId: {
type: 'string',
description: 'ObjectId of the storyworld that will contain this asset.'
},
title: {
type: 'string',
minLength: 1,
maxLength: 200,
description: 'Descriptive title for the asset (e.g., "Character Portrait - Sarah Chen").'
},
fileBase64: {
type: 'string',
description: 'Base64-encoded file data with proper MIME type prefix (e.g., "data:image/png;base64,iVBORw0...").'
},
mimeType: {
type: 'string',
enum: ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'application/pdf', 'text/plain'],
description: 'MIME type of the uploaded file. Must match the actual file format.'
},
parentId: {
type: 'string',
description: 'Optional parent node ID (typically a scene, character, or location) for hierarchical organization.'
},
metadata: {
type: 'object',
description: 'Additional metadata such as AI generation details, usage context, or custom properties.'
}
},
required: ['storyworldId', 'title', 'fileBase64', 'mimeType']
}
},
{
name: 'asset_create',
description: 'Create an ASSET node for an existing file in Firebase Storage. Use when the file is already uploaded and you need to create the corresponding node with metadata.',
inputSchema: {
type: 'object',
properties: {
storyworldId: {
type: 'string',
description: 'ObjectId of the storyworld that will contain this asset.'
},
title: {
type: 'string',
minLength: 1,
maxLength: 200,
description: 'Descriptive title for the asset.'
},
mimeType: {
type: 'string',
description: 'MIME type of the file (e.g., "image/png", "application/pdf").'
},
fileSize: {
type: 'number',
minimum: 1,
description: 'Size of the file in bytes.'
},
storagePath: {
type: 'string',
description: 'Firebase Storage path where the file is located (e.g., "gs://bucket/path/file.png").'
},
parentId: {
type: 'string',
description: 'Optional parent node ID for hierarchical organization.'
},
metadata: {
type: 'object',
description: 'Additional metadata including SHA256 hash, creation details, or custom properties.'
},
sha256: {
type: 'string',
description: 'Optional SHA256 hash of the file for integrity verification.'
}
},
required: ['storyworldId', 'title', 'mimeType', 'fileSize', 'storagePath']
}
}
];
//# sourceMappingURL=v2-core-tools.js.map