Claude
Skills
Sign in
Back

dotnet-ai

Included with Lifetime
$97 forever

.NET AI integration with Microsoft.Extensions.AI, Semantic Kernel, MCP servers, embeddings, vector search, and agent frameworks

AI Agents

What this skill does


# .NET AI Integration

## Microsoft.Extensions.AI (Unified AI Abstraction)

The recommended way to integrate AI in .NET apps. Provides a vendor-agnostic abstraction over AI services.

```csharp
// Install: dotnet add package Microsoft.Extensions.AI
// Provider packages: Microsoft.Extensions.AI.OpenAI, Microsoft.Extensions.AI.AzureAIInference, etc.

using Microsoft.Extensions.AI;

// Register in DI
builder.Services.AddChatClient(new AzureOpenAIClient(
    new Uri(builder.Configuration["AI:Endpoint"]!),
    new DefaultAzureCredential())
    .GetChatClient("gpt-4o"));

// Or with OpenAI directly
builder.Services.AddChatClient(new OpenAIClient(apiKey)
    .GetChatClient("gpt-4o"));
```

### Chat Completion

```csharp
public sealed class ChatService(IChatClient chatClient)
{
    public async Task<string> AskAsync(string question, CancellationToken ct)
    {
        var response = await chatClient.GetResponseAsync(question, cancellationToken: ct);
        return response.Text;
    }

    public async Task<string> AskWithContextAsync(string question, string systemPrompt, CancellationToken ct)
    {
        var messages = new List<ChatMessage>
        {
            new(ChatRole.System, systemPrompt),
            new(ChatRole.User, question)
        };

        var response = await chatClient.GetResponseAsync(messages, cancellationToken: ct);
        return response.Text;
    }

    // Streaming
    public async IAsyncEnumerable<string> StreamAsync(
        string prompt, [EnumeratorCancellation] CancellationToken ct = default)
    {
        await foreach (var update in chatClient.GetStreamingResponseAsync(prompt, cancellationToken: ct))
        {
            if (update.Text is not null)
                yield return update.Text;
        }
    }
}
```

### Function Calling (Tool Use) - from official docs

```csharp
using Microsoft.Extensions.AI;
using OpenAI;

// Build client with function invocation middleware
IChatClient client =
    new ChatClientBuilder(new OpenAIClient(key).GetChatClient("gpt-4o").AsIChatClient())
    .UseFunctionInvocation()  // Auto-invokes local functions
    .Build();

// Define tools available to the model
var chatOptions = new ChatOptions
{
    Tools = [AIFunctionFactory.Create((string location, string unit) =>
    {
        return "Periods of rain or drizzle, 15 C";
    },
    "get_current_weather",
    "Gets the current weather in a given location")]
};

// Conversation with automatic tool invocation
List<ChatMessage> chatHistory =
[
    new(ChatRole.System, "You are a hiking enthusiast who helps discover fun hikes."),
    new(ChatRole.User, "I live in Montreal. What's the current weather like?")
];

ChatResponse response = await client.GetResponseAsync(chatHistory, chatOptions);
Console.WriteLine(response.Text);  // Model auto-called get_current_weather
```

### Embeddings

```csharp
// IEmbeddingGenerator<string, Embedding<float>>
builder.Services.AddEmbeddingGenerator(new AzureOpenAIClient(endpoint, credential)
    .GetEmbeddingClient("text-embedding-3-small"));

public sealed class SemanticSearchService(IEmbeddingGenerator<string, Embedding<float>> embedder)
{
    public async Task<float[]> GetEmbeddingAsync(string text, CancellationToken ct)
    {
        var embedding = await embedder.GenerateAsync(text, cancellationToken: ct);
        return embedding[0].Vector.ToArray();
    }

    public async Task<IReadOnlyList<float[]>> GetBatchEmbeddingsAsync(
        IEnumerable<string> texts, CancellationToken ct)
    {
        var embeddings = await embedder.GenerateAsync(texts.ToList(), cancellationToken: ct);
        return embeddings.Select(e => e.Vector.ToArray()).ToList();
    }
}
```

## Semantic Kernel (AI Orchestration)

