DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Designing Agentic Systems Like Distributed Systems
  • 5 Ways Azure AI Search Enhances Enterprise RAG Architectures
  • The Technical Evolution of Video Production: AI Automation vs. Traditional Workflows
  • Building a State-Driven Workflow Engine for AI Applications

Trending

  • The ORM Is Over: AI-Written SQL Is the New Data Access Layer
  • The Agent Protocol Stack: MCP vs. A2A vs. AG-UI
  • From APIs to Actions: Rethinking Back-End Design for Agents
  • Smart Deployment Strategies for Modern Applications
  1. DZone
  2. Data Engineering
  3. AI/ML
  4. Supercharge AI Workflows on Azure: Remote MCP Tool Triggers + Your First TypeScript MCP Server

Supercharge AI Workflows on Azure: Remote MCP Tool Triggers + Your First TypeScript MCP Server

Remote MCP in Azure Functions exposes serverless tools for AI assistants, enabling scalable, cloud-native workflows with Azure services and bindings.

By 
Swapnil Nagar user avatar
Swapnil Nagar
·
Jan. 13, 26 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
2.0K Views

Join the DZone community and get the full member experience.

Join For Free

Introduction

The workflow for an agentic app begins when the user interacts with it, presenting a prompt via a chat interface or a form. The agent receives this prompt and analyzes it to determine the user's intent and requirements. It can use an LLM to acquire tasks, clarify details, and break the whole into subtasks.

As soon as the agent has a clear understanding of the target, it selects the most appropriate specialized tools or services to achieve the goal. These bring APIs, databases, generative AI (for writing, image generation, etc.), or other partnered systems, and the agent might arrange or put together multiple tool actions, dependent on the difficulty of the job.

The agent continually assesses and adjusts, repeating the tool calls and requesting further clarification if the output is insufficient or unclear. After achieving a tangible or high-quality outcome, the agent merges the outputs, formats the response, and returns it to the user for review. This adaptation process gives the user a relevant, sometimes even superior answer by fully utilizing the integrated tools and intelligent planning.



Why the Need for Standard Protocol?

The present architecture lacks the flexibility to implement all but tools, which means that the tool is solely part of the particular agent application. There is no universal method to publish this tool for use by other systems or applications.

The Model Context Protocol (MCP) is where the matter comes to application. MCP is a system created by Anthropic that not only makes it easy to plug tools into a single application but also lets many different applications connect to those tools through a shared, standard way of describing and exposing capabilities. MCP is modeled on a client-server architecture.

It is structured as follows: The server is the application that communicates its specific capabilities via the standard MCP interface. The clients are equivalent to other applications that utilize these facilities to create intelligent, deeply integrated experiences. An overview of the classical MCP architecture is given below.

A graphic overview of the classical MCP architecture.

An overview of the classical MCP architecture.



Microsoft Azure Functions Helps

The agent's lack of flexibility is addressed by the Microsoft offering, which includes the recently released Remote MCP feature in Azure Functions. It is a step ahead in developing intelligent AI workflows and tools to quickly and accurately connect and collaborate with cloud services. Through direct use of the MCPs in Azure Functions, developers can, for the first time, create robust, scalable AI tools that can harness the full power of the respected Azure platforms, while also running easily and cheaply due to serverless computing.

What is Remote MCP?

Remote MCP is a feature that allows Azure Functions to be configured as MCP servers, which expose custom tools that AI assistants like GitHub Copilot, Claude, or other MCP-compatible clients can find and use. 

The MCP allows connecting the AI logic to the cloud-native operations, thus making it possible for the AI agents to:

  • Read and write data from Azure Storage 
  • Query databases 
  • Process files and documents 
  • Integrate with third-party APIs 
  • Perform complex business logic in the cloud


Real-World Use Case: Smart Snippet Management

Let's explore a practical scenario where developers need an AI-powered code snippet management system that can:

  1. **Save and retrieve** reusable snippets
  2. **Organize snippets** by name and content
  3. **Analyze and summarize** multiple snippets

This system demonstrates Remote MCP using MCP Tool Triggers with Azure Functions input and output bindings in their simplest form.

Implementation

1. Snippet Storage and Retrieval

TypeScript
 
import { app, InvocationContext, input, output, arg } from "@azure/functions";

// Constants matching the C# ToolsInformation class
const GET_SNIPPET_TOOL_NAME = "getsnippets";
const GET_SNIPPET_TOOL_DESCRIPTION =
  "Gets code snippets from your snippet collection.";
