From ed7525441dd828a21df3b198911ecb34c7ceb360 Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 18:42:29 -0700 Subject: [PATCH 01/17] MCP Server Support --- src/app.ts | 5 +++++ src/trigger.ts | 11 ++++++++++- types/app.d.ts | 3 +++ types/index.d.ts | 1 + types/mcpServer.d.ts | 31 +++++++++++++++++++++++++++++++ types/trigger.d.ts | 6 ++++++ 6 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 types/mcpServer.d.ts diff --git a/src/app.ts b/src/app.ts index 485dd35..b8cf880 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,6 +11,7 @@ import { HttpHandler, HttpMethod, HttpMethodFunctionOptions, + McpServerFunctionOptions, MySqlFunctionOptions, ServiceBusQueueFunctionOptions, ServiceBusTopicFunctionOptions, @@ -145,6 +146,10 @@ export function webPubSub(name: string, options: WebPubSubFunctionOptions): void generic(name, convertToGenericOptions(options, trigger.webPubSub)); } +export function mcpServer(name: string, options: McpServerFunctionOptions): void { + generic(name, convertToGenericOptions(options, trigger.mcpServer)); +} + export function generic(name: string, options: GenericFunctionOptions): void { if (!hasSetModel) { setProgrammingModel(); diff --git a/src/trigger.ts b/src/trigger.ts index f709abb..ec30d83 100644 --- a/src/trigger.ts +++ b/src/trigger.ts @@ -12,8 +12,10 @@ import { GenericTriggerOptions, HttpTrigger, HttpTriggerOptions, + McpServerTrigger, + McpServerTriggerOptions, MySqlTrigger, - MySqlTriggerOptions, + MySqlTriggerOptions, ServiceBusQueueTrigger, ServiceBusQueueTriggerOptions, ServiceBusTopicTrigger, @@ -126,6 +128,13 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger { }); } +export function mcpServer(options: McpServerTriggerOptions): McpServerTrigger { + return addTriggerBindingName({ + ...options, + type: 'mcpToolTrigger', + }); +} + export function generic(options: GenericTriggerOptions): FunctionTrigger { return addTriggerBindingName(options); } diff --git a/types/app.d.ts b/types/app.d.ts index c06c9b1..14479bf 100644 --- a/types/app.d.ts +++ b/types/app.d.ts @@ -6,6 +6,7 @@ import { EventGridFunctionOptions } from './eventGrid'; import { EventHubFunctionOptions } from './eventHub'; import { GenericFunctionOptions } from './generic'; import { HttpFunctionOptions, HttpHandler, HttpMethodFunctionOptions } from './http'; +import { McpServerFunctionOptions } from './mcpServer'; import { MySqlFunctionOptions } from './mySql'; import { ServiceBusQueueFunctionOptions, ServiceBusTopicFunctionOptions } from './serviceBus'; import { SetupOptions } from './setup'; @@ -196,4 +197,6 @@ export function generic(name: string, options: GenericFunctionOptions): void; */ export function webPubSub(name: string, options: WebPubSubFunctionOptions): void; +export function mcpServer(name: string, options: McpServerFunctionOptions): void; + export * as hook from './hooks/registerHook'; diff --git a/types/index.d.ts b/types/index.d.ts index 2676a89..10edcf6 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -17,6 +17,7 @@ export * from './hooks/logHooks'; export * from './http'; export * as input from './input'; export * from './InvocationContext'; +export * from './mcpServer'; export * from './mySql'; export * as output from './output'; export * from './serviceBus'; diff --git a/types/mcpServer.d.ts b/types/mcpServer.d.ts new file mode 100644 index 0000000..80b9df0 --- /dev/null +++ b/types/mcpServer.d.ts @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { FunctionOptions, FunctionResult, FunctionTrigger } from './index'; +import { InvocationContext } from './InvocationContext'; + +export type McpServerTriggerHandler = (messages: unknown, context: InvocationContext) => FunctionResult; + +export interface McpServerFunctionOptions extends McpServerTriggerOptions, Partial { + handler: McpServerTriggerHandler; + + trigger?: McpServerTrigger; +} + +export interface McpServerTriggerOptions { + /** + * An app setting (or environment variable) with the service bus connection string + */ + toolName: string; + + /** + * An app setting (or environment variable) with the service bus connection string + */ + description: string; + + /** + * A dictionary of arguments associated with the trigger. + */ + toolProperties?: Record; +} +export type McpServerTrigger = FunctionTrigger & McpServerTriggerOptions; diff --git a/types/trigger.d.ts b/types/trigger.d.ts index f54764b..a480a22 100644 --- a/types/trigger.d.ts +++ b/types/trigger.d.ts @@ -7,6 +7,7 @@ import { EventHubTrigger, EventHubTriggerOptions } from './eventHub'; import { GenericTriggerOptions } from './generic'; import { HttpTrigger, HttpTriggerOptions } from './http'; import { FunctionTrigger } from './index'; +import { McpServerFunctionOptions, McpServerTrigger } from './mcpServer'; import { MySqlTrigger, MySqlTriggerOptions } from './mySql'; import { ServiceBusQueueTrigger, @@ -90,6 +91,11 @@ export function mySql(options: MySqlTriggerOptions): MySqlTrigger; */ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger; +/** + * [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-trigger?pivots=programming-language-javascript) + */ +export function mcpServer(options: McpServerFunctionOptions): McpServerTrigger; + /** * A generic option that can be used for any trigger type * Use this method if your desired trigger type does not already have its own method From b4a62214153501c38be02e523d8570051747f220 Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 19:32:01 -0700 Subject: [PATCH 02/17] Fixing the naming --- src/app.ts | 6 +++--- src/trigger.ts | 6 +++--- types/app.d.ts | 4 ++-- types/index.d.ts | 2 +- types/{mcpServer.d.ts => mcpTool.d.ts} | 12 ++++++------ types/trigger.d.ts | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) rename types/{mcpServer.d.ts => mcpTool.d.ts} (58%) diff --git a/src/app.ts b/src/app.ts index b8cf880..acc3604 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,7 +11,7 @@ import { HttpHandler, HttpMethod, HttpMethodFunctionOptions, - McpServerFunctionOptions, + McpToolFunctionOptions, MySqlFunctionOptions, ServiceBusQueueFunctionOptions, ServiceBusTopicFunctionOptions, @@ -146,8 +146,8 @@ export function webPubSub(name: string, options: WebPubSubFunctionOptions): void generic(name, convertToGenericOptions(options, trigger.webPubSub)); } -export function mcpServer(name: string, options: McpServerFunctionOptions): void { - generic(name, convertToGenericOptions(options, trigger.mcpServer)); +export function mcpTool(name: string, options: McpToolFunctionOptions): void { + generic(name, convertToGenericOptions(options, trigger.mcpTool)); } export function generic(name: string, options: GenericFunctionOptions): void { diff --git a/src/trigger.ts b/src/trigger.ts index ec30d83..007d5bb 100644 --- a/src/trigger.ts +++ b/src/trigger.ts @@ -12,8 +12,8 @@ import { GenericTriggerOptions, HttpTrigger, HttpTriggerOptions, - McpServerTrigger, - McpServerTriggerOptions, + McpToolTrigger, + McpToolTriggerOptions, MySqlTrigger, MySqlTriggerOptions, ServiceBusQueueTrigger, @@ -128,7 +128,7 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger { }); } -export function mcpServer(options: McpServerTriggerOptions): McpServerTrigger { +export function mcpTool(options: McpToolTriggerOptions): McpToolTrigger { return addTriggerBindingName({ ...options, type: 'mcpToolTrigger', diff --git a/types/app.d.ts b/types/app.d.ts index 14479bf..db3e059 100644 --- a/types/app.d.ts +++ b/types/app.d.ts @@ -6,7 +6,7 @@ import { EventGridFunctionOptions } from './eventGrid'; import { EventHubFunctionOptions } from './eventHub'; import { GenericFunctionOptions } from './generic'; import { HttpFunctionOptions, HttpHandler, HttpMethodFunctionOptions } from './http'; -import { McpServerFunctionOptions } from './mcpServer'; +import { McpToolFunctionOptions } from './mcpTool'; import { MySqlFunctionOptions } from './mySql'; import { ServiceBusQueueFunctionOptions, ServiceBusTopicFunctionOptions } from './serviceBus'; import { SetupOptions } from './setup'; @@ -197,6 +197,6 @@ export function generic(name: string, options: GenericFunctionOptions): void; */ export function webPubSub(name: string, options: WebPubSubFunctionOptions): void; -export function mcpServer(name: string, options: McpServerFunctionOptions): void; +export function mcpTool(name: string, options: McpToolFunctionOptions): void; export * as hook from './hooks/registerHook'; diff --git a/types/index.d.ts b/types/index.d.ts index 10edcf6..314c4c1 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -17,7 +17,7 @@ export * from './hooks/logHooks'; export * from './http'; export * as input from './input'; export * from './InvocationContext'; -export * from './mcpServer'; +export * from './mcpTool'; export * from './mySql'; export * as output from './output'; export * from './serviceBus'; diff --git a/types/mcpServer.d.ts b/types/mcpTool.d.ts similarity index 58% rename from types/mcpServer.d.ts rename to types/mcpTool.d.ts index 80b9df0..411d573 100644 --- a/types/mcpServer.d.ts +++ b/types/mcpTool.d.ts @@ -4,15 +4,15 @@ import { FunctionOptions, FunctionResult, FunctionTrigger } from './index'; import { InvocationContext } from './InvocationContext'; -export type McpServerTriggerHandler = (messages: unknown, context: InvocationContext) => FunctionResult; +export type McpToolTriggerHandler = (messages: unknown, context: InvocationContext) => FunctionResult; -export interface McpServerFunctionOptions extends McpServerTriggerOptions, Partial { - handler: McpServerTriggerHandler; +export interface McpToolFunctionOptions extends McpToolTriggerOptions, Partial { + handler: McpToolTriggerHandler; - trigger?: McpServerTrigger; + trigger?: McpToolTrigger; } -export interface McpServerTriggerOptions { +export interface McpToolTriggerOptions { /** * An app setting (or environment variable) with the service bus connection string */ @@ -28,4 +28,4 @@ export interface McpServerTriggerOptions { */ toolProperties?: Record; } -export type McpServerTrigger = FunctionTrigger & McpServerTriggerOptions; +export type McpToolTrigger = FunctionTrigger & McpToolTriggerOptions; diff --git a/types/trigger.d.ts b/types/trigger.d.ts index a480a22..ef3d73b 100644 --- a/types/trigger.d.ts +++ b/types/trigger.d.ts @@ -7,7 +7,7 @@ import { EventHubTrigger, EventHubTriggerOptions } from './eventHub'; import { GenericTriggerOptions } from './generic'; import { HttpTrigger, HttpTriggerOptions } from './http'; import { FunctionTrigger } from './index'; -import { McpServerFunctionOptions, McpServerTrigger } from './mcpServer'; +import { McpToolFunctionOptions, McpToolTrigger } from './mcpTool'; import { MySqlTrigger, MySqlTriggerOptions } from './mySql'; import { ServiceBusQueueTrigger, @@ -94,7 +94,7 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger; /** * [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-trigger?pivots=programming-language-javascript) */ -export function mcpServer(options: McpServerFunctionOptions): McpServerTrigger; +export function mcpTool(options: McpToolFunctionOptions): McpToolTrigger; /** * A generic option that can be used for any trigger type From 1a9baddbb87bc61eeb1e72d8e6cd209a4652108c Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 21:25:03 -0700 Subject: [PATCH 03/17] Adding comments --- src/app.ts | 7 +++++++ src/trigger.ts | 7 +++++++ types/mcpTool.d.ts | 35 ++++++++++++++++++++++++++++++++--- types/trigger.d.ts | 2 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/app.ts b/src/app.ts index acc3604..84d4be7 100644 --- a/src/app.ts +++ b/src/app.ts @@ -146,6 +146,13 @@ export function webPubSub(name: string, options: WebPubSubFunctionOptions): void generic(name, convertToGenericOptions(options, trigger.webPubSub)); } +/** + * Registers an MCP Tool function in your app. + * This function is triggered by MCP Tool events and allows you to define the behavior of the function. + * + * @param name - The name of the function. This must be unique within your app and is primarily used for tracking purposes. + * @param options - Configuration options for the MCP Tool function, including the handler and trigger-specific settings. + */ export function mcpTool(name: string, options: McpToolFunctionOptions): void { generic(name, convertToGenericOptions(options, trigger.mcpTool)); } diff --git a/src/trigger.ts b/src/trigger.ts index 007d5bb..6771081 100644 --- a/src/trigger.ts +++ b/src/trigger.ts @@ -128,6 +128,13 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger { }); } +/** + * Creates an MCP Tool trigger configuration. + * This function is used to define an MCP Tool trigger for an Azure Function. + * + * @param options - The configuration options for the MCP Tool trigger, including tool-specific metadata. + * @returns An MCP Tool trigger object with the specified configuration. + */ export function mcpTool(options: McpToolTriggerOptions): McpToolTrigger { return addTriggerBindingName({ ...options, diff --git a/types/mcpTool.d.ts b/types/mcpTool.d.ts index 411d573..24a5ad3 100644 --- a/types/mcpTool.d.ts +++ b/types/mcpTool.d.ts @@ -4,28 +4,57 @@ import { FunctionOptions, FunctionResult, FunctionTrigger } from './index'; import { InvocationContext } from './InvocationContext'; +/** + * A handler function for MCP Tool triggers. + * + * @param messages - The messages or data received by the trigger. + * @param context - The invocation context for the function. + * @returns A result that can be a promise or a synchronous value. + */ export type McpToolTriggerHandler = (messages: unknown, context: InvocationContext) => FunctionResult; +/** + * Configuration options for an MCP Tool function. + * This includes trigger-specific options and general function options. + */ export interface McpToolFunctionOptions extends McpToolTriggerOptions, Partial { + /** + * The handler function to execute when the trigger is invoked. + */ handler: McpToolTriggerHandler; + /** + * The trigger configuration for the MCP Tool. + */ trigger?: McpToolTrigger; } +/** + * Configuration options for an MCP Tool trigger. + * These options define the behavior and metadata for the trigger. + */ export interface McpToolTriggerOptions { /** - * An app setting (or environment variable) with the service bus connection string + * The name of the tool associated with the trigger. + * This is typically an app setting or environment variable. */ toolName: string; /** - * An app setting (or environment variable) with the service bus connection string + * A description of the tool or trigger. + * This provides additional context about the trigger's purpose. */ description: string; /** - * A dictionary of arguments associated with the trigger. + * Additional properties or metadata for the tool. + * This is a dictionary of key-value pairs that can be used to configure the trigger. */ toolProperties?: Record; } + +/** + * Represents an MCP Tool trigger, combining base function trigger options + * with MCP Tool-specific trigger options. + */ export type McpToolTrigger = FunctionTrigger & McpToolTriggerOptions; diff --git a/types/trigger.d.ts b/types/trigger.d.ts index ef3d73b..e8105d2 100644 --- a/types/trigger.d.ts +++ b/types/trigger.d.ts @@ -92,7 +92,7 @@ export function mySql(options: MySqlTriggerOptions): MySqlTrigger; export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger; /** - * [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-trigger?pivots=programming-language-javascript) + * [Link to docs and examples](//TODO Add link to docs and examples) */ export function mcpTool(options: McpToolFunctionOptions): McpToolTrigger; From 3afe50a076fc9f8796198978f62891db48a0076c Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 22:58:10 -0700 Subject: [PATCH 04/17] 4.8.0-beta.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2060284..4566b3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.7.0", + "version": "4.8.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.7.0", + "version": "4.8.0-beta.0", "license": "MIT", "dependencies": { "cookie": "^0.7.0", diff --git a/package.json b/package.json index 10b16f3..a3886d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.7.0", + "version": "4.8.0-beta.0", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From 87cf071ea99b83aaa490be2a7f9a5c91c0aeae3b Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 22:58:34 -0700 Subject: [PATCH 05/17] 4.8.0-beta.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4566b3c..7bb6a4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.8.0-beta.0", + "version": "4.8.0-beta.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.8.0-beta.0", + "version": "4.8.0-beta.1", "license": "MIT", "dependencies": { "cookie": "^0.7.0", diff --git a/package.json b/package.json index a3886d4..b04c9b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.8.0-beta.0", + "version": "4.8.0-beta.1", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From 881a6ba1f74f23062e41cfaf3f1239b2ad4e4604 Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 22:58:46 -0700 Subject: [PATCH 06/17] 4.9.0-beta.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7bb6a4d..f31b5cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.8.0-beta.1", + "version": "4.9.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.8.0-beta.1", + "version": "4.9.0-beta.0", "license": "MIT", "dependencies": { "cookie": "^0.7.0", diff --git a/package.json b/package.json index b04c9b1..8884320 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.8.0-beta.1", + "version": "4.9.0-beta.0", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From 1930d06184b7f265dd7a381972505507a63faf73 Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 23:10:42 -0700 Subject: [PATCH 07/17] 4.10.0-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f31b5cb..eb38579 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.9.0-beta.0", + "version": "4.10.0-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.9.0-beta.0", + "version": "4.10.0-alpha.0", "license": "MIT", "dependencies": { "cookie": "^0.7.0", diff --git a/package.json b/package.json index 8884320..2497895 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.9.0-beta.0", + "version": "4.10.0-alpha.0", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From 27680e4d4c09f75ec1c21ed2604f5da95f9eb882 Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 23:16:42 -0700 Subject: [PATCH 08/17] 4.10.0-experimental.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb38579..42a21ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.10.0-alpha.0", + "version": "4.10.0-experimental.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.10.0-alpha.0", + "version": "4.10.0-experimental.0", "license": "MIT", "dependencies": { "cookie": "^0.7.0", diff --git a/package.json b/package.json index 2497895..1c592a5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.10.0-alpha.0", + "version": "4.10.0-experimental.0", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From e9e6128cc7a4c157b21dfb2519431b34e136aabd Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 23:17:07 -0700 Subject: [PATCH 09/17] 4.10.0-experimental.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42a21ae..21aa6b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.10.0-experimental.0", + "version": "4.10.0-experimental.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.10.0-experimental.0", + "version": "4.10.0-experimental.1", "license": "MIT", "dependencies": { "cookie": "^0.7.0", diff --git a/package.json b/package.json index 1c592a5..2ecc25e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.10.0-experimental.0", + "version": "4.10.0-experimental.1", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From 256733738e4e5da772f5c60290bf1ba97a8b8d9b Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Sat, 29 Mar 2025 23:22:05 -0700 Subject: [PATCH 10/17] Updating Pacakge for Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ecc25e..e50ef76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@azure/functions", - "version": "4.10.0-experimental.1", + "version": "4.8.0-experimental.0", "description": "Microsoft Azure Functions NodeJS Framework", "keywords": [ "azure", From 771f873959c6a3b7ac331768fc25b0fd97577ed9 Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Tue, 1 Apr 2025 12:31:12 -0700 Subject: [PATCH 11/17] Adding Properties --- types/mcpTool.d.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/types/mcpTool.d.ts b/types/mcpTool.d.ts index 24a5ad3..a456dba 100644 --- a/types/mcpTool.d.ts +++ b/types/mcpTool.d.ts @@ -50,7 +50,7 @@ export interface McpToolTriggerOptions { * Additional properties or metadata for the tool. * This is a dictionary of key-value pairs that can be used to configure the trigger. */ - toolProperties?: Record; + toolProperties?: string; } /** @@ -58,3 +58,21 @@ export interface McpToolTriggerOptions { * with MCP Tool-specific trigger options. */ export type McpToolTrigger = FunctionTrigger & McpToolTriggerOptions; + +export interface McpToolProperty { + /** + * The name of the property. + */ + propertyName: string; + + /** + * The value of the property. + */ + propertyValue: string; + + /** + * A description of the property. + * This provides additional context about the purpose or usage of the property. + */ + description: string; +} From d16d7d4b2e02dbc154afbf67517dd1b98052e49c Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Tue, 1 Apr 2025 13:10:44 -0700 Subject: [PATCH 12/17] Adding .net type fluent API --- src/trigger.ts | 19 ++++++++++++++++++- types/mcpTool.d.ts | 26 +++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/trigger.ts b/src/trigger.ts index 6771081..e38f73e 100644 --- a/src/trigger.ts +++ b/src/trigger.ts @@ -14,6 +14,7 @@ import { HttpTriggerOptions, McpToolTrigger, McpToolTriggerOptions, + McpToolTriggerOptionsToRpc, MySqlTrigger, MySqlTriggerOptions, ServiceBusQueueTrigger, @@ -128,6 +129,22 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger { }); } +/** + * Converts an McpToolTriggerOptions object to an McpToolTriggerOptionsToRpc object. + * + * @param mcpToolTriggerOptions - The input options to be converted. + * @returns The converted McpToolTriggerOptionsToRpc object. + */ +export function converToMcpToolTriggerOptionsToRpc( + mcpToolTriggerOptions: McpToolTriggerOptions +): McpToolTriggerOptionsToRpc { + return { + toolName: mcpToolTriggerOptions.toolName, + description: mcpToolTriggerOptions.description, + toolProperties: JSON.stringify(mcpToolTriggerOptions.toolProperties), + }; +} + /** * Creates an MCP Tool trigger configuration. * This function is used to define an MCP Tool trigger for an Azure Function. @@ -137,7 +154,7 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger { */ export function mcpTool(options: McpToolTriggerOptions): McpToolTrigger { return addTriggerBindingName({ - ...options, + ...converToMcpToolTriggerOptionsToRpc(options), type: 'mcpToolTrigger', }); } diff --git a/types/mcpTool.d.ts b/types/mcpTool.d.ts index a456dba..6e5a747 100644 --- a/types/mcpTool.d.ts +++ b/types/mcpTool.d.ts @@ -46,6 +46,30 @@ export interface McpToolTriggerOptions { */ description: string; + /** + * Additional properties or metadata for the tool. + * This is a dictionary of key-value pairs that can be used to configure the trigger. + */ + toolProperties?: McpToolProperty[]; +} + +/** + * Configuration options for an MCP Tool trigger. + * These options define the behavior and metadata for the trigger. + */ +export interface McpToolTriggerOptionsToRpc { + /** + * The name of the tool associated with the trigger. + * This is typically an app setting or environment variable. + */ + toolName: string; + + /** + * A description of the tool or trigger. + * This provides additional context about the trigger's purpose. + */ + description: string; + /** * Additional properties or metadata for the tool. * This is a dictionary of key-value pairs that can be used to configure the trigger. @@ -57,7 +81,7 @@ export interface McpToolTriggerOptions { * Represents an MCP Tool trigger, combining base function trigger options * with MCP Tool-specific trigger options. */ -export type McpToolTrigger = FunctionTrigger & McpToolTriggerOptions; +export type McpToolTrigger = FunctionTrigger & McpToolTriggerOptionsToRpc; export interface McpToolProperty { /** From 9ab24aaa5417a84caf628ad356df863fa3d0bd8e Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Tue, 1 Apr 2025 20:44:11 -0700 Subject: [PATCH 13/17] Adding support for zod conversion --- .../toMcpToolTriggerOptionsToRpc.ts | 92 +++++++++++++++++++ src/trigger.ts | 18 +--- types/mcpTool.d.ts | 2 +- 3 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 src/converters/toMcpToolTriggerOptionsToRpc.ts diff --git a/src/converters/toMcpToolTriggerOptionsToRpc.ts b/src/converters/toMcpToolTriggerOptionsToRpc.ts new file mode 100644 index 0000000..8816765 --- /dev/null +++ b/src/converters/toMcpToolTriggerOptionsToRpc.ts @@ -0,0 +1,92 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { McpToolProperty, McpToolTriggerOptions, McpToolTriggerOptionsToRpc } from '../../types'; + +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +/** + * Converts an McpToolTriggerOptions object to an McpToolTriggerOptionsToRpc object. + * + * @param mcpToolTriggerOptions - The input options to be converted. + * @returns The converted McpToolTriggerOptionsToRpc object. + */ +export function converToMcpToolTriggerOptionsToRpc( + mcpToolTriggerOptions: McpToolTriggerOptions +): McpToolTriggerOptionsToRpc { + // Check if toolProperties is an array of McpToolProperty objects + if (Array.isArray(mcpToolTriggerOptions.toolProperties)) { + const isValid = mcpToolTriggerOptions.toolProperties.every(isMcpToolProperty); + + if (isValid) { + return { + toolName: mcpToolTriggerOptions.toolName, + description: mcpToolTriggerOptions.description, + toolProperties: JSON.stringify(mcpToolTriggerOptions.toolProperties), + }; + } + } else if ( + mcpToolTriggerOptions?.toolProperties !== null && + typeof mcpToolTriggerOptions.toolProperties === 'object' + ) { + return { + toolName: mcpToolTriggerOptions.toolName, + description: mcpToolTriggerOptions.description, + toolProperties: JSON.stringify( + Object.entries(mcpToolTriggerOptions?.toolProperties as Record).map( + ([key, value]) => ({ + propertyName: key, + propertyType: getPropertyType(value), + description: (value as { _def: { description: string } })._def.description, + }) + ) + ), + }; + } + // Handle cases where toolProperties is not an array + throw new Error('Invalid toolProperties: Expected an array of McpToolProperty objects or zod objects.'); +} + +// Helper function to infer property type from zod schema +function getPropertyType(zodType: any): string { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + switch (zodType._def.typeName) { + case 'ZodNumber': + return 'number'; + case 'ZodString': + return 'string'; + case 'ZodBoolean': + return 'boolean'; + case 'ZodArray': + return 'array'; + case 'ZodObject': + return 'object'; + default: + return 'unknown'; + } +} + +/** + * Type guard to check if a given object is of type McpToolProperty. + * + * @param property - The object to check. + * @returns True if the object is of type McpToolProperty, otherwise false. + * + * This function ensures that the object: + * - Is not null and is of type 'object'. + * - Contains the required properties: 'propertyName', 'propertyValue', and 'description'. + * - Each of these properties is of the correct type (string). + */ +function isMcpToolProperty(property: unknown): property is McpToolProperty { + return ( + typeof property === 'object' && + property !== null && + 'propertyName' in property && + 'propertyValue' in property && + 'description' in property && + typeof (property as McpToolProperty).propertyName === 'string' && + typeof (property as McpToolProperty).propertyValue === 'string' && + typeof (property as McpToolProperty).description === 'string' + ); +} diff --git a/src/trigger.ts b/src/trigger.ts index e38f73e..1a25f69 100644 --- a/src/trigger.ts +++ b/src/trigger.ts @@ -14,7 +14,6 @@ import { HttpTriggerOptions, McpToolTrigger, McpToolTriggerOptions, - McpToolTriggerOptionsToRpc, MySqlTrigger, MySqlTriggerOptions, ServiceBusQueueTrigger, @@ -35,6 +34,7 @@ import { WebPubSubTriggerOptions, } from '@azure/functions'; import { addBindingName } from './addBindingName'; +import { converToMcpToolTriggerOptionsToRpc } from './converters/toMcpToolTriggerOptionsToRpc'; export function http(options: HttpTriggerOptions): HttpTrigger { return addTriggerBindingName({ @@ -129,22 +129,6 @@ export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger { }); } -/** - * Converts an McpToolTriggerOptions object to an McpToolTriggerOptionsToRpc object. - * - * @param mcpToolTriggerOptions - The input options to be converted. - * @returns The converted McpToolTriggerOptionsToRpc object. - */ -export function converToMcpToolTriggerOptionsToRpc( - mcpToolTriggerOptions: McpToolTriggerOptions -): McpToolTriggerOptionsToRpc { - return { - toolName: mcpToolTriggerOptions.toolName, - description: mcpToolTriggerOptions.description, - toolProperties: JSON.stringify(mcpToolTriggerOptions.toolProperties), - }; -} - /** * Creates an MCP Tool trigger configuration. * This function is used to define an MCP Tool trigger for an Azure Function. diff --git a/types/mcpTool.d.ts b/types/mcpTool.d.ts index 6e5a747..91aa366 100644 --- a/types/mcpTool.d.ts +++ b/types/mcpTool.d.ts @@ -50,7 +50,7 @@ export interface McpToolTriggerOptions { * Additional properties or metadata for the tool. * This is a dictionary of key-value pairs that can be used to configure the trigger. */ - toolProperties?: McpToolProperty[]; + toolProperties?: any | McpToolProperty[]; } /** From c989f9e0f547233d9827e897a420552ccc6703ef Mon Sep 17 00:00:00 2001 From: swapnil-nagar Date: Tue, 1 Apr 2025 23:15:50 -0700 Subject: [PATCH 14/17] Adding null toolProperties support --- src/converters/toMcpToolTriggerOptionsToRpc.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/converters/toMcpToolTriggerOptionsToRpc.ts b/src/converters/toMcpToolTriggerOptionsToRpc.ts index 8816765..b103b73 100644 --- a/src/converters/toMcpToolTriggerOptionsToRpc.ts +++ b/src/converters/toMcpToolTriggerOptionsToRpc.ts @@ -15,10 +15,18 @@ import { McpToolProperty, McpToolTriggerOptions, McpToolTriggerOptionsToRpc } fr export function converToMcpToolTriggerOptionsToRpc( mcpToolTriggerOptions: McpToolTriggerOptions ): McpToolTriggerOptionsToRpc { - // Check if toolProperties is an array of McpToolProperty objects + //Check for null or undefined input + if (!mcpToolTriggerOptions?.toolProperties) { + return { + toolName: mcpToolTriggerOptions.toolName, + description: mcpToolTriggerOptions.description, + toolProperties: JSON.stringify([]), // Default to an empty array + }; + } + + //Check if toolProperties is an array of McpToolProperty objects if (Array.isArray(mcpToolTriggerOptions.toolProperties)) { const isValid = mcpToolTriggerOptions.toolProperties.every(isMcpToolProperty); - if (isValid) { return { toolName: mcpToolTriggerOptions.toolName, @@ -26,7 +34,9 @@ export function converToMcpToolTriggerOptionsToRpc( toolProperties: JSON.stringify(mcpToolTriggerOptions.toolProperties), }; } - } else if ( + } + // Handle cases where toolProperties is a zod schema or other object types + else if ( mcpToolTriggerOptions?.toolProperties !== null && typeof mcpToolTriggerOptions.toolProperties === 'object' ) { From 02469f2508edc6a8f8306fd62c017720caf8f45d Mon Sep 17 00:00:00 2001 From: Swapnil Nagar Date: Mon, 14 Apr 2025 00:58:07 -0700 Subject: [PATCH 15/17] Adding z.Object support --- .../toMcpToolTriggerOptionsToRpc.ts | 116 ++++++++++++------ 1 file changed, 76 insertions(+), 40 deletions(-) diff --git a/src/converters/toMcpToolTriggerOptionsToRpc.ts b/src/converters/toMcpToolTriggerOptionsToRpc.ts index b103b73..51c283a 100644 --- a/src/converters/toMcpToolTriggerOptionsToRpc.ts +++ b/src/converters/toMcpToolTriggerOptionsToRpc.ts @@ -15,67 +15,103 @@ import { McpToolProperty, McpToolTriggerOptions, McpToolTriggerOptionsToRpc } fr export function converToMcpToolTriggerOptionsToRpc( mcpToolTriggerOptions: McpToolTriggerOptions ): McpToolTriggerOptionsToRpc { - //Check for null or undefined input + // Base object for the return value + const baseResult = { + toolName: mcpToolTriggerOptions.toolName, + description: mcpToolTriggerOptions.description, + }; + + // Check for null or undefined toolProperties if (!mcpToolTriggerOptions?.toolProperties) { return { - toolName: mcpToolTriggerOptions.toolName, - description: mcpToolTriggerOptions.description, + ...baseResult, toolProperties: JSON.stringify([]), // Default to an empty array }; } - //Check if toolProperties is an array of McpToolProperty objects + // Check if toolProperties is an array of McpToolProperty objects if (Array.isArray(mcpToolTriggerOptions.toolProperties)) { const isValid = mcpToolTriggerOptions.toolProperties.every(isMcpToolProperty); if (isValid) { return { - toolName: mcpToolTriggerOptions.toolName, - description: mcpToolTriggerOptions.description, + ...baseResult, toolProperties: JSON.stringify(mcpToolTriggerOptions.toolProperties), }; + } else { + throw new Error('Invalid toolProperties: Array contains invalid McpToolProperty objects.'); } } - // Handle cases where toolProperties is a zod schema or other object types - else if ( - mcpToolTriggerOptions?.toolProperties !== null && - typeof mcpToolTriggerOptions.toolProperties === 'object' - ) { + + // Handle cases where toolProperties is an object (e.g., Zod schema) + if (typeof mcpToolTriggerOptions.toolProperties === 'object') { + let isZodObject = false; + + type ZodPropertyDef = { + description?: string; + typeName: string; + }; + + // type ZodShape = Record; + // type PlainObjectShape = Record; + // Narrow the type of `shape` based on whether the input is a Zod object or plain object + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + // const shape: ZodShape | PlainObjectShape = isZodObject + // ? (mcpToolTriggerOptions.toolProperties as { shape: ZodShape }).shape + // : typeof mcpToolTriggerOptions.toolProperties === 'object' + // ? mcpToolTriggerOptions.toolProperties + // : {}; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (mcpToolTriggerOptions.toolProperties?._def?.typeName === 'ZodObject') { + isZodObject = true; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const shape: Record = isZodObject + ? (mcpToolTriggerOptions.toolProperties as { shape: Record }).shape + : mcpToolTriggerOptions.toolProperties; // Handle plain objects directly + + const result = Object.keys(shape).map((propertyName) => { + const property = shape[propertyName] as { _def: ZodPropertyDef }; + const description = property?._def?.description || ''; + const propertyType = property?._def?.typeName?.toLowerCase() || 'unknown'; // Extract type name or default to "unknown" + + return { + propertyName, + propertyType, + description, + }; + }); + return { - toolName: mcpToolTriggerOptions.toolName, - description: mcpToolTriggerOptions.description, - toolProperties: JSON.stringify( - Object.entries(mcpToolTriggerOptions?.toolProperties as Record).map( - ([key, value]) => ({ - propertyName: key, - propertyType: getPropertyType(value), - description: (value as { _def: { description: string } })._def.description, - }) - ) - ), + ...baseResult, + toolProperties: JSON.stringify(result), }; } // Handle cases where toolProperties is not an array throw new Error('Invalid toolProperties: Expected an array of McpToolProperty objects or zod objects.'); } -// Helper function to infer property type from zod schema -function getPropertyType(zodType: any): string { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - switch (zodType._def.typeName) { - case 'ZodNumber': - return 'number'; - case 'ZodString': - return 'string'; - case 'ZodBoolean': - return 'boolean'; - case 'ZodArray': - return 'array'; - case 'ZodObject': - return 'object'; - default: - return 'unknown'; - } -} +// } +// // Helper function to infer property type from zod schema +// function getPropertyType(zodType: any): string { +// // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-plus-operands +// console.log('Here: ' + zodType); +// // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +// switch (zodType._def.typeName) { +// case 'ZodNumber': +// return 'number'; +// case 'ZodString': +// return 'string'; +// case 'ZodBoolean': +// return 'boolean'; +// case 'ZodArray': +// return 'array'; +// case 'ZodObject': +// return 'object'; +// default: +// return 'unknown'; +// } +// } /** * Type guard to check if a given object is of type McpToolProperty. From 39990b6ea57fde89f8f5e06029662b476ef3153f Mon Sep 17 00:00:00 2001 From: Swapnil Nagar Date: Mon, 14 Apr 2025 01:33:50 -0700 Subject: [PATCH 16/17] Fixing linting issue --- .../toMcpToolTriggerOptionsToRpc.ts | 62 +++++++------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/src/converters/toMcpToolTriggerOptionsToRpc.ts b/src/converters/toMcpToolTriggerOptionsToRpc.ts index 51c283a..3bcda3d 100644 --- a/src/converters/toMcpToolTriggerOptionsToRpc.ts +++ b/src/converters/toMcpToolTriggerOptionsToRpc.ts @@ -44,32 +44,38 @@ export function converToMcpToolTriggerOptionsToRpc( // Handle cases where toolProperties is an object (e.g., Zod schema) if (typeof mcpToolTriggerOptions.toolProperties === 'object') { - let isZodObject = false; - + // Define the type of the ZodObject shape and ZodPropertyDef type ZodPropertyDef = { description?: string; typeName: string; }; + type ZodObjectShape = Record; - // type ZodShape = Record; - // type PlainObjectShape = Record; - // Narrow the type of `shape` based on whether the input is a Zod object or plain object - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - // const shape: ZodShape | PlainObjectShape = isZodObject - // ? (mcpToolTriggerOptions.toolProperties as { shape: ZodShape }).shape - // : typeof mcpToolTriggerOptions.toolProperties === 'object' - // ? mcpToolTriggerOptions.toolProperties - // : {}; + // Define the type of the toolProperties object + type ToolProperties = + | { + _def?: { + typeName?: string; + }; + shape?: ZodObjectShape; + } + | Record; + + let isZodObject = false; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (mcpToolTriggerOptions.toolProperties?._def?.typeName === 'ZodObject') { + const toolProperties = mcpToolTriggerOptions.toolProperties as ToolProperties; + + // Check if the object is a ZodObject + if ((toolProperties?._def as { typeName?: string })?.typeName === 'ZodObject') { isZodObject = true; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const shape: Record = isZodObject - ? (mcpToolTriggerOptions.toolProperties as { shape: Record }).shape - : mcpToolTriggerOptions.toolProperties; // Handle plain objects directly + // Check if shape is a valid ZodObject shape + const shape: ZodObjectShape | Record = isZodObject + ? (toolProperties as { shape: ZodObjectShape }).shape + : toolProperties; + + // Extract properties from the ZodObject shape const result = Object.keys(shape).map((propertyName) => { const property = shape[propertyName] as { _def: ZodPropertyDef }; const description = property?._def?.description || ''; @@ -91,28 +97,6 @@ export function converToMcpToolTriggerOptionsToRpc( throw new Error('Invalid toolProperties: Expected an array of McpToolProperty objects or zod objects.'); } -// } -// // Helper function to infer property type from zod schema -// function getPropertyType(zodType: any): string { -// // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-plus-operands -// console.log('Here: ' + zodType); -// // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -// switch (zodType._def.typeName) { -// case 'ZodNumber': -// return 'number'; -// case 'ZodString': -// return 'string'; -// case 'ZodBoolean': -// return 'boolean'; -// case 'ZodArray': -// return 'array'; -// case 'ZodObject': -// return 'object'; -// default: -// return 'unknown'; -// } -// } - /** * Type guard to check if a given object is of type McpToolProperty. * From d1ab8d850ac67a82493068503692a6b0d4aafa7c Mon Sep 17 00:00:00 2001 From: Swapnil Nagar Date: Mon, 14 Apr 2025 03:33:58 -0700 Subject: [PATCH 17/17] Adding more types --- .../toMcpToolTriggerOptionsToRpc.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/converters/toMcpToolTriggerOptionsToRpc.ts b/src/converters/toMcpToolTriggerOptionsToRpc.ts index 3bcda3d..bdaa833 100644 --- a/src/converters/toMcpToolTriggerOptionsToRpc.ts +++ b/src/converters/toMcpToolTriggerOptionsToRpc.ts @@ -79,7 +79,7 @@ export function converToMcpToolTriggerOptionsToRpc( const result = Object.keys(shape).map((propertyName) => { const property = shape[propertyName] as { _def: ZodPropertyDef }; const description = property?._def?.description || ''; - const propertyType = property?._def?.typeName?.toLowerCase() || 'unknown'; // Extract type name or default to "unknown" + const propertyType = getPropertyType(property?._def?.typeName?.toLowerCase() || 'unknown'); // Extract type name or default to "unknown" return { propertyName, @@ -88,6 +88,11 @@ export function converToMcpToolTriggerOptionsToRpc( }; }); + console.log('result', { + ...baseResult, + toolProperties: JSON.stringify(result), + }); + return { ...baseResult, toolProperties: JSON.stringify(result), @@ -97,6 +102,31 @@ export function converToMcpToolTriggerOptionsToRpc( throw new Error('Invalid toolProperties: Expected an array of McpToolProperty objects or zod objects.'); } +// Helper function to infer property type from zod schema +function getPropertyType(zodType: string): string { + switch (zodType) { + case 'zodnumber': + return 'number'; + case 'zodstring': + return 'string'; + case 'zodboolean': + return 'boolean'; + case 'zodarray': + return 'array'; + case 'zodobject': + return 'object'; + case 'zodbigint': + return 'long'; + case 'zoddate': + return 'DateTime'; + case 'zodtuple': + return 'Tuple'; + default: + console.warn(`Unknown zod type: ${zodType}`); + return 'unknown'; + } +} + /** * Type guard to check if a given object is of type McpToolProperty. *