```csharp
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

// Build kernel
var kernel = Kernel.CreateBuilder()
    .AddAzureOpenAIChatCompletion("gpt-4o", endpoint, credential)
    .Build();

// Simple prompt
var result = await kernel.InvokePromptAsync("Summarize: {{$input}}", new() { ["input"] = text });

// With plugins
kernel.Plugins.AddFromType<TimePlugin>();
kernel.Plugins.AddFromType<WeatherPlugin>();

// Auto function calling
var settings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var response = await chatService.GetChatMessageContentAsync("What time is it in London?", settings, kernel);
```

## MCP (Model Context Protocol) in .NET - from official docs

### Build MCP Server

```bash
# Requires .NET 10.0 SDK
dotnet new install Microsoft.McpServer.ProjectTemplates
dotnet new mcpserver -n MyMcpServer
```

```csharp
// Program.cs
using ModelContextProtocol.Server;
using System.ComponentModel;

var hostBuilder = Host.CreateDefaultBuilder(args)
    .ConfigureServices((context, services) =>
    {
        services.AddMcpServer(options =>
        {
            options.Name = "SampleMcpServer";
            options.Version = "1.0";
        })
        .WithStdioServerTransport()  // or .WithHttpServerTransport()
        .AddMcpServerTools();
    });

var host = hostBuilder.Build();
await host.RunAsync();
```

```csharp
// Tool definitions
public class RandomNumberTools
{
    [McpServerTool]
    [Description("Gets a random number between min and max")]
    public string GetRandomNumber(
        [Description("Minimum value")] int min,
        [Description("Maximum value")] int max)
    {
        return $"Your random number is {Random.Shared.Next(min, max + 1)}.";
    }

    [McpServerTool]
    [Description("Describes random weather in the provided city")]
    public string GetCityWeather(
        [Description("Name of the city")] string city)
    {
        var weather = Environment.GetEnvironmentVariable("WEATHER_CHOICES") ?? "balmy,rainy,stormy";
        var choices = weather.Split(",");
        return $"The weather in {city} is {choices[Random.Shared.Next(0, choices.Length)]}.";
    }
}
```

### MCP Server Config (.vscode/mcp.json)
```json
{
  "servers": {
    "MyMcpServer": {
      "type": "stdio",
      "command": "dotnet",
      "args": ["run", "--project", "<path-to-csproj>"],
      "env": { "WEATHER_CHOICES": "sunny,humid,freezing" }
    }
  }
}
```

### Build MCP Client
```csharp
using ModelContextProtocol.Client;
using Microsoft.Extensions.AI;

// Create MCP client connection
var transport = new StdioClientTransport(new()
{
    Command = "dotnet run",
    Arguments = ["--project", "<path-to-mcp-server>"],
    Name = "Minimal MCP Server",
});
McpClient mcpClient = await McpClient.CreateAsync(transport);

// Discover tools
IList<McpClientTool> tools = await mcpClient.ListToolsAsync();
foreach (McpClientTool tool in tools)
    Console.WriteLine(tool);

// Integrate MCP tools with chat client
IChatClient chatClient = new ChatClientBuilder(baseClient)
    .UseFunctionInvocation()
    .Build();

// Use MCP tools in chat
List<ChatMessage> messages = [new(ChatRole.User, "What's the weather in Paris?")];
await foreach (var update in chatClient.GetStreamingResponseAsync(
    messages, new() { Tools = [.. tools] }))
{
    Console.Write(update);
}
```

## Vector Search

```csharp
// Using Microsoft.Extensions.VectorData
using Microsoft.Extensions.VectorData;

public sealed class ProductSearchVector
{
    [VectorStoreRecordKey]
    public int Id { get; set; }

    [VectorStoreRecordData]
    public string Name { get; set; } = "";

    [VectorStoreRecordData]
    public string Description { get; set; } = "";

    [VectorStoreRecordVector(1536)] // OpenAI embedding dimension
    public ReadOnlyMemory<float> Embedding { get; set; }
}

// Search
public sealed class VectorSearchService(
    IVectorStore vectorStore,
    IEmbeddingGenerator<string, Embedding<float>> embedder)
{
    public async Task<IReadOnlyList<ProductSearchVector>> SearchAsync(
        string query, int topK = 5, CancellationToken ct = default)
    {

Related in AI Agents