const SAVE_SNIPPET_TOOL_NAME = "savesnippet";
const SAVE_SNIPPET_TOOL_DESCRIPTION =
  "Saves a code snippet into your snippet collection.";
const SNIPPET_NAME_PROPERTY_NAME = "snippetname";
const SNIPPET_PROPERTY_NAME = "snippet";
const SNIPPET_NAME_PROPERTY_DESCRIPTION = "The name of the snippet.";
const SNIPPET_PROPERTY_DESCRIPTION = "The code snippet.";

// Define blob input and output bindings
const blobInputBinding = input.storageBlob({
  connection: "AzureWebJobsStorage",
  path: `snippets/{mcptoolargs.${SNIPPET_NAME_PROPERTY_NAME}}.json`,
});

const blobOutputBinding = output.storageBlob({
  connection: "AzureWebJobsStorage",
  path: `snippets/{mcptoolargs.${SNIPPET_NAME_PROPERTY_NAME}}.json`,
});

// GetSnippet function - retrieves a snippet by name
export async function getSnippet(
  _toolArguments: unknown,
  context: InvocationContext
): Promise<string> {
  console.info("Getting snippet");

  // Get snippet name from the tool arguments
  const mcptoolargs = context.triggerMetadata.mcptoolargs as {
    snippetname?: string;
  };
  const snippetName = mcptoolargs?.snippetname;

  console.info(`Snippet name: ${snippetName}`);

  if (!snippetName) {
    return "No snippet name provided";
  }

  // Get the content from blob binding - properly retrieving from extraInputs
  const snippetContent = context.extraInputs.get(blobInputBinding);

  if (!snippetContent) {
    return `Snippet '${snippetName}' not found`;
  }

  console.info(`Retrieved snippet: ${snippetName}`);
  return snippetContent as string;
}

// SaveSnippet function - saves a snippet with a name
export async function saveSnippet(
  _toolArguments: unknown,
  context: InvocationContext
): Promise<string> {
  console.info("Saving snippet");

  // Get snippet name and content from the tool arguments
  const mcptoolargs = context.triggerMetadata.mcptoolargs as {
    snippetname?: string;
    snippet?: string;
  };

  const snippetName = mcptoolargs?.snippetname;
  const snippet = mcptoolargs?.snippet;

  if (!snippetName) {
    return "No snippet name provided";
  }

  if (!snippet) {
    return "No snippet content provided";
  }

  // Save the snippet to blob storage using the output binding
  context.extraOutputs.set(blobOutputBinding, snippet);

  console.info(`Saved snippet: ${snippetName}`);
  return snippet;
}

// Register the GetSnippet tool
app.mcpTool("getSnippet", {
  toolName: GET_SNIPPET_TOOL_NAME,
  description: GET_SNIPPET_TOOL_DESCRIPTION,
  toolProperties: {
    [SNIPPET_NAME_PROPERTY_NAME]: arg.string().describe(SNIPPET_NAME_PROPERTY_DESCRIPTION)
  },
  extraInputs: [blobInputBinding],
  handler: getSnippet,
});

// Register the SaveSnippet tool
app.mcpTool("saveSnippet", {
  toolName: SAVE_SNIPPET_TOOL_NAME,
  description: SAVE_SNIPPET_TOOL_DESCRIPTION,
  toolProperties: {
    [SNIPPET_NAME_PROPERTY_NAME]: arg.string().describe(SNIPPET_NAME_PROPERTY_DESCRIPTION),
    [SNIPPET_PROPERTY_NAME]: arg.string().describe(SNIPPET_PROPERTY_DESCRIPTION)
  },
  extraOutputs: [blobOutputBinding],
  handler: saveSnippet,
});


Screenshot of the MCP inspector.

Screenshot of the MCP inspector.



2. Smart Snippet Analysis

TypeScript
 
// Summarize multiple snippets at once
export async function summarizeSnippets(
  _toolArguments: unknown,
  context: InvocationContext
): Promise<string> {
  console.info("Summarizing snippets");

  try {
    // Get the storage connection string
    const connectionString = process.env.AzureWebJobsStorage;
    if (!connectionString) {
      return "Azure Storage connection string not configured";
    }

    // Create blob service client
    const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
    const containerClient = blobServiceClient.getContainerClient("snippets");

    if (!(await containerClient.exists())) {
      return "No snippets container found";
    }

    let summary = `**Snippets Summary**\n\n`;
    let totalWords = 0;
    let totalChars = 0;

    // Read and display all snippets
    for await (const blob of containerClient.listBlobsFlat()) {
      const blobClient = containerClient.getBlobClient(blob.name);
      const response = await blobClient.download();

      if (response.readableStreamBody) {
        const chunks = [];
        for await (const chunk of response.readableStreamBody) {
          chunks.push(chunk);
        }
        const content = Buffer.concat(chunks).toString();
        const words = content.trim().split(/\s+/).length;
        const chars = content.length;

        totalWords += words;
        totalChars += chars;

        const fileName = blob.name.replace('.json', '');
        summary += `**${fileName}** (${words} words, ${chars} chars)\n`;
        summary += `\`\`\`\n${content}\n\`\`\`\n\n`;
      }
    }

    summary = `**Snippets Summary** (${totalWords} total words, ${totalChars} total chars)\n\n` + summary;
    return summary;

  } catch (error) {
    console.error("Error in summarizeSnippets:", error);
    return `Error generating summary: ${error instanceof Error ? error.message : 'Unknown error'}`;
  }
}

// Register the SummarizeSnippets tool
app.mcpTool("summarizeSnippets", {
  toolName: "summarize_snippets",
  description: "Analyze and summarize all code snippets in storage with statistics and insights",
  toolProperties: {
    // No parameters needed - analyzes all snippets in storage
  },
  handler: summarizeSnippets,
});



Screenshot of the MCP inspector.


3. Integration with AI Assistants

Once deployed, AI assistants can discover and use these tools:

GitHub Copilot Chat Example:

User: "Store a new document about TypeScript best practices"

AI: I'll help you store that document. Let me use the document management system.

Screenshot shows use of store_document tool with appropriate parameters.

Uses store_document tool with appropriate parameters


User: "Find all documents related to Azure"

AI: I'll search for documents with Azure-related content.

Screenshot shows use of summarize_snippets tool to retrieve all the saved documents.

Uses summarize_snippets tool to retrieve all the saved documents


Why use Azure Serverless Platform?

Serverless Scalability: Azure Functions automatically scales based on demand, handling everything from single-document requests to thousands of concurrent operations.

Rich Integration Ecosystem: With built-in bindings, you can easily integrate with:

  • Azure Storage (Blobs, Tables, Queues)
  • Azure SQL Database
  • Cosmos DB
  • Service Bus
  • Event Hubs
  • And many more…

Cost-Effective: Pay only for execution time with the consumption plan, making it perfect for AI assistant scenarios with sporadic usage patterns.

Enterprise Security: Built-in authentication, network isolation, and managed identity support ensure your AI tools are secure by default.

Getting Started

1. Clone the sample repository:

TypeScript
 
git clone https://github.com/Azure-Samples/remote-mcp-functions-typescript

git clone https://github.com/Azure-Samples/remote-mcp-functions-python

git clone https://github.com/Azure-Samples/remote-mcp-functions-java

git clone https://github.com/Azure-Samples/remote-mcp-functions-dotnet

cd remote-mcp-functions-typescript


2. Install dependencies:

TypeScript
 
npm install


3. Start local development:

TypeScript
 
func start


4. Deploy to Azure:

TypeScript
 
azd up


Conclusion

The Remote MCP, aka MCP Tool Trigger, feature in Azure Functions is an amazing opportunity to build cloud-native AI assistants/Workflows. Serverless, along with Azure's extensive ecosystem, seamlessly integrates to help developers create powerful, scalable, and economical AI tools.

 MCP Tool Triggers are also a shortcut to AI decision-making in the workflow of document management systems, data processing pipelines, or custom business logic. The functional integration with the Azure Functions binding system lets you connect to virtually any service or data source, thereby enhancing the capabilities and usefulness of your AI assistants.

Be the first to get your hands on fingerprint file triggers and explore how the truly autonomous cloud can transform your apps!


Resources

Azure Functions Documentation

Model Context Protocol Specification

Sample Repository TypeScript

Sample Repository Python

Sample Repository DotNet

Sample Repository Java

Azure Functions TypeScript Guide

AI TypeScript azure remote workflow

Opinions expressed by DZone contributors are their own.

Related

  • Designing Agentic Systems Like Distributed Systems
  • 5 Ways Azure AI Search Enhances Enterprise RAG Architectures
  • The Technical Evolution of Video Production: AI Automation vs. Traditional Workflows
  • Building a State-Driven Workflow Engine for AI Applications

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook