Chapter 01 · Getting Started

Get Running in 10 Minutes

By the end of this page, the harness will be running on your machine and an agent will have answered a question you typed. We'll cover the prerequisites, the credentials it needs, the build, and the specific errors you'll probably hit on a fresh clone — with the exact fixes for each one.

Before you start

You need four things on your machine. If you already have them, skim and skip ahead. If you don't, get them now — none of them take more than a few minutes to install.

1 · .NET 10 SDK

This whole project is built on .NET 10. The SDK is what compiles the code; the runtime alone won't work for development. Download the SDK from dotnet.microsoft.com/download/dotnet/10.0.

SDK vs. Runtime

A runtime can run compiled .NET apps but can't build them. The SDK includes the runtime plus the compiler, the dotnet CLI, and the build tooling. Developers always want the SDK.

Verify the install worked:

bash
dotnet --version
# Expected output: 10.0.x (or higher)

2 · Git

If you're reading this, you probably already have it. If not, install from git-scm.com. Any version from the last few years is fine.

3 · An AI provider account

The agent calls a real Large Language Model. The harness ships pointed at Azure OpenAI — the shipped appsettings.json sets ClientType: "AzureOpenAI" with the gpt-4o deployment — but the same code path works for plain OpenAI, Anthropic via Azure AI Foundry, or any OpenAI-compatible gateway (OpenRouter, LiteLLM, a local proxy) driven through the OpenAI client type. Pick whichever fits your situation:

  • Azure OpenAI (the shipped default) — an Azure subscription with the OpenAI service provisioned and a deployment created (most enterprise users land here in production). You'll need the endpoint URL and an API key, or a managed identity if you're running on Azure compute. The default deployment name is gpt-4o.
  • OpenAI — an API key from platform.openai.com. Direct, no Azure layer.
  • OpenAI-compatible gateway (e.g. OpenRouter) — there is no dedicated OpenRouter client type; you reach it through the OpenAI client type by setting Endpoint to the gateway's base URL and supplying its API key. One key from openrouter.ai/keys then fronts Anthropic, OpenAI, Google, Mistral, and more — handy if you don't have an Azure subscription.
  • Anthropic — the Anthropic client type routes Claude calls through the native Anthropic Messages API under an Azure AI Foundry resource endpoint. Use this if your enterprise standardizes on Claude models via Foundry.
i
One switch, many providers

The AI:AgentFramework:ClientType setting picks the SDK path. The AIAgentFrameworkClientType enum has seven values: AzureOpenAI, OpenAI, AzureAIInference, PersistentAgents, Anthropic, Echo (a deterministic test client), and FoundryResponses. Then Endpoint, DefaultDeployment, and ApiKey point it at the chosen provider. Switching providers is a config change, not a code change. See Architecture · Compute & AI for the full provider matrix.

i
Embeddings are configured separately

Embeddings have their own AI:Embedding:* settings, independent of your chat provider. Azure OpenAI and OpenAI both expose embedding endpoints; some gateways (OpenRouter, for example) do not. If you need RAG or the knowledge graph, point AI:Embedding:* at an OpenAI or Azure OpenAI embedding deployment. For the 10-minute getting-started path you can skip this — the agent itself works without embeddings.

4 · An IDE (optional but recommended)

You can do everything from the command line, but real life is easier with an IDE. Any of these work well:

  • JetBrains Rider — best-in-class .NET experience.
  • Visual Studio 2022/2025 — Windows only, free Community edition is fine.
  • VS Code + C# Dev Kit — cross-platform, lightweight. The Dev Kit extension is what makes it usable for .NET.

The 10-minute path

