From 1dc89ccbc9998a8bd91edc24acc3f3306c5bb3bc Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 12:53:07 +0200 Subject: [PATCH 1/8] [AI-6021] Add Angie tool annotations to public SDK Export ANGIE_REQUIRED_RESOURCES, ANGIE_MODEL_PREFERENCES, ANGIE_EXTENDED_TIMEOUT, MCP_READONLY constants and AngieRequiredResource, AngieModelPreferences, AngieExtendedTimeout interfaces so third-party MCP server developers can annotate their tools with Angie-specific metadata. Co-Authored-By: Claude Sonnet 4.6 --- src/angie-annotations.ts | 21 +++++++++++++++++++++ src/index.ts | 1 + 2 files changed, 22 insertions(+) create mode 100644 src/angie-annotations.ts diff --git a/src/angie-annotations.ts b/src/angie-annotations.ts new file mode 100644 index 0000000..471c061 --- /dev/null +++ b/src/angie-annotations.ts @@ -0,0 +1,21 @@ +export const ANGIE_REQUIRED_RESOURCES = 'angie/requiredResources' as const; +export const ANGIE_MODEL_PREFERENCES = 'angie/modelPreferences' as const; +export const ANGIE_EXTENDED_TIMEOUT = 'angie/extendedTimeout' as const; +export const MCP_READONLY = 'readOnlyHint' as const; + +export interface AngieRequiredResource { + uri: string; + whenToUse: string; + params?: Record; +} + +export interface AngieModelPreferences { + hints?: Array<{ name: string }>; + costPriority?: number; + speedPriority?: number; + intelligencePriority?: number; +} + +export interface AngieExtendedTimeout { + timeoutMs: number; +} diff --git a/src/index.ts b/src/index.ts index 0ca11be..7e23335 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,5 +19,6 @@ export { navigateAngieIframe } from './navigation-utils'; export { getAngieIframe } from './angie-iframe-utils'; export { disableNavigationPrevention } from './iframe'; export * from './types'; +export * from './angie-annotations'; export { BrowserContextTransport } from './browser-context-transport'; export { setReferrerRedirect, getReferrerRedirect, clearReferrerRedirect, executeReferrerRedirect, type ReferrerRedirectData } from './referrer-redirect'; From 1adc566458f9dda511ad3392b63060b6099d302c Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 13:29:42 +0200 Subject: [PATCH 2/8] [AI-6021] Replace model-preferences.md with comprehensive tool-annotations.md Covers all four Angie tool annotations (requiredResources, modelPreferences, extendedTimeout, readOnlyHint) with schemas, examples, and a combined usage example. Co-Authored-By: Claude Sonnet 4.6 --- docs/model-preferences.md | 66 -------------- docs/tool-annotations.md | 182 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 66 deletions(-) delete mode 100644 docs/model-preferences.md create mode 100644 docs/tool-annotations.md diff --git a/docs/model-preferences.md b/docs/model-preferences.md deleted file mode 100644 index 0d7a35d..0000000 --- a/docs/model-preferences.md +++ /dev/null @@ -1,66 +0,0 @@ -# Tool Model Preferences - -Angie allows MCP tools to specify their preferred AI models using the `angie/modelPreferences` annotation. This ensures tools can request specific models optimized for their functionality (e.g., code generation tools preferring Claude Sonnet). - -## How It Works - -When a tool is selected, Angie uses its preferred model for both planning and execution, overriding user preferences when specified. - -## Annotation Schema - -```typescript -export const ANGIE_MODEL_PREFERENCES = 'angie/modelPreferences' as const; - -export interface AngieModelPreferences { - hints?: Array<{ name: string }>; - costPriority?: number; // 0-1 (future use) - speedPriority?: number; // 0-1 (future use) - intelligencePriority?: number; // 0-1 (future use) -} -``` - -## Usage Example - -```typescript - -server.tool( - 'generate-custom-css', - 'Generates CSS code based on design requirements', - { /* input schema */ }, - { - [ANGIE_MODEL_PREFERENCES]: { - hints: [ - { name: 'claude-sonnet' }, // First choice - { name: 'gpt-4.1' } // Fallback - ], - intelligencePriority: 0.9 // Optional: for future use - } - }, - async (args) => { - // Tool handler implementation - } -); -``` - -## Model Selection Priority - -Angie resolves the model to use in this order: - -1. **User preference (Internal users only)** - `executionModel` if provided and different from the system default -2. **Tool annotation** - `angie/modelPreferences.hints[0]` if user preference is default or not provided -3. **System defaults** - Falls back to default model if neither is available - -## Best Practices - -- **Use for specialized tasks**: Apply model preferences when your tool requires specific model capabilities (e.g., code generation, creative writing) -- **Provide fallbacks**: List multiple model hints in order of preference -- **Test with different models**: Verify your tool works with fallback models -- **Document requirements**: Explain in your tool description why specific models are preferred - -## Notes - -- Based on [MCP Sampling specification](https://modelcontextprotocol.io/specification/2025-06-18/client/sampling) -- First hint is the most preferred, subsequent hints are fallbacks -- Fully typed with TypeScript - no `any` types used -- Backward compatible with existing model selection behavior - diff --git a/docs/tool-annotations.md b/docs/tool-annotations.md new file mode 100644 index 0000000..6d731d2 --- /dev/null +++ b/docs/tool-annotations.md @@ -0,0 +1,182 @@ +# Angie Tool Annotations + +Angie exposes a set of annotation constants and interfaces that MCP tool authors can use to attach Angie-specific metadata to their tools. These are exported directly from `@elementor/angie-sdk`. + +## Available Annotations + +| Constant | Value | Purpose | +|---|---|---| +| `ANGIE_REQUIRED_RESOURCES` | `'angie/requiredResources'` | Declare resources the tool needs | +| `ANGIE_MODEL_PREFERENCES` | `'angie/modelPreferences'` | Request a specific AI model | +| `ANGIE_EXTENDED_TIMEOUT` | `'angie/extendedTimeout'` | Request a longer execution timeout | +| `MCP_READONLY` | `'readOnlyHint'` | Mark a tool as read-only | + +--- + +## `ANGIE_REQUIRED_RESOURCES` + +Declare which resources the tool expects Angie to fetch and provide before execution. + +```typescript +interface AngieRequiredResource { + uri: string; // Resource URI to fetch + whenToUse: string; // Human-readable description of when this resource is needed + params?: Record; // Optional URI template parameters +} +``` + +**Example:** + +```typescript +import { ANGIE_REQUIRED_RESOURCES } from '@elementor/angie-sdk'; + +server.tool( + 'update-page-styles', + 'Updates the CSS styles for the current page', + { /* input schema */ }, + { + [ANGIE_REQUIRED_RESOURCES]: [ + { + uri: 'elementor://page/styles', + whenToUse: 'Always — needed to read current page styles before updating', + } + ] + }, + async (args) => { /* handler */ } +); +``` + +--- + +## `ANGIE_MODEL_PREFERENCES` + +Request a specific AI model for planning and execution of this tool. When the tool is selected, Angie uses this preference to override the default model. + +```typescript +interface AngieModelPreferences { + hints?: Array<{ name: string }>; // Ordered list of preferred model names + costPriority?: number; // 0–1 (future use) + speedPriority?: number; // 0–1 (future use) + intelligencePriority?: number; // 0–1 (future use) +} +``` + +### Model Selection Priority + +Angie resolves the model in this order: + +1. **User preference (internal users only)** — `executionModel` if provided and different from the system default +2. **Tool annotation** — `angie/modelPreferences.hints[0]` if user preference is default or absent +3. **System default** — falls back if neither is available + +**Example:** + +```typescript +import { ANGIE_MODEL_PREFERENCES } from '@elementor/angie-sdk'; + +server.tool( + 'generate-custom-css', + 'Generates CSS code based on design requirements', + { /* input schema */ }, + { + [ANGIE_MODEL_PREFERENCES]: { + hints: [ + { name: 'claude-sonnet' }, // First choice + { name: 'gpt-4.1' } // Fallback + ], + intelligencePriority: 0.9 // Optional: for future use + } + }, + async (args) => { /* handler */ } +); +``` + +> Based on the [MCP Sampling specification](https://modelcontextprotocol.io/specification/2025-06-18/client/sampling). First hint is the most preferred; subsequent hints are fallbacks. + +--- + +## `ANGIE_EXTENDED_TIMEOUT` + +Request a longer execution timeout for tools that perform heavy or slow operations (e.g., large DOM mutations, external API calls). + +```typescript +interface AngieExtendedTimeout { + timeoutMs: number; // Timeout in milliseconds +} +``` + +**Example:** + +```typescript +import { ANGIE_EXTENDED_TIMEOUT } from '@elementor/angie-sdk'; + +server.tool( + 'bulk-update-elements', + 'Updates all elements on the page in one operation', + { /* input schema */ }, + { + [ANGIE_EXTENDED_TIMEOUT]: { + timeoutMs: 60000 // 60 seconds + } + }, + async (args) => { /* handler */ } +); +``` + +--- + +## `MCP_READONLY` + +Mark a tool as read-only. Angie uses this hint to understand that the tool does not mutate any state, which can affect planning and user confirmation flows. + +**Example:** + +```typescript +import { MCP_READONLY } from '@elementor/angie-sdk'; + +server.tool( + 'get-page-structure', + 'Returns the structure of the current page', + { /* input schema */ }, + { + [MCP_READONLY]: true + }, + async (args) => { /* handler */ } +); +``` + +--- + +## Using Multiple Annotations Together + +All annotations can be combined on a single tool: + +```typescript +import { + ANGIE_REQUIRED_RESOURCES, + ANGIE_MODEL_PREFERENCES, + ANGIE_EXTENDED_TIMEOUT, + MCP_READONLY, +} from '@elementor/angie-sdk'; + +server.tool( + 'analyze-page-layout', + 'Analyzes the current page layout and returns suggestions', + { /* input schema */ }, + { + [MCP_READONLY]: true, + [ANGIE_EXTENDED_TIMEOUT]: { timeoutMs: 30000 }, + [ANGIE_REQUIRED_RESOURCES]: [ + { + uri: 'elementor://page/layout', + whenToUse: 'Always — needed to read the page structure', + } + ], + [ANGIE_MODEL_PREFERENCES]: { + hints: [{ name: 'claude-sonnet' }], + intelligencePriority: 0.9 + } + }, + async (args) => { /* handler */ } +); +``` From 0d6ef76ef952572992a16938ca43f5683617ed2e Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 13:34:18 +0200 Subject: [PATCH 3/8] Fixed version --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index fb15584..eac7dc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@elementor/angie-sdk", - "version": "1.4.0", + "version": "1.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@elementor/angie-sdk", - "version": "1.4.0", + "version": "1.4.1", "license": "MIT", "dependencies": { "@elementor/angie-logger": "^0.3.1", From bcd9b58d323f99a9c5c6606fc6635d2b3f5264fe Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 13:35:36 +0200 Subject: [PATCH 4/8] [AI-6021] Add tests for angie-annotations constants Co-Authored-By: Claude Sonnet 4.6 --- src/angie-annotations.test.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/angie-annotations.test.ts diff --git a/src/angie-annotations.test.ts b/src/angie-annotations.test.ts new file mode 100644 index 0000000..755c544 --- /dev/null +++ b/src/angie-annotations.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from '@jest/globals'; +import { + ANGIE_REQUIRED_RESOURCES, + ANGIE_MODEL_PREFERENCES, + ANGIE_EXTENDED_TIMEOUT, + MCP_READONLY, +} from './angie-annotations'; + +describe('angie-annotations', () => { + it('ANGIE_REQUIRED_RESOURCES has the correct value', () => { + expect(ANGIE_REQUIRED_RESOURCES).toBe('angie/requiredResources'); + }); + + it('ANGIE_MODEL_PREFERENCES has the correct value', () => { + expect(ANGIE_MODEL_PREFERENCES).toBe('angie/modelPreferences'); + }); + + it('ANGIE_EXTENDED_TIMEOUT has the correct value', () => { + expect(ANGIE_EXTENDED_TIMEOUT).toBe('angie/extendedTimeout'); + }); + + it('MCP_READONLY has the correct value', () => { + expect(MCP_READONLY).toBe('readOnlyHint'); + }); +}); From f245843cd1ac51b6a2d3de3859958faa11f30cff Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 14:17:44 +0200 Subject: [PATCH 5/8] [AI-6021] Document tool annotations usage in SDK docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix broken link to deleted model-preferences.md → tool-annotations.md - Add Tool Annotations section to README with import/usage example - Update angie-sdk-supported-features.md to use SDK constants and correct field names Co-Authored-By: Claude Sonnet 4.6 --- README.md | 37 +++++++++++++++++++++++++++- docs/angie-sdk-supported-features.md | 8 +++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9e8dfba..6a89852 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ This SDK enables you to create custom MCP servers that Angie can discover and us - [MCP Server Example](#mcp-server-example) - [Adding Instructions to MCP Servers](#adding-instructions-to-mcp-servers) - [Registering Tools](#registering-tools) +- [Tool Annotations](#tool-annotations) - [Handling Tool Calls](#handling-tool-calls) - [Best Practices](#best-practices) - [Remote SSE and HTTP Streamable MCP servers](#remote-sse-and-http-streamable-mcp-servers) @@ -105,7 +106,7 @@ The SDK covers three main abilities: 📖 **Documentation:** - [MCP SDK Supported Features](./docs/angie-sdk-supported-features.md) -- [Tool Model Preferences](./docs/model-preferences.md) - Configure preferred AI models for your tools +- [Tool Annotations](./docs/tool-annotations.md) - Annotate tools with resource dependencies, model preferences, and more --- @@ -317,6 +318,40 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({ --- +## Tool Annotations + +Angie extends MCP tool annotations with Angie-specific metadata. Import the annotation constants directly from `@elementor/angie-sdk`: + +```typescript +import { + ANGIE_REQUIRED_RESOURCES, + ANGIE_MODEL_PREFERENCES, + ANGIE_EXTENDED_TIMEOUT, + MCP_READONLY, +} from '@elementor/angie-sdk'; + +server.tool( + 'analyze-page-layout', + 'Analyzes the current page layout and returns suggestions', + { /* input schema */ }, + { + [MCP_READONLY]: true, + [ANGIE_EXTENDED_TIMEOUT]: { timeoutMs: 30000 }, + [ANGIE_REQUIRED_RESOURCES]: [ + { uri: 'elementor://page/layout', whenToUse: 'Always — needed to read the page structure' } + ], + [ANGIE_MODEL_PREFERENCES]: { + hints: [{ name: 'claude-sonnet' }] + } + }, + async (args) => { /* handler */ } +); +``` + +📖 See [Tool Annotations](./docs/tool-annotations.md) for full reference. + +--- + ## Handling Tool Calls Implement a handler for `CallToolRequestSchema`: diff --git a/docs/angie-sdk-supported-features.md b/docs/angie-sdk-supported-features.md index 04822a3..f561c9d 100644 --- a/docs/angie-sdk-supported-features.md +++ b/docs/angie-sdk-supported-features.md @@ -41,13 +41,15 @@ These annotations are **Angie-specific** and extend standard MCP tool annotation Declare which resources a tool needs before execution. Angie will fetch these resources automatically before calling the tool. ```typescript +import { ANGIE_REQUIRED_RESOURCES } from '@elementor/angie-sdk'; + server.tool('update-element', 'Update an Elementor element', { elementId: z.string(), changes: z.object({ /* ... */ }), }, { - 'angie/requiredResources': [ - { uri: 'elementor://page-context', description: 'Current page structure' }, - { uri: 'elementor://selected-element', description: 'Currently selected element' } + [ANGIE_REQUIRED_RESOURCES]: [ + { uri: 'elementor://page-context', whenToUse: 'Current page structure' }, + { uri: 'elementor://selected-element', whenToUse: 'Currently selected element' } ] }, handler); ``` From 76d8fbe821bf14de843b6808d158c5a203f4e222 Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 15:58:51 +0200 Subject: [PATCH 6/8] Bump version to 1.4.2 Co-Authored-By: Claude Sonnet 4.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51c6ed0..f2af34e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@elementor/angie-sdk", - "version": "1.4.1", + "version": "1.4.2", "description": "TypeScript SDK for Angie AI assistant", "main": "dist/index.cjs", "module": "dist/index.js", From 6721829f03c21ed19a3e1c824a48ac7a9f756fbc Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 15:59:42 +0200 Subject: [PATCH 7/8] Update package-lock.json to 1.4.2 Co-Authored-By: Claude Sonnet 4.6 --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index eac7dc7..dc66f77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@elementor/angie-sdk", - "version": "1.4.1", + "version": "1.4.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@elementor/angie-sdk", - "version": "1.4.1", + "version": "1.4.2", "license": "MIT", "dependencies": { "@elementor/angie-logger": "^0.3.1", From 3db25627d9883d499c979f430add46e84f6b4c19 Mon Sep 17 00:00:00 2001 From: Gal Oz Date: Sun, 8 Mar 2026 17:00:13 +0200 Subject: [PATCH 8/8] [AI-6021] Add ToolAnnotations cast to annotation examples Re-export ToolAnnotations from @elementor/angie-sdk and add `as ToolAnnotations` casts to all annotation objects in docs to work around strict MCP SDK typing until tools are refactored. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 3 ++- docs/angie-sdk-supported-features.md | 4 ++-- docs/tool-annotations.md | 19 ++++++++++--------- src/types.ts | 1 + 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 6a89852..5229424 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,7 @@ import { ANGIE_MODEL_PREFERENCES, ANGIE_EXTENDED_TIMEOUT, MCP_READONLY, + ToolAnnotations, } from '@elementor/angie-sdk'; server.tool( @@ -343,7 +344,7 @@ server.tool( [ANGIE_MODEL_PREFERENCES]: { hints: [{ name: 'claude-sonnet' }] } - }, + } as ToolAnnotations, async (args) => { /* handler */ } ); ``` diff --git a/docs/angie-sdk-supported-features.md b/docs/angie-sdk-supported-features.md index f561c9d..09b43fc 100644 --- a/docs/angie-sdk-supported-features.md +++ b/docs/angie-sdk-supported-features.md @@ -41,7 +41,7 @@ These annotations are **Angie-specific** and extend standard MCP tool annotation Declare which resources a tool needs before execution. Angie will fetch these resources automatically before calling the tool. ```typescript -import { ANGIE_REQUIRED_RESOURCES } from '@elementor/angie-sdk'; +import { ANGIE_REQUIRED_RESOURCES, ToolAnnotations } from '@elementor/angie-sdk'; server.tool('update-element', 'Update an Elementor element', { elementId: z.string(), @@ -51,7 +51,7 @@ server.tool('update-element', 'Update an Elementor element', { { uri: 'elementor://page-context', whenToUse: 'Current page structure' }, { uri: 'elementor://selected-element', whenToUse: 'Currently selected element' } ] -}, handler); +} as ToolAnnotations, handler); ``` **How it works:** diff --git a/docs/tool-annotations.md b/docs/tool-annotations.md index 6d731d2..1a8275a 100644 --- a/docs/tool-annotations.md +++ b/docs/tool-annotations.md @@ -28,7 +28,7 @@ interface AngieRequiredResource { **Example:** ```typescript -import { ANGIE_REQUIRED_RESOURCES } from '@elementor/angie-sdk'; +import { ANGIE_REQUIRED_RESOURCES, ToolAnnotations } from '@elementor/angie-sdk'; server.tool( 'update-page-styles', @@ -41,7 +41,7 @@ server.tool( whenToUse: 'Always — needed to read current page styles before updating', } ] - }, + } as ToolAnnotations, async (args) => { /* handler */ } ); ``` @@ -72,7 +72,7 @@ Angie resolves the model in this order: **Example:** ```typescript -import { ANGIE_MODEL_PREFERENCES } from '@elementor/angie-sdk'; +import { ANGIE_MODEL_PREFERENCES, ToolAnnotations } from '@elementor/angie-sdk'; server.tool( 'generate-custom-css', @@ -86,7 +86,7 @@ server.tool( ], intelligencePriority: 0.9 // Optional: for future use } - }, + } as ToolAnnotations, async (args) => { /* handler */ } ); ``` @@ -108,7 +108,7 @@ interface AngieExtendedTimeout { **Example:** ```typescript -import { ANGIE_EXTENDED_TIMEOUT } from '@elementor/angie-sdk'; +import { ANGIE_EXTENDED_TIMEOUT, ToolAnnotations } from '@elementor/angie-sdk'; server.tool( 'bulk-update-elements', @@ -118,7 +118,7 @@ server.tool( [ANGIE_EXTENDED_TIMEOUT]: { timeoutMs: 60000 // 60 seconds } - }, + } as ToolAnnotations, async (args) => { /* handler */ } ); ``` @@ -132,7 +132,7 @@ Mark a tool as read-only. Angie uses this hint to understand that the tool does **Example:** ```typescript -import { MCP_READONLY } from '@elementor/angie-sdk'; +import { MCP_READONLY, ToolAnnotations } from '@elementor/angie-sdk'; server.tool( 'get-page-structure', @@ -140,7 +140,7 @@ server.tool( { /* input schema */ }, { [MCP_READONLY]: true - }, + } as ToolAnnotations, async (args) => { /* handler */ } ); ``` @@ -157,6 +157,7 @@ import { ANGIE_MODEL_PREFERENCES, ANGIE_EXTENDED_TIMEOUT, MCP_READONLY, + ToolAnnotations, } from '@elementor/angie-sdk'; server.tool( @@ -176,7 +177,7 @@ server.tool( hints: [{ name: 'claude-sonnet' }], intelligencePriority: 0.9 } - }, + } as ToolAnnotations, async (args) => { /* handler */ } ); ``` diff --git a/src/types.ts b/src/types.ts index 93c2bae..7316bed 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { ServerCapabilities } from '@modelcontextprotocol/sdk/types.js'; +export { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'; // Backward compatibility export enum AngieMCPTransport {