Skip to content

Commit 17f492a

Browse files
Add MCP Resource trigger templates for JavaScript and TypeScript (#4966)
* Adding the Mcp Resource Templates * Adding the template for VSCode
1 parent c86a856 commit 17f492a

File tree

5 files changed

+53
-9
lines changed

5 files changed

+53
-9
lines changed

resources/backupTemplates/nodejs-4.x/templates/templates.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,5 +656,47 @@
656656
"enabledInTryMode": true,
657657
"userPrompt": []
658658
}
659+
},
660+
{
661+
"id": "McpResourceTrigger-JavaScript-4.x",
662+
"runtime": "2",
663+
"files": {
664+
"%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});"
665+
},
666+
"metadata": {
667+
"defaultFunctionName": "mcpResourceTrigger",
668+
"description": "$McpResourceTrigger_description",
669+
"name": "MCP Resource Trigger",
670+
"language": "JavaScript",
671+
"triggerType": "mcpResourceTrigger",
672+
"category": [
673+
"$temp_category_core",
674+
"$temp_category_dataProcessing"
675+
],
676+
"categoryStyle": "other",
677+
"enabledInTryMode": false,
678+
"userPrompt": []
679+
}
680+
},
681+
{
682+
"id": "McpResourceTrigger-TypeScript-4.x",
683+
"runtime": "2",
684+
"files": {
685+
"%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<string> {\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});"
686+
},
687+
"metadata": {
688+
"defaultFunctionName": "mcpResourceTrigger",
689+
"description": "$McpResourceTrigger_description",
690+
"name": "MCP Resource Trigger",
691+
"language": "TypeScript",
692+
"triggerType": "mcpResourceTrigger",
693+
"category": [
694+
"$temp_category_core",
695+
"$temp_category_dataProcessing"
696+
],
697+
"categoryStyle": "other",
698+
"enabledInTryMode": false,
699+
"userPrompt": []
700+
}
659701
}
660702
]

src/funcConfig/function.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ export class ParsedFunctionJson {
3939

4040
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4141
public constructor(data: any) {
42-
42+
4343
if (typeof data === 'object' && data !== null && (data.triggerType !== undefined)) {
4444
this.template = <IFunctionTemplate>data;
4545
this.data = {};
4646
}
47-
47+
4848
else if (typeof data === 'object' && data !== null && (data.bindings === undefined || data.bindings instanceof Array)) {
4949
this.data = <IFunctionJson>data;
50-
50+
5151
} else {
5252
this.data = {};
5353
}
@@ -85,10 +85,10 @@ export class ParsedFunctionJson {
8585

8686
public get isMcpTrigger(): boolean {
8787
if (this.template?.triggerType) {
88-
return /^mcptooltrigger/i.test(this.template.triggerType) || /^mcptrigger/i.test(this.template.triggerType);
88+
return /^mcptooltrigger/i.test(this.template.triggerType) || /^mcptrigger/i.test(this.template.triggerType) || /^mcpresourcetrigger/i.test(this.template.triggerType);
8989
}
9090
if (this.triggerBinding && this.triggerBinding.type) {
91-
return /^mcptooltrigger/i.test(this.triggerBinding.type) || /^mcptrigger/i.test(this.triggerBinding.type);
91+
return /^mcptooltrigger/i.test(this.triggerBinding.type) || /^mcptrigger/i.test(this.triggerBinding.type) || /^mcpresourcetrigger/i.test(this.triggerBinding.type);
9292
}
9393

9494
return false;

src/templates/script/getScriptVerifiedTemplateIds.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export function getScriptVerifiedTemplateIds(version: string): (string | RegExp)
3939
'EventGridBlobTrigger',
4040
'SqlTrigger',
4141
'McpToolTrigger',
42+
'McpResourceTrigger',
4243
'MCPTrigger'
4344
]);
4445

src/templates/script/parseScriptTemplatesV2.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ export function parseScriptTemplates(rawTemplates: RawTemplateV2[], rawBindings:
121121
}
122122
const isHttpTrigger = !!templateV2.id?.toLowerCase().includes('httptrigger-');
123123
const isTimerTrigger = !!templateV2.id?.toLowerCase().includes('timertrigger-');
124-
// python and node.js use 2 different IDs for Mcp Triggers... because of course they do
124+
// MCP trigger variants use multiple IDs across templates/providers.
125125
const isMcpTrigger = !!templateV2.id?.toLowerCase().includes('mcptooltrigger') ||
126-
templateV2.id?.toLowerCase().includes('mcptrigger');
126+
templateV2.id?.toLowerCase().includes('mcptrigger') ||
127+
templateV2.id?.toLowerCase().includes('mcpresourcetrigger');
127128

128129
templates.push(Object.assign(templateV2, {
129130
wizards: parsedJobs,

test/templateCount.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ function addSuite(source: TemplateSource | undefined): void {
3030
suite(`Template Count - ${source === undefined ? 'defaultOnExtensionActivation' : source}`, () => {
3131
const cases: TestCase[] = [
3232
{ language: ProjectLanguage.JavaScript, version: FuncVersion.v1, expectedCount: 8 },
33-
{ language: ProjectLanguage.JavaScript, version: FuncVersion.v4, expectedCount: 18 },
33+
{ language: ProjectLanguage.JavaScript, version: FuncVersion.v4, expectedCount: 18, backupExpectedCount: 18 },
3434
{ language: ProjectLanguage.CSharp, version: FuncVersion.v1, expectedCount: 12 },
3535
{ language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 15, projectTemplateKey: 'net6.0' },
3636
{ language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 14, backupExpectedCount: 13, projectTemplateKey: 'net6.0-isolated' },
3737
{ language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 14, backupExpectedCount: 13, projectTemplateKey: 'net7.0-isolated' },
3838
{ language: ProjectLanguage.CSharp, version: FuncVersion.v4, expectedCount: 14, backupExpectedCount: 13, projectTemplateKey: 'net8.0-isolated' },
3939
{ language: ProjectLanguage.Python, version: FuncVersion.v4, expectedCount: 15 },
40-
{ language: ProjectLanguage.TypeScript, version: FuncVersion.v4, expectedCount: 18 },
40+
{ language: ProjectLanguage.TypeScript, version: FuncVersion.v4, expectedCount: 18, backupExpectedCount: 18 },
4141
{ language: ProjectLanguage.PowerShell, version: FuncVersion.v4, expectedCount: 16 },
4242
{ language: ProjectLanguage.Ballerina, version: FuncVersion.v4, expectedCount: 5 }
4343
];

0 commit comments

Comments
 (0)