diff --git a/resources/backupTemplates/nodejs-4.x/templates/templates.json b/resources/backupTemplates/nodejs-4.x/templates/templates.json index 679df4775..6e645f5a3 100644 --- a/resources/backupTemplates/nodejs-4.x/templates/templates.json +++ b/resources/backupTemplates/nodejs-4.x/templates/templates.json @@ -656,5 +656,47 @@ "enabledInTryMode": true, "userPrompt": [] } + }, + { + "id": "McpResourceTrigger-JavaScript-4.x", + "runtime": "2", + "files": { + "%functionName%.js": "const { app } = require('@azure/functions');\n\n// Handler returns the content for the MCP resource when a client reads it.\nasync function mcpResourceHello(_resourceContext, context) {\n context.log('MCP Resource trigger function processed a request.');\n return 'Hello from MCP Resource!';\n}\n\n// Register a file-style MCP resource clients can discover and read.\napp.mcpResource('mcpFileResource', {\n uri: 'file://mcpFileResource.txt',\n resourceName: 'mcpFileResource',\n description: 'Simple MCP Resource that returns text content.',\n mimeType: 'text/plain',\n handler: mcpResourceHello\n});" + }, + "metadata": { + "defaultFunctionName": "mcpResourceTrigger", + "description": "$McpResourceTrigger_description", + "name": "MCP Resource Trigger", + "language": "JavaScript", + "triggerType": "mcpResourceTrigger", + "category": [ + "$temp_category_core", + "$temp_category_dataProcessing" + ], + "categoryStyle": "other", + "enabledInTryMode": false, + "userPrompt": [] + } + }, + { + "id": "McpResourceTrigger-TypeScript-4.x", + "runtime": "2", + "files": { + "%functionName%.ts": "import { app, InvocationContext } from \"@azure/functions\";\n\n// Handler returns the content for the MCP resource when a client reads it.\nexport async function mcpResourceHello(_resourceContext: unknown, context: InvocationContext): Promise {\n context.log('MCP Resource trigger function processed a request.');\n return 'Hello from MCP Resource!';\n}\n\n// Register a file-style MCP resource clients can discover and read.\napp.mcpResource('mcpFileResource', {\n uri: 'file://mcpFileResource.txt',\n resourceName: 'mcpFileResource',\n description: 'Simple MCP Resource that returns text content.',\n mimeType: 'text/plain',\n handler: mcpResourceHello\n});" + }, + "metadata": { + "defaultFunctionName": "mcpResourceTrigger", + "description": "$McpResourceTrigger_description", + "name": "MCP Resource Trigger", + "language": "TypeScript", + "triggerType": "mcpResourceTrigger", + "category": [ + "$temp_category_core", + "$temp_category_dataProcessing" + ], + "categoryStyle": "other", + "enabledInTryMode": false, + "userPrompt": [] + } } ] diff --git a/src/funcConfig/function.ts b/src/funcConfig/function.ts index 72ace8da8..c0c9ddd6f 100644 --- a/src/funcConfig/function.ts +++ b/src/funcConfig/function.ts @@ -39,15 +39,15 @@ export class ParsedFunctionJson { // eslint-disable-next-line @typescript-eslint/no-explicit-any public constructor(data: any) { - + if (typeof data === 'object' && data !== null && (data.triggerType !== undefined)) { this.template = data; this.data = {}; } - + else if (typeof data === 'object' && data !== null && (data.bindings === undefined || data.bindings instanceof Array)) { this.data = data; - + } else { this.data = {}; } @@ -85,10 +85,10 @@ export class ParsedFunctionJson { public get isMcpTrigger(): boolean { if (this.template?.triggerType) { - return /^mcptooltrigger/i.test(this.template.triggerType) || /^mcptrigger/i.test(this.template.triggerType); + return /^mcptooltrigger/i.test(this.template.triggerType) || /^mcptrigger/i.test(this.template.triggerType) || /^mcpresourcetrigger/i.test(this.template.triggerType); } if (this.triggerBinding && this.triggerBinding.type) { - return /^mcptooltrigger/i.test(this.triggerBinding.type) || /^mcptrigger/i.test(this.triggerBinding.type); + return /^mcptooltrigger/i.test(this.triggerBinding.type) || /^mcptrigger/i.test(this.triggerBinding.type) || /^mcpresourcetrigger/i.test(this.triggerBinding.type); } return false; diff --git a/src/templates/script/getScriptVerifiedTemplateIds.ts b/src/templates/script/getScriptVerifiedTemplateIds.ts index a7b1e5c65..0a4e490a5 100644 --- a/src/templates/script/getScriptVerifiedTemplateIds.ts +++ b/src/templates/script/getScriptVerifiedTemplateIds.ts @@ -39,6 +39,7 @@ export function getScriptVerifiedTemplateIds(version: string): (string | RegExp) 'EventGridBlobTrigger', 'SqlTrigger', 'McpToolTrigger', + 'McpResourceTrigger', 'MCPTrigger' ]); diff --git a/src/templates/script/parseScriptTemplatesV2.ts b/src/templates/script/parseScriptTemplatesV2.ts index b2f87227a..b164fe5fb 100644 --- a/src/templates/script/parseScriptTemplatesV2.ts +++ b/src/templates/script/parseScriptTemplatesV2.ts @@ -121,9 +121,10 @@ export function parseScriptTemplates(rawTemplates: RawTemplateV2[], rawBindings: } const isHttpTrigger = !!templateV2.id?.toLowerCase().includes('httptrigger-'); const isTimerTrigger = !!templateV2.id?.toLowerCase().includes('timertrigger-'); - // python and node.js use 2 different IDs for Mcp Triggers... because of course they do + // MCP trigger variants use multiple IDs across templates/providers. const isMcpTrigger = !!templateV2.id?.toLowerCase().includes('mcptooltrigger') || - templateV2.id?.toLowerCase().includes('mcptrigger'); + templateV2.id?.toLowerCase().includes('mcptrigger') || + templateV2.id?.toLowerCase().includes('mcpresourcetrigger'); templates.push(Object.assign(templateV2, { wizards: parsedJobs, diff --git a/test/templateCount.test.ts b/test/templateCount.test.ts index 7a6250662..1ae8d910a 100644 --- a/test/templateCount.test.ts +++ b/test/templateCount.test.ts @@ -30,14 +30,14 @@ function addSuite(source: TemplateSource | undefined): void { suite(`Template Count - ${source === undefined ? 'defaultOnExtensionActivation' : source}`, () => { const cases: TestCase[] = [ { language: ProjectLanguage.JavaScript, version: FuncVersion.v1, expectedCount: 8 }, - { language: ProjectLanguage.JavaScript, version: FuncVersion.v4, expectedCount: 18 }, + { language: ProjectLanguage.JavaScript, version: FuncVersion.v4, expectedCount: 18, backupExpectedCount: 18 }, { language: ProjectLanguage.CSharp, version: FuncVersion.v1, expectedCount: 12 }, { language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 15, projectTemplateKey: 'net6.0' }, { language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 14, backupExpectedCount: 13, projectTemplateKey: 'net6.0-isolated' }, { language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 14, backupExpectedCount: 13, projectTemplateKey: 'net7.0-isolated' }, { language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 14, backupExpectedCount: 13, projectTemplateKey: 'net8.0-isolated' }, { language: ProjectLanguage.Python, version: FuncVersion.v4, expectedCount: 15 }, - { language: ProjectLanguage.TypeScript, version: FuncVersion.v4, expectedCount: 18 }, + { language: ProjectLanguage.TypeScript, version: FuncVersion.v4, expectedCount: 18, backupExpectedCount: 18 }, { language: ProjectLanguage.PowerShell, version: FuncVersion.v4, expectedCount: 16 }, { language: ProjectLanguage.Ballerina, version: FuncVersion.v4, expectedCount: 5 } ];