Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure/functions",
"version": "4.11.1",
"version": "4.12.0-preview.2",
"description": "Microsoft Azure Functions NodeJS Framework",
"keywords": [
"azure",
Expand Down
12 changes: 12 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
HttpHandler,
HttpMethod,
HttpMethodFunctionOptions,
McpResourceFunctionOptions,
McpToolFunctionOptions,
MySqlFunctionOptions,
ServiceBusQueueFunctionOptions,
Expand Down Expand Up @@ -157,6 +158,17 @@ export function mcpTool(name: string, options: McpToolFunctionOptions): void {
generic(name, convertToGenericOptions(options, trigger.mcpTool));
}

/**
* Registers an MCP Resource function in your app.
* This function is triggered when an MCP client reads the resource and allows you to define the resource content.
*
* @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 Resource function, including the handler and trigger-specific settings.
*/
export function mcpResource(name: string, options: McpResourceFunctionOptions): void {
generic(name, convertToGenericOptions(options, trigger.mcpResource));
}

export function generic(name: string, options: GenericFunctionOptions): void {
if (!hasSetModel) {
setProgrammingModel();
Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

export const version = '4.11.1';
export const version = '4.12.0-preview.1';

export const returnBindingKey = '$return';
64 changes: 64 additions & 0 deletions src/converters/toMcpResourceTriggerOptionsToRpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

import { McpResourceTriggerOptions, McpResourceTriggerOptionsToRpc } from '../../types';

/**
* Converts an McpResourceTriggerOptions object to an McpResourceTriggerOptionsToRpc object.
*
* @param options - The input options to be converted.
* @returns The converted McpResourceTriggerOptionsToRpc object.
* @throws Error if required properties are missing or invalid.
*/
export function convertToMcpResourceTriggerOptionsToRpc(
options: McpResourceTriggerOptions
): McpResourceTriggerOptionsToRpc {
// Validate required properties
if (!options.uri || typeof options.uri !== 'string' || options.uri.trim() === '') {
throw new Error('MCP Resource trigger requires a valid "uri" property.');
}

if (!options.resourceName || typeof options.resourceName !== 'string' || options.resourceName.trim() === '') {
throw new Error('MCP Resource trigger requires a valid "resourceName" property.');
}

// Build the result object with required properties
const result: McpResourceTriggerOptionsToRpc = {
uri: options.uri,
resourceName: options.resourceName,
};

// Add optional properties if they are defined
if (options.title !== undefined) {
result.title = options.title;
}

if (options.description !== undefined) {
result.description = options.description;
}

if (options.mimeType !== undefined) {
result.mimeType = options.mimeType;
}

if (options.size !== undefined) {
if (typeof options.size !== 'number' || options.size < 0) {
throw new Error('MCP Resource trigger "size" must be a non-negative number.');
}
result.size = options.size;
}

if (options.metadata !== undefined) {
// Validate that metadata is a valid JSON string
if (typeof options.metadata === 'string' && options.metadata.trim() !== '') {
try {
JSON.parse(options.metadata);
} catch (e) {
throw new Error('MCP Resource trigger "metadata" must be a valid JSON string.');
}
}
result.metadata = options.metadata;
}

return result;
}
17 changes: 16 additions & 1 deletion src/converters/toMcpToolTriggerOptionsToRpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,27 @@ export function converToMcpToolTriggerOptionsToRpc(
normalizedProperties = undefined;
}

// Validate metadata if provided
if (mcpToolTriggerOptions.metadata !== undefined) {
if (typeof mcpToolTriggerOptions.metadata === 'string' && mcpToolTriggerOptions.metadata.trim() !== '') {
try {
JSON.parse(mcpToolTriggerOptions.metadata);
} catch (e) {
throw new Error('MCP Tool trigger "metadata" must be a valid JSON string.');
}
}
}

// If we successfully normalized the properties, use them
if (normalizedProperties !== undefined) {
return {
const result: McpToolTriggerOptionsToRpc = {
...baseResult,
toolProperties: JSON.stringify(normalizedProperties),
};
if (mcpToolTriggerOptions.metadata !== undefined) {
result.metadata = mcpToolTriggerOptions.metadata;
}
return result;
}

// Handle cases where toolProperties is not an array
Expand Down
18 changes: 18 additions & 0 deletions src/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
GenericTriggerOptions,
HttpTrigger,
HttpTriggerOptions,
McpResourceTrigger,
McpResourceTriggerOptions,
McpToolTrigger,
McpToolTriggerOptions,
MySqlTrigger,
Expand All @@ -34,6 +36,7 @@ import {
WebPubSubTriggerOptions,
} from '@azure/functions';
import { addBindingName } from './addBindingName';
import { convertToMcpResourceTriggerOptionsToRpc } from './converters/toMcpResourceTriggerOptionsToRpc';
import { converToMcpToolTriggerOptionsToRpc } from './converters/toMcpToolTriggerOptionsToRpc';

export function http(options: HttpTriggerOptions): HttpTrigger {
Expand Down Expand Up @@ -143,6 +146,21 @@ export function mcpTool(options: McpToolTriggerOptions): McpToolTrigger {
});
}

/**
* Creates an MCP Resource trigger configuration.
* This function is used to define an MCP Resource trigger for an Azure Function.
* MCP Resources are read-only data sources that can be accessed by MCP clients.
*
* @param options - The configuration options for the MCP Resource trigger, including resource-specific metadata.
* @returns An MCP Resource trigger object with the specified configuration.
*/
export function mcpResource(options: McpResourceTriggerOptions): McpResourceTrigger {
return addTriggerBindingName({
...convertToMcpResourceTriggerOptionsToRpc(options),
type: 'mcpResourceTrigger',
});
}

export function generic(options: GenericTriggerOptions): FunctionTrigger {
return addTriggerBindingName(options);
}
Expand Down
Loading
Loading