These six steps will get you from zero to a running agent. Each step links to a "what if it fails" section further down the page.

  1. Step 1 · ~30 seconds
    Clone the repo

    Pick a folder you're happy to keep code in (avoid OneDrive or Dropbox paths if you can — they sometimes lock files mid-build).

    bash
    git clone https://github.com/MCKRUZ/microsoft-agentic-harness.git
    cd microsoft-agentic-harness

    If your team has a fork, clone that instead. The folder structure and commands are the same.

  2. Step 2 · ~2 minutes
    Configure your secrets

    The agent needs your AI provider credentials, but those credentials should never be committed to source control. .NET solves this with a feature called User Secrets — encrypted-at-rest values stored in your user profile, scoped per project. The harness ships with a wizard that sets them up for you.

    .NET User Secrets

    A built-in development-only secrets store. Run dotnet user-secrets set "Key" "Value" --project <path> and the value is stored in %APPDATA%\Microsoft\UserSecrets\ (Windows) or ~/.microsoft/usersecrets/ (macOS/Linux), keyed by a unique GUID in the .csproj. Never use this in production — it's plaintext-on-disk under your user account. For production, use Azure Key Vault.

    Run the setup wizard:

    cmd (Windows)
    setup-secrets.bat

    or, if you prefer to do it yourself or you're not on Windows:

    bash
    cd src/Content/Presentation/Presentation.ConsoleUI
    
    # For Azure OpenAI
    dotnet user-secrets set "AppConfig:AI:AgentFramework:ClientType" "AzureOpenAI"
    dotnet user-secrets set "AppConfig:AI:AgentFramework:Endpoint" "https://your-resource.openai.azure.com/"
    dotnet user-secrets set "AppConfig:AI:AgentFramework:ApiKey" "your-key-here"
    dotnet user-secrets set "AppConfig:AI:AgentFramework:DefaultDeployment" "gpt-4o"
    
    # Or for plain OpenAI
    dotnet user-secrets set "AppConfig:AI:AgentFramework:ClientType" "OpenAI"
    dotnet user-secrets set "AppConfig:AI:AgentFramework:ApiKey" "sk-..."
    dotnet user-secrets set "AppConfig:AI:AgentFramework:DefaultDeployment" "gpt-4o"
    
    cd ../../../..
    Inspecting what you set

    At any time, run dotnet user-secrets list --project src/Content/Presentation/Presentation.ConsoleUI to see every secret currently set for the console project. Use this to debug "the wrong endpoint is being used" issues.

  3. Step 3 · ~3 minutes (first time)
    Build the solution

    The first build will restore NuGet packages (.NET's package manager — like npm or pip but for .NET). This is the slowest step on a fresh clone; subsequent builds are incremental and take seconds.

    bash
    dotnet build src/AgenticHarness.slnx

    You're looking for the line at the bottom that says Build succeeded:

    output
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:42.18

    If you see warnings, that's fine for now. Errors mean we need to talk — see Troubleshooting below.

    .slnx vs .sln

    .slnx is the new XML-based solution format introduced in recent Visual Studio / .NET SDK versions. It does the same job as the old .sln file (groups projects together) but is easier to read and diff. The dotnet CLI handles both transparently.

  4. Step 4 · ~1 minute (optional)
    Run the tests

    Not strictly required to run the agent, but it's a great smoke test that confirms everything compiled and wired up correctly.

    bash
    dotnet test src/AgenticHarness.slnx

    You'll see hundreds of tests run across the test projects. A green Passed at the bottom means the codebase is healthy on your machine. A few skipped tests (typically integration tests requiring external services) are expected and normal.

  5. Step 5 · ~10 seconds
    Run the console UI

    Now the fun part. The ConsoleUI is one of several presentation layers that can host an agent (others include a SignalR hub and an MCP server). For learning the codebase, the console is the easiest entry point because everything happens in front of you on the terminal.

    bash
    dotnet run --project src/Content/Presentation/Presentation.ConsoleUI

    You should see an interactive menu. It's a Spectre.Console SelectionPrompt, not a numbered list: the examples are grouped under category headings, and you move between them with the arrow keys and press Enter to run the highlighted one (there's nothing to type). The highlighted row is drawn in colour:

    terminal
    ┌────────────────────────────────────────────┐
    │              Agentic Harness                 │
    └────────────────────────────────────────────┘
    
    What would you like to do?
    
      Agents
      > Research Agent (Standalone)      ◀ use ↑/↓ to move, Enter to select
        Orchestrator Agent (Multi-Agent)
        Magentic Orchestration (Multi-Agent)
        Persistent Agent (AI Foundry)
        A2A Agent-to-Agent
        A2A SRE-to-Workspace
      RAG & Retrieval
        RAG Pipeline Demo
        Multi-Source Retrieval
      Knowledge Graph
        Knowledge Graph Memory
        Knowledge Graph Compliance
      Governance & Safety
        Response Sanitization
        Escalation & Approvals
        Pipeline Behaviors
      Skills & Tools
        Skills Discovery & Budget
        Tool Converter Demo
        MCP Tools Discovery
        Sandbox Capabilities
      Observability
        Drift Detection
        Learnings Log
        Budget & Health Tracking
      Optimization
        Meta-Harness Optimizer
        Skill Training (SkillOpt)
      Setup
        Setup User Secrets
        Show Configuration
      Exit

    The category headings (Agents, RAG & Retrieval, and so on) are AddChoiceGroup labels — they're not selectable; the cursor skips over them to the runnable items underneath.

  6. Step 6 · ~30 seconds
    Talk to an agent

    Arrow down to Research Agent (Standalone) under the Agents group and press Enter. It's the simplest single-agent example, and a great first interaction to demystify what's happening under the hood.

    When prompted, type something like:

    prompt
    What is Clean Architecture in three sentences?

    The agent will respond. Depending on your network and the model, this takes a few seconds. While you wait, several things are happening that the rest of this guide will unpack:

    • Your prompt was wrapped in a ExecuteAgentTurn command and sent through the MediatR pipeline for validation and logging (A Message's Journey).
    • The research agent's skill was loaded into the agent's context (Skills System).
    • The harness assembled the final prompt — system instructions, skill content, tool schemas, conversation history — and called the LLM (A Message's Journey).
    • Every step was traced with OpenTelemetry, so if you had Jaeger running, you'd see a span-by-span timeline of the request (Observability & Safety).

    Congratulations — you've just run a production-grade AI agent on your own machine. 🎉

Troubleshooting: errors you'll probably hit

On a fresh clone, these are the issues we see most often. If your error isn't here, check the logs/ folder at the repo root — the harness writes structured JSON logs there that usually contain the real cause buried inside a generic-looking stack trace.

error NETSDK1045: The current .NET SDK does not support targeting .NET 10.0

Your .NET SDK is too old. Either you installed a 9.x version or your PATH is picking up an older install.

Fix: Install .NET 10 SDK from the official download page, then run dotnet --list-sdks to confirm 10.x is listed. On Windows, if multiple SDKs are installed, .NET picks the highest by default — but you can pin a version with a global.json file in the repo root.

Unauthorized or 401 from the LLM call

Your API key is wrong, missing, or pointing at the wrong endpoint.

Fix: Run this from the repo root to see exactly what's been set:

bash
dotnet user-secrets list --project src/Content/Presentation/Presentation.ConsoleUI

Check that Endpoint matches your Azure OpenAI resource URL (with the trailing slash), ApiKey is set to a real key, and DefaultDeployment matches the deployment name in the Azure portal (case-sensitive!). If they look right but it still fails, regenerate the key in Azure — keys do get rotated.

DeploymentNotFound or The API deployment for this resource does not exist

Your API key is valid but the deployment name doesn't match anything in your Azure OpenAI resource.

Fix: Go to the Azure Portal → your Azure OpenAI resource → Model deployments. The name in the Deployment name column is what DefaultDeployment should be set to. Note that the model column (e.g. gpt-4o) is different from the deployment name (which might be gpt-4o, my-deployment, or anything else you chose).

The file is being used by another process

Common on Windows, especially if the repo lives in OneDrive or Dropbox. The build is trying to write a DLL that another process (often a previous dotnet instance or the IDE) has open.

Fix: Close your IDE, stop any running dotnet processes (taskkill /F /IM dotnet.exe on Windows), then retry. If it keeps happening, consider moving the repo to a non-synced folder like C:\dev\.

File access denied when running a tool

The harness sandboxes file system access — tools can only touch files under explicitly allow-listed paths. By default, that's the repo root and below.

Fix: Open src/Content/Presentation/Presentation.ConsoleUI/appsettings.json and find the AppConfig.Infrastructure.FileSystem.AllowedBasePaths array. Add any paths you want the agent to read or write. Don't just open everything to "/" — the sandbox is deliberate. Read Tools & Keyed DI for the why. The exact key is documented in Configuration → FileSystem.

!
Don't disable the sandbox

The first instinct when a sandboxed tool fails is to widen the allow-list to "/" or remove the check entirely. Don't. The sandbox exists because the agent can be tricked into reading or deleting things — see Observability & Safety. Add the specific path you need, nothing more.

error NU1101: Unable to find package

NuGet can't reach the package source. Usually a corporate proxy or VPN issue.

Fix: Check dotnet nuget list source — at minimum, you need nuget.org enabled. If your company has a private feed (Azure Artifacts, Artifactory), you may need to add it with dotnet nuget add source <url> --name internal and provide credentials. Ask your DevOps team for the right URL.


What just happened

Mechanically: you compiled a .NET solution, set credentials, ran a console app that asked an LLM a question, and saw the answer. That's the user view. But under the hood, every one of the following systems engaged for a single prompt:

DI composition root
Program.cs built the service container — registering every layer (Domain, Application, Infrastructure, Presentation) via their respective Add*Dependencies() extension methods.
Hosted services
Background services (like the skill seeder that copies SKILL.md files into the working directory) started before the menu rendered.
MediatR pipeline
Your prompt was wrapped in an ExecuteAgentTurnCommand and flowed through validation, caching, and performance-logging behaviors before reaching the handler.
AgentFactory
Built an agent instance with the right skills loaded, the right tools registered, and content-safety middleware wired in.
ChatClientFactory
Created an Azure OpenAI (or OpenAI) chat client using the credentials you set in User Secrets, decorated with retries, timeouts, and observability.
OpenTelemetry
Every step above created a span. Even though you don't have a trace collector running yet, the spans were captured locally. We'll set up Jaeger in Observability & Safety.

Don't worry about understanding all of that yet — each item gets its own page. What matters right now is that it works on your machine. The rest of this guide is about opening the hood and looking at the engine.

Where to go from here

Two pages worth reading next, in this order: