---
title: "onemodelcontext"
url: https://recursiveai.org/onemodelcontext/
description: "A .NET SDK for the Model Context Protocol®, client and server, in C#: the 2026-07-28 revision and the older ones behind one API, stdio and Streamable HTTP, generated tool schemas, and OAuth on both sides. Open source, MIT or Apache-2.0. 1.0.1."
---

# onemodelcontext

A .NET SDK for the Model Context Protocol®, client and server, in C#. Declare tools with attributes, serve them over stdio or Streamable HTTP, and connect to any server, old revision or new, through one API.

**Open source**, MIT or Apache-2.0, made by Recursive AI. Version 1.0.1 is on NuGet. The core depends on the .NET base class library only.

```sh
dotnet add package RecursiveAI.OneModelContext
```

- [Getting started](https://recursiveai.org/onemodelcontext/docs/getting-started/)
- [Docs](https://recursiveai.org/onemodelcontext/docs/)
- [GitHub](https://github.com/recursive-ai-oss/onemodelcontext-csharp)
- [NuGet](https://www.nuget.org/packages/RecursiveAI.OneModelContext)

## A quick look

A tool is a method with `[Tool]` on it. The generator writes its schema from the signature and doc comments; one call serves it, and one call connects to it.

The output shown is from a run on 1.0.1 from NuGet. The server is abridged here; Getting started has both programs whole.

[Getting started](https://recursiveai.org/onemodelcontext/docs/getting-started/)

*Glossary.cs, Program.cs · C#*

```
public partial class Glossary
{
    /// <summary>Looks up a term.</summary>
    /// <param name="term">The word or phrase to define.</param>
    [Tool(ReadOnly = true)]
    public string Define(string term) => …;
}
 
await ModelContext.ServeAsync(new Glossary());   // stdio
 
// The client, in another program:
await using var client = await ModelContext.ConnectAsync(
    "dotnet run --project ../GlossaryServer");
Console.WriteLine($"protocol {client.ProtocolVersion} ({client.Era} era)");
// protocol 2026-07-28 (Modern era)
 
var result = await client.CallToolAsync("define",
    new { term = "idempotent" });
Console.WriteLine(result.Text);
// idempotent: Safe to repeat: doing it twice has
// the same effect as doing it once.
```

### Both protocol eras, one API

“The stateless 2026-07-28 revision first, and one legacy codec for 2024-11-05 through 2025-11-25. A client negotiates the era per server; a server answers both on one stdio stream or endpoint.”

[Era negotiation](https://recursiveai.org/onemodelcontext/docs/stdio/)

### stdio and Streamable HTTP

“stdio and any duplex `Stream`; Streamable HTTP as a client, as a host-agnostic server core, on a small built-in HTTP/1.1 listener (loopback by default) and on ASP.NET Core with `MapModelContext`; the deprecated HTTP+SSE transport as a client fallback.”

[Streamable HTTP client](https://recursiveai.org/onemodelcontext/docs/http-client/)

### The built-in listener

A small HTTP/1.1 server on `Socket`, “for local tools and command-line programs.” `ModelContext.ServeHttpAsync` starts one on the loopback address, and every size and time limit is an option with a documented default.

[Listener limits](https://recursiveai.org/onemodelcontext/docs/http-limits/)

### Tools, resources and prompts

“Declared with attributes or registered while the server runs.” In the README’s words, “The generator writes each tool’s JSON Schema 2020-12 from the signature and its doc comments, and an AOT-safe invoker.”

[Tool schemas](https://recursiveai.org/onemodelcontext/docs/tool-schemas/)

### Resource server

For an HTTP server that requires sign-in: “protected resource metadata, challenges, step-up, audience checks; JWT/JWKS, introspection, static-token and delegate validators.”

[Resource server](https://recursiveai.org/onemodelcontext/docs/resource-server/)

### OAuth client

“A full OAuth 2.1 client, Client Credentials and Enterprise-Managed Authorization.” It follows “the 2026-07-28 authorization pages (with the 2025-03-26, 2025-06-18 and 2025-11-25 differences), OAuth 2.1, RFC 9728, RFC 8414, OpenID Connect Discovery, RFC 7636, RFC 8707 and RFC 9207.”

[OAuth client](https://recursiveai.org/onemodelcontext/docs/oauth-client/)

### Embedded authorization server

“An embedded `AuthorizationServer` whose login and consent stay with the host.” In the docs’ words, “Signing a user in and asking for consent is a callback into your application, and the server never renders a login page itself.”

[Authorization server](https://recursiveai.org/onemodelcontext/docs/authorization-server/)

### Extensions

“A public extension mechanism, MCP Apps, and Tasks, Skills and Server Cards, which are `[Experimental]` until their specifications are stable.”

[Extensions](https://recursiveai.org/onemodelcontext/docs/extensions/)

### Safe by default

“Every size, depth and time limit is a documented default on a public option.” Tokens are never logged, and no request that carries a credential follows a redirect.

[Limits and defaults](https://recursiveai.org/onemodelcontext/docs/http-limits/)

## The conformance suite

In the repository’s words, it “is checked against the protocol’s official conformance suite, run as a black box: it is installed from its published package and driven through its command line.” The suite is `@modelcontextprotocol/conformance` 0.2.0-alpha.12.

| Revision | Scenarios that pass |
|---|---|
| 2026-07-28 | Server 35 of 35, client 33 of 33 |
| 2025-11-25 | Server 34 of 34, client 19 of 19 |
| 2025-06-18 | Server 27 of 27, client 5 of 5 |
| 2025-03-26 | Server 1 of 1, client 2 of 2 |
| Extensions | Server 13 of 13, client 7 of 10 |

- **Server.** Run by `gate-server.sh` “on both hosts (`listener` and `aspnetcore`), with the same result on each.” For the server extensions (Tasks, Skills), “the suite itself skips `tasks-status-notifications`.”
- **Client.** Run by `gate-client.sh` with the conformance client. The 3 that fail, `auth/dpop`, `auth/dpop-nonce` and `auth/wif-jwt-bearer`, “test authorization extensions this library does not implement.”
- **Authorization server.** The suite’s two scenarios “pass at every `--spec-version` they apply to.”
- **2024-11-05.** “The suite lists no scenarios for 2024-11-05; that revision is covered by the interop harness.”

[Conformance, scenario by scenario](https://recursiveai.org/onemodelcontext/docs/conformance/)

## What 1.0.1 is, and isn’t

- **Status.** “**Status: 1.0.** The public API is stable and checked by package validation. Tasks, Skills and Server Cards follow experimental MCP extensions and are marked `[Experimental]` until those extensions are stable.”
- **Deprecated features.** “Sampling, Roots and Logging are implemented and marked `[Obsolete]` (diagnostic IDs `OMC0001`-`OMC0003`), following the revision that deprecates them.”
- **The listener is for local use.** “For a server on the internet, host the endpoint in a web framework.”
- **HTTP+SSE.** “This transport is client-only; the library never serves it.”
- **DPoP.** Not implemented. “DPoP will be added in a minor release once it reaches Beta or Stable.”
- **The quick path.** Tools from lambdas are “a reflection quick path that writes the same schemas and is annotated as not trim- or AOT-safe.”
- **Token storage.** A client keeps its tokens in memory, an owner-only file, EF Core or OneLite; “there is no keychain package.”

[The overview](https://recursiveai.org/onemodelcontext/docs/overview/)

## Packages

- **Core**: `RecursiveAI.OneModelContext`: the protocol (both eras), client, server, transports, the built-in listener, authorization, extensions, stores and the `[Tool]` generator. The .NET base class library only.
- **AspNetCore**: `RecursiveAI.OneModelContext.AspNetCore`: `MapModelContext`, the authentication handler and the authorization server endpoints.
- **Hosting**: `RecursiveAI.OneModelContext.Hosting`: `AddContextServer<T>()`, hosted stdio and listener lifetimes, and an `ILogger` bridge.
- **Extensions.AI**: `RecursiveAI.OneModelContext.Extensions.AI`: tools as `AIFunction`s both ways, and Sampling answered by an `IChatClient`.
- **EF Core**: `RecursiveAI.OneModelContext.EntityFrameworkCore`: authorization, token and task stores on your `DbContext`, for several instances.
- **OneLite**: `RecursiveAI.OneModelContext.OneLite`: the same stores in one embedded [OneLite](https://recursiveai.org/onelite/) database file, for a single host.
- **Cli**: `RecursiveAI.OneModelContext.Cli`: the `onemodelcontext` tool: `inspect`, `call`, `read`, `prompt`, `login`, `logout` and `proxy`.
- **Templates**: `RecursiveAI.OneModelContext.Templates`: `dotnet new onemodelcontext-server` and `onemodelcontext-client`.
- **Status**: 1.0.1, all eight packages on one version. 1.0.0 was the first public release.
- **Fixed in 1.0.1**: From the [changelog](https://recursiveai.org/onemodelcontext/docs/changelog/): “Tool-call argument overloads for ordinary C# objects and source-generated JSON metadata.” “Compile checks for documentation C# samples.”
- **.NET**: .NET 10, C#. The core has no native code and is trim- and NativeAOT-safe. MIT or Apache-2.0.

## Go further

- [GitHub](https://github.com/recursive-ai-oss/onemodelcontext-csharp)
- [NuGet](https://www.nuget.org/packages/RecursiveAI.OneModelContext)
- [Getting started](https://recursiveai.org/onemodelcontext/docs/getting-started/)
- [All docs](https://recursiveai.org/onemodelcontext/docs/)
- [Samples](https://recursiveai.org/onemodelcontext/docs/samples/)
- [Coming from the official C# SDK](https://recursiveai.org/onemodelcontext/docs/coming-from-the-official-sdk/)
- [Changelog](https://recursiveai.org/onemodelcontext/docs/changelog/)

Model Context Protocol® is a registered trademark of LF Projects, LLC. OneModelContext is an independent project and is not affiliated with or endorsed by LF Projects, LLC or the Model Context Protocol project.
