Skip to content

Commit 568b72e

Browse files
Update readme
1 parent 39a6b87 commit 568b72e

File tree

1 file changed

+71
-104
lines changed

1 file changed

+71
-104
lines changed

README.md

Lines changed: 71 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
**The safest way to make REST calls in C#**
66

7+
**New!** Generate MCP servers from OpenAPI specs!!!
8+
79
Built from the ground up with functional programming, type safety, and modern .NET patterns. Successor to the [original RestClient.Net](https://www.nuget.org/packages/RestClient.Net.Abstractions).
810

911
## What Makes It Different
@@ -16,6 +18,7 @@ This library is uncompromising in its approach to type safety and functional des
1618

1719
## Features
1820

21+
- **Generate an MCP Server and client code** from an OpenAPI 3.x spec.
1922
- **Result Types** - Returns `Result<TSuccess, HttpError<TError>>` with closed hierarchy types for compile-time safety (Outcome package)
2023
- **Zero Exceptions** - No exception throwing for predictable error handling
2124
- **Progress Reporting** - Built-in download/upload progress tracking
@@ -108,6 +111,74 @@ global using ExceptionErrorPost = Outcome.HttpError<ErrorResponse>.ExceptionErro
108111

109112
If you use the OpenAPI generator, it will generate these type aliases for you automatically.
110113

114+
## OpenAPI Client and MCP Code Generation
115+
116+
Generate type-safe C# clients and MCP servers from OpenAPI specs.
117+
118+
### Client Generation
119+
120+
```bash
121+
dotnet add package RestClient.Net.OpenApiGenerator
122+
```
123+
124+
Generate extension methods from OpenAPI 3.x specs:
125+
126+
```csharp
127+
// Generated code usage
128+
using YourApi.Generated;
129+
130+
var httpClient = factory.CreateClient();
131+
132+
// All HTTP methods supported with Result types
133+
var user = await httpClient.GetUserById("123", ct);
134+
var created = await httpClient.CreateUser(newUser, ct);
135+
var updated = await httpClient.UpdateUser((Params: "123", Body: user), ct);
136+
var deleted = await httpClient.DeleteUser("123", ct);
137+
138+
// Pattern match on results
139+
switch (user)
140+
{
141+
case OkUser(var success):
142+
Console.WriteLine($"User: {success.Name}");
143+
break;
144+
case ErrorUser(var error):
145+
Console.WriteLine($"Error: {error.StatusCode}");
146+
break;
147+
}
148+
```
149+
150+
The generator creates extension methods on `HttpClient`, model classes from schemas, and result type aliases for pattern matching.
151+
152+
### MCP Server Generation
153+
154+
Generate Model Context Protocol servers for Claude Code from OpenAPI specs:
155+
156+
```bash
157+
# Generate API client first
158+
dotnet run --project RestClient.Net.OpenApiGenerator.Cli -- \
159+
-u api.yaml \
160+
-o Generated \
161+
-n YourApi.Generated
162+
163+
# Generate MCP tools from the same spec
164+
dotnet run --project RestClient.Net.McpGenerator.Cli -- \
165+
--openapi-url api.yaml \
166+
--output-file Generated/McpTools.g.cs \
167+
--namespace YourApi.Mcp \
168+
--server-name YourApi \
169+
--ext-namespace YourApi.Generated \
170+
--tags "Search,Resources"
171+
```
172+
173+
The MCP generator wraps the generated extension methods as MCP tools that Claude Code can invoke.
174+
175+
**Complete example:** See `Samples/NucliaDbClient.McpServer` for a working MCP server built from the NucliaDB OpenAPI spec. The example includes:
176+
- Generated client code (`Samples/NucliaDbClient/Generated`)
177+
- Generated MCP tools (`NucliaDbMcpTools.g.cs`)
178+
- MCP server host project (`NucliaDbClient.McpServer`)
179+
- Docker Compose setup for NucliaDB
180+
- Claude Code integration script (`run-for-claude.sh`)
181+
111182
## Exhaustiveness Checking with Exhaustion
112183

113184
**Exhaustion is integral to RestClient.Net's safety guarantees.** It's a Roslyn analyzer that ensures you handle every possible case when pattern matching on Result types.
@@ -155,110 +226,6 @@ Exhaustion works by analyzing sealed type hierarchies in switch expressions and
155226

156227
If you don't handle all three, your code won't compile.
157228

158-
### OpenAPI Code Generation
159-
160-
Generate type-safe extension methods from OpenAPI specs:
161-
162-
```csharp
163-
using JSONPlaceholder.Generated;
164-
165-
// Get HttpClient from factory
166-
var httpClient = factory.CreateClient();
167-
168-
// GET all todos
169-
var todos = await httpClient.GetTodos(ct);
170-
171-
// GET todo by ID
172-
var todo = await httpClient.GetTodoById(1, ct);
173-
switch (todo)
174-
{
175-
case OkTodo(var success):
176-
Console.WriteLine($"Todo: {success.Title}");
177-
break;
178-
case ErrorTodo(var error):
179-
Console.WriteLine($"Error: {error.StatusCode} - {error.Body}");
180-
break;
181-
}
182-
183-
// POST - create a new todo
184-
var newTodo = new TodoInput { Title = "New Task", UserId = 1, Completed = false };
185-
var created = await httpClient.CreateTodo(newTodo, ct);
186-
187-
// PUT - update with path param and body
188-
var updated = await httpClient.UpdateTodo((Params: 1, Body: newTodo), ct);
189-
190-
// DELETE - returns Unit
191-
var deleted = await httpClient.DeleteTodo(1, ct);
192-
```
193-
194-
```bash
195-
dotnet add package RestClient.Net.OpenApiGenerator
196-
```
197-
198-
Define your schema (OpenAPI 3.x):
199-
```yaml
200-
openapi: 3.0.0
201-
paths:
202-
/users/{id}:
203-
get:
204-
operationId: getUserById
205-
parameters:
206-
- name: id
207-
in: path
208-
required: true
209-
schema:
210-
type: string
211-
responses:
212-
'200':
213-
content:
214-
application/json:
215-
schema:
216-
$ref: '#/components/schemas/User'
217-
/users:
218-
post:
219-
operationId: createUser
220-
requestBody:
221-
content:
222-
application/json:
223-
schema:
224-
$ref: '#/components/schemas/User'
225-
responses:
226-
'201':
227-
content:
228-
application/json:
229-
schema:
230-
$ref: '#/components/schemas/User'
231-
```
232-
233-
The generator creates:
234-
1. **Extension methods** - Strongly-typed methods on `HttpClient`
235-
2. **Model classes** - DTOs from schema definitions
236-
3. **Result type aliases** - Convenient `OkUser` and `ErrorUser` types
237-
238-
Generated usage:
239-
```csharp
240-
// Get HttpClient from factory
241-
var httpClient = factory.CreateClient();
242-
243-
// GET with path parameter
244-
var user = await httpClient.GetUserById("123", ct);
245-
246-
// POST with body
247-
var created = await httpClient.CreateUser(newUser, ct);
248-
249-
// PUT with path param and body
250-
var updated = await httpClient.UpdateUser((Params: "123", Body: user), ct);
251-
252-
// DELETE returns Unit
253-
var deleted = await httpClient.DeleteUser("123", ct);
254-
```
255-
256-
All generated methods:
257-
- Create extension methods on `HttpClient` (use with `IHttpClientFactory.CreateClient()`)
258-
- Return `Result<TSuccess, HttpError<TError>>` for functional error handling
259-
- Bundle URL/body/headers into `HttpRequestParts` via `buildRequest`
260-
- Support progress reporting through `ProgressReportingHttpContent`
261-
262229
### Progress Reporting
263230

264231
You can track upload progress with `ProgressReportingHttpContent`. This example writes to the console when there is a progress report.

0 commit comments

Comments
 (0)