Monday, April 20, 2026

Microsoft Agent Framework Connections Repo!!

 

Connecting to most available LLM Providers

This post summarizes the video "How we connect different model providers".
It provides the necessary NuGet packages, setup steps, and C# code for integrating various LLMs into the Microsoft Agent Framework.

Core Architecture

The framework is designed around the IChatClient interface (from Microsoft.Extensions.AI). Any provider that can be wrapped in this interface can power a Microsoft Agent.



1. OpenAI

var client = new OpenAIClient("YOUR_API_KEY");
IChatClient chatClient = client.AsChatClient("gpt-4o");
var agent = new ChatClientAgent(chatClient);
await agent.RunAsync("Hello!");

2. Google Gemini

var chatClient = new GoogleAiChatClient(apiKey: "YOUR_KEY", modelId: "gemini-1.5-pro");
var agent = new ChatClientAgent(chatClient);

3. Anthropic

  • Source: console.anthropic.com

  • NuGet: Community Anthropic SDK + Microsoft.Extensions.AI.

  • Note: MaxTokens is mandatory in ChatOptions.

var client = new AnthropicClient("YOUR_KEY");
var chatClient = client.AsChatClient();
var agent = new ChatClientAgent(chatClient, new ChatOptions { 
    ModelId = "claude-3-5-sonnet", 
    MaxTokens = 1000 
});

4. Mistral

var client = new MistralClient("YOUR_KEY");
var chatClient = client.AsChatClient();
var agent = new ChatClientAgent(chatClient, new ChatOptions { ModelId = "mistral-large-latest" });

5. XAI (Grok)

  • Source: x.ai

  • NuGet: Microsoft.Agents.AI.OpenAI (OpenAI compatible).

var options = new OpenAIClientOptions { Endpoint = new Uri("[https://api.x.ai/v1](https://api.x.ai/v1)") };
var client = new OpenAIClient("YOUR_KEY", options);
IChatClient chatClient = client.AsChatClient("grok-beta");

6. Azure OpenAI

  • Source: ai.azure.com

  • NuGet: Azure.AI.OpenAI

  • Note: Requires a "Deployment Name" instead of just a model ID.

var client = new AzureOpenAIClient(new Uri("YOUR_ENDPOINT"), new AzureKeyCredential("YOUR_KEY"));
IChatClient chatClient = client.AsChatClient("YOUR_DEPLOYMENT_NAME");

7. Microsoft Foundry (Cloud)

  • Source: Azure AI Foundry.

  • NuGet: Microsoft.Agents.AI.Azure.AI

  • Note: Uses Azure Credentials (CLI/Managed Identity) instead of API keys.

var projectClient = new AIProjectClient("YOUR_CONNECTION_STRING", new DefaultAzureCredential());
var agent = await projectClient.GetAgentAsync("AGENT_ID");
// Turn Foundry Agent into Framework Agent
var frameworkAgent = agent.AsAgent();

8. Amazon Bedrock

// Set AWS_BEARER_TOKEN_BEDROCK environment variable
var runtime = new AmazonBedrockRuntimeClient();
IChatClient chatClient = runtime.AsChatClient("anthropic.claude-3-sonnet");

9. Ollama (Local)

  • Source: Local installation of Ollama.

  • NuGet: OllamaSharp

var uri = new Uri("http://localhost:11434");
var client = new OllamaApiClient(uri);
IChatClient chatClient = client.AsChatClient("llama3");

10. Microsoft Foundry Local

  • Source: WinGet install Microsoft Foundry Local.

  • NuGet: Microsoft.AI.FoundryLocal

  • Note: Runs models locally using system NPU/GPU/CPU.

var model = await FoundryLocal.StartModelAsync("phi3");
var client = new OpenAIClient(new OpenAIClientOptions { Endpoint = model.Endpoint });
IChatClient chatClient = client.AsChatClient(model.ModelId);

11-14. Multi-Model Portals (OpenRouter, Together.ai, Cohere, HuggingFace)

These providers use the OpenAI-compatible standard. Use Microsoft.Agents.AI.OpenAI and change the endpoint.

Provider

Endpoint

OpenRouter

https://openrouter.ai/api/v1

Together.ai

https://api.together.xyz/v1

Cohere

https://api.cohere.ai/compatibility/v1

HuggingFace

https://router.huggingface.co/v1

Generic Code Pattern:

var options = new OpenAIClientOptions { Endpoint = new Uri("PROVIDER_ENDPOINT") };
var client = new OpenAIClient("YOUR_API_KEY", options);
IChatClient chatClient = client.AsChatClient("MODEL_NAME");

15. GitHub Models

  • Source: GitHub Personal Access Token (PAT) with model access.

  • NuGet: Azure.AI.Inference + Microsoft.Extensions.AI.

var client = new ChatCompletionsClient(new Uri("[https://models.inference.ai.azure.com]
(https://models.inference.ai.azure.com)"), new AzureKeyCredential("GITHUB_PAT")); IChatClient chatClient = client.AsChatClient(); var agent = new ChatClientAgent(chatClient, new ChatOptions { ModelId = "gpt-4o" });

Key Takeaway: The "magic" is the IChatClient abstraction. Once you have an IChatClient, you can pass it to any Agent in the framework, regardless of the underlying LLM provider.

Saturday, April 18, 2026

REST over HTTP, gRPC with Protocol Buffers, and Event-Driven Messaging.

Choosing the Right Communication Layer in Modern Architectures

At the heart of every distributed system lies a foundational choice that governs how data flows between its parts. This communication layer acts as the application's nervous system; it establishes your baseline latency, dictates the level of autonomy your teams enjoy during deployment, determines the resilience of your services against cascading failures, and ultimately defines the long-term maintenance cost of every interface contract.

In modern systems, three patterns dominate: REST over HTTP, gRPC with Protocol Buffers, and Event-Driven Messaging. While most production environments use a hybrid of all three, the real skill lies in knowing which pattern fits which interaction.

The Three Patterns at a Glance

Pattern

Communication

Protocol

Serialization

Best For

REST

Synchronous

HTTP/1.x

JSON (Text)

Public APIs, CRUD

gRPC

Sync + Stream

HTTP/2

Protobuf (Binary)

Internal High-Throughput

Messaging

Asynchronous

Broker-based

Flexible

Workflows, Decoupling

1. REST: The Universal Standard

REST remains the default choice for external-facing services. It is resource-oriented, stateless, and benefits from the massive ecosystem of the web.

Why REST Excels

  • Ubiquity: Every language, framework, and proxy supports HTTP/JSON.

  • Human-Readable: Debugging with curl or browser tools is trivial.

  • Caching: Leveraging Cache-Control and ETags allows for efficient data delivery at the edge.

Implementation: Inventory Fetch & Caching

// Order service calling the Inventory service via REST
async function checkInventory(productId: string): Promise<InventoryStatus> {
  const response = await fetch(`/api/v1/products/${productId}/stock`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${getServiceToken()}`,
    },
  });

  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
}

// Example of built-in caching semantics in Express
app.get("/api/v1/products/:id", async (req, res) => {
  const product = await getProduct(req.params.id);
  res.set("Cache-Control", "public, max-age=60");
  res.set("ETag", computeETag(product));
  res.json(product);
});

2. gRPC: The Performance Engine

gRPC is a high-performance RPC framework that uses HTTP/2 and Protocol Buffers. It moves away from "endpoints" toward "methods," providing a strictly-typed contract between services.

Why gRPC Excels

  • Performance: Binary serialization is significantly faster and more compact than JSON.

  • Strict Contracts: Code is generated from .proto files, catching breaking changes at compile time.

  • Advanced Streams: Supports server-side, client-side, and bi-directional streaming natively.

Implementation: Defining & Using gRPC

// inventory.proto
syntax = "proto3";
package inventory;

service InventoryService {
  rpc CheckStock(StockRequest) returns (StockResponse);
  rpc WatchStockLevels(WatchRequest) returns (stream StockUpdate);
}

message StockRequest {
  string product_id = 1;
  string warehouse_id = 2;
}
// Client-side usage with generated code
async function checkStock(productId: string): Promise<StockResponse> {
  return new Promise((resolve, reject) => {
    client.checkStock({ productId, warehouseId: "eu-1" }, (err, res) => {
      if (err) reject(err);
      else resolve(res);
    });
  });
}

3. Event-Driven Messaging: The Decoupling Choice

This pattern flips the model: instead of calling a service, a service publishes an Event. This creates a system that is temporally decoupled—the producer doesn't care if the consumer is online or busy.

Why Messaging Excels

  • Resilience: Brokers (Kafka/RabbitMQ) act as a buffer, preventing cascading failures.

  • Scalability: Perfect for "fan-out" where one action triggers many reactions (e.g., an order triggers payment, shipping, and analytics).

  • Reliability: Using the Transactional Outbox Pattern ensures that database updates and event publishing happen atomically.

Implementation: Kafka Producer & Outbox Pattern

// Ensuring reliability via the Outbox Pattern
async function confirmOrder(order: Order, db: Database) {
  await db.transaction(async (tx) => {
    // 1. Update the local state
    await tx.update("orders", { id: order.id, status: "confirmed" });
    // 2. Insert into outbox table (to be picked up by a relay)
    await tx.insert("outbox", {
      id: crypto.randomUUID(),
      topic: "order.confirmed",
      payload: JSON.stringify(order),
    });
  });
}

The Five Trade-off Dimensions

Dimension

REST

gRPC

Messaging

Latency

Moderate (JSON/Text)

Lowest (Binary)

High (Broker overhead)

Coupling

Request-time sync

Request-time sync

Decoupled (Async)

Schema

Flexible/Fragile

Strict (Protobuf)

Registry-enforced

Observability

Highest (Human-readable)

Moderate

Complex (Trace IDs)

Ops Complexity

Low

Moderate

High (Broker management)

Decision Framework

1. Does the caller need an immediate response?

  • Yes: Is it for the browser/public? Use REST.

  • Yes: Is it internal and latency-sensitive? Use gRPC.

  • No: Use Event-Driven Messaging.

2. Does one action trigger multiple downstream reactions?

  • Use Messaging to avoid "Distributed Monolith" coupling where Service A calls B, C, and D synchronously.

3. Are you building for performance?

  • If you have "chatty" services (many small calls), gRPC’s multiplexing and binary format will save significant CPU and bandwidth.

Summary: The Hybrid Architecture

Most production systems embrace all three:

  1. REST at the Edge: Browsers and Mobile apps talk to a Gateway via REST.

  2. gRPC Internally: The Gateway talks to core microservices via gRPC for speed.

  3. Messaging for Side Effects: Core services emit events to Kafka for analytics, emails, and auditing.

Selecting a communication pattern isn't about finding the "best" technology—it's about choosing the right trade-offs for each specific interaction in your system.

Sunday, April 12, 2026

Unleashing AI in DevOps: The Power of MCP Servers

 In the world of DevOps, speed and context are everything. We’ve spent years building complex pipelines, but the "last mile" having an AI that can actually do the work across these platforms has always been a hurdle.

Enter the Model Context Protocol (MCP).

By using MCP, we can give AI models a standardized way to read, write, and execute actions across our entire tech stack. Here is how MCP servers are revolutionizing the DevOps lifecycle.

1. Code & Pipeline Management

  • GitHub/GitLab: Instead of just summarizing code, an MCP-enabled AI can sync repositories, manage pull requests, and trigger builds directly. It becomes a tireless "Virtual Maintainer."

  • Jenkins: AI can now monitor build logs in real-time, diagnose a failed CI/CD job, and suggest (or apply) the fix to the pipeline configuration.

2. Infrastructure as Code (IaC) & Cloud

  • Terraform: Imagine telling an AI, "Optimize our staging environment," and having it generate, apply, and track the infrastructure changes through an MCP server.

  • AWS/Azure/GCP: MCP provides a unified interface. You no longer need to switch tabs between cloud consoles; your AI agent can provision resources and manage credentials across multi-cloud environments seamlessly.

3. Orchestration & Security

  • Kubernetes & Docker: MCP allows AI to monitor container health and scale node clusters dynamically based on natural language commands.

  • HashiCorp Vault: Security is paramount. MCP servers ensure that AI interactions with secrets and sensitive credentials follow strict, pre-defined access policies.

4. Observability & Communication

  • Prometheus & Grafana: Shift from "looking at dashboards" to "asking questions." MCP lets AI query real-time metrics and explain why a spike is happening.

  • Slack: The feedback loop closes here. AI can send intelligent, summarized notifications to your team, moving beyond simple bot spam to meaningful project updates.


🛠 The flow of DevOps.

CategoryTools IncludedKey MCP Capability
Source & CI/CDGitHub, GitLab, JenkinsAutomate PR reviews and fix broken pipelines.
Cloud & IaCAWS, Azure, GCP, TerraformProvision resources and manage multi-cloud assets.
ContainersDocker, KubernetesOrchestrate images and auto-scale clusters.
MonitoringPrometheus, GrafanaQuery real-time metrics via natural language.
Security & OpsHashiCorp Vault, SlackSecure credential management and smart alerting.

🧠 MCP Concept Overview

MCP acts as a universal bridge between AI models and DevOps tools. It standardizes how models read, write, and execute actions across systems — turning passive assistants into active operators.

⚙️ Architecture Flow (Textual Explanation)

1. AI Layer (Top)

  • LLM / AI Agent

    • Issues natural language commands: “Deploy staging,” “Fix Jenkins build,” “Query Grafana for CPU spikes.”

    • Communicates via MCP protocol (JSON-RPC or WebSocket).

2. MCP Server Layer (Middle)

  • MCP Core Gateway

    • Translates AI intent into structured API calls.

    • Manages authentication, context, and permissions.

    • Routes requests to the correct tool connector.

  • MCP Connectors

    • Each connector interfaces with a DevOps tool:

      • GitHub/GitLab/Jenkins → CI/CD automation

      • Terraform/AWS/Azure/GCP → IaC and cloud provisioning

      • Kubernetes/Docker → container orchestration

      • Prometheus/Grafana → observability and metrics

      • Vault/Slack → security and communication

3. Tool Layer (Bottom)

  • Each tool executes the command received from MCP:

    • Jenkins triggers builds.

    • Terraform applies infrastructure changes.

    • Kubernetes scales pods.

    • Prometheus collects metrics.

    • Grafana visualizes results.

    • Slack sends intelligent alerts.

4. Feedback Loop

  • Tools send telemetry and logs back to MCP.

  • MCP normalizes data and feeds it to the AI model.

  • AI interprets results and provides human-readable insights or next actions.

🧩 Data Flow Summary

StageComponentActionExample
1AI AgentIssues command“Optimize staging environment”
2MCP ServerTranslates & routesConverts to Terraform API call
3ToolExecutesTerraform applies changes
4MCP ServerCollects resultsReceives success/failure logs
5AI AgentReports outcome“Staging optimized successfully”

🖼️ Diagram Description

Imagine a layered flowchart:

  • Top Layer (AI) → “LLM / AI Agent” box ↓

  • Middle Layer (MCP Server) → central hub with connectors branching out ↓

  • Bottom Layer (DevOps Tools) → grouped by function:

    • Source & CI/CD: GitHub, GitLab, Jenkins

    • Cloud & IaC: AWS, Azure, GCP, Terraform

    • Containers: Docker, Kubernetes

    • Monitoring: Prometheus, Grafana

    • Security & Ops: Vault, Slack

Arrows show:

  • Yellow: AI → MCP → Tools (command flow)

  • Blue: Tools → MCP → AI (feedback flow)

  • Green: MCP ↔ AI (context synchronization)


This layout makes it clear how MCP turns AI into an active operator across your stack.