import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
/**
* Register annotation conversion strategy prompt
*/
export function registerAnnotationConversionPrompts(server: McpServer): void {
server.prompt(
"annotation_conversion_strategy",
"Strategy for converting manual annotations to Figma's native annotations",
() => {
return {
messages: [
{
role: "assistant",
content: {
type: "text",
text: `# Automatic Annotation Conversion
## Process Overview
The process of converting manual annotations (numbered/alphabetical indicators with connected descriptions) to Figma's native annotations:
1. Get selected frame/component information
2. Scan and collect all annotation text nodes
3. Scan target UI elements (components, instances, frames)
4. Match annotations to appropriate UI elements
5. Apply native Figma annotations
## Step 1: Get Selection and Initial Setup
First, get the selected frame or component that contains annotations:
\`\`\`typescript
// Get the selected frame/component
const selection = await get_selection();
const selectedNodeId = selection[0].id
// Get available annotation categories for later use
const annotationData = await get_annotations({
nodeId: selectedNodeId,
includeCategories: true
});
const categories = annotationData.categories;
\`\`\`
## Step 2: Scan Annotation Text Nodes
Scan all text nodes to identify annotations and their descriptions:
\`\`\`typescript
// Get all text nodes in the selection
const textNodes = await scan_text_nodes({
nodeId: selectedNodeId
});
// Filter and group annotation markers and descriptions
// Markers typically have these characteristics:
// - Short text content (usually single digit/letter)
// - Specific font styles (often bold)
// - Located in a container with "Marker" or "Dot" in the name
// - Have a clear naming pattern (e.g., "1", "2", "3" or "A", "B", "C")
// Identify description nodes
// Usually longer text nodes near markers or with matching numbers in path
\`\`\`
## Step 3: Scan Target UI Elements
Get all potential target elements that annotations might refer to:
\`\`\`typescript
// Scan for all UI elements that could be annotation targets
const targetNodes = await scan_nodes_by_types({
nodeId: selectedNodeId,
types: [
"COMPONENT",
"INSTANCE",
"FRAME"
]
});
\`\`\`
## Step 4: Match Annotations to Targets
Match each annotation to its target UI element using these strategies in order of priority:
1. **Path-Based Matching**:
- Look at the marker's parent container name in the Figma layer hierarchy
- Remove any "Marker:" or "Annotation:" prefixes from the parent name
- Find UI elements that share the same parent name or have it in their path
- This works well when markers are grouped with their target elements
2. **Name-Based Matching**:
- Extract key terms from the annotation description
- Look for UI elements whose names contain these key terms
- Consider both exact matches and semantic similarities
- Particularly effective for form fields, buttons, and labeled components
3. **Proximity-Based Matching** (fallback):
- Calculate the center point of the marker
- Find the closest UI element by measuring distances to element centers
- Consider the marker's position relative to nearby elements
- Use this method when other matching strategies fail
Additional Matching Considerations:
- Give higher priority to matches found through path-based matching
- Consider the type of UI element when evaluating matches
- Take into account the annotation's context and content
- Use a combination of strategies for more accurate matching
## Step 5: Apply Native Annotations
Convert matched annotations to Figma's native annotations using batch processing:
\`\`\`typescript
// Prepare annotations array for batch processing
const annotationsToApply = Object.values(annotations).map(({ marker, description }) => {
// Find target using multiple strategies
const target =
findTargetByPath(marker, targetNodes) ||
findTargetByName(description, targetNodes) ||
findTargetByProximity(marker, targetNodes);
if (target) {
// Determine appropriate category based on content
const category = determineCategory(description.characters, categories);
// Determine appropriate additional annotationProperty based on content
const annotationProperty = determineProperties(description.characters, target.type);
return {
nodeId: target.id,
labelMarkdown: description.characters,
categoryId: category.id,
properties: annotationProperty
};
}
return null;
}).filter(Boolean); // Remove null entries
// Apply annotations in batches using set_multiple_annotations
if (annotationsToApply.length > 0) {
await set_multiple_annotations({
nodeId: selectedNodeId,
annotations: annotationsToApply
});
}
\`\`\`
This strategy focuses on practical implementation based on real-world usage patterns, emphasizing the importance of handling various UI elements as annotation targets, not just text nodes.`,
},
},
],
description:
"Strategy for converting manual annotations to Figma's native annotations",
};
},
);
}