FsMcp.Server.Http 1.0.1

dotnet add package FsMcp.Server.Http --version 1.0.1
                    
NuGet\Install-Package FsMcp.Server.Http -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FsMcp.Server.Http" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FsMcp.Server.Http" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="FsMcp.Server.Http" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FsMcp.Server.Http --version 1.0.1
                    
#r "nuget: FsMcp.Server.Http, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FsMcp.Server.Http@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FsMcp.Server.Http&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=FsMcp.Server.Http&version=1.0.1
                    
Install as a Cake Tool

FsMcp

FsMcp is an idiomatic F# toolkit for building Model Context Protocol (MCP) servers and clients. It wraps the official Microsoft ModelContextProtocol .NET SDK with computation expressions, typed tool handlers, Result-based error handling, and composable middleware — so you can build MCP servers in F# with type safety and zero boilerplate.

CI NuGet License: MIT Docs

type GreetArgs = { name: string; greeting: string option }

let server = mcpServer {
    name "MyServer"
    version "1.0.0"

    tool (TypedTool.define<GreetArgs> "greet" "Greets a person" (fun args -> task {
        let greeting = args.greeting |> Option.defaultValue "Hello"
        return Ok [ Content.text $"{greeting}, {args.name}!" ]
    }) |> unwrapResult)

    useStdio
}

Server.run server |> fun t -> t.GetAwaiter().GetResult()
// Input schema auto-generated: name=required, greeting=optional

Install

dotnet add package FsMcp.Server     # server builder + stdio transport
dotnet add package FsMcp.Client     # typed client wrapper
dotnet add package FsMcp.Testing    # test helpers + FsCheck generators
dotnet add package FsMcp.TaskApi    # FsToolkit.ErrorHandling pipeline
dotnet add package FsMcp.Server.Http  # HTTP/SSE transport (opt-in ASP.NET)
dotnet add package FsMcp.Sampling   # LLM sampling from server tools

Why FsMcp?

  • mcpServer { } CE — declare tools, resources, prompts in a single block
  • TypedTool.define<'T> — F# record as input, JSON Schema auto-generated via TypeShape
  • Result<'T, McpError> — no exceptions in expected paths, typed errors everywhere
  • Smart constructorsToolName.create validates at construction, not at runtime
  • Composable middleware — logging, validation, telemetry via Middleware.pipeline
  • 306 tests — Expecto + FsCheck property tests on every domain type

Quick Start

Server with typed tools

open FsMcp.Core
open FsMcp.Core.Validation
open FsMcp.Server

type CalcArgs = { a: float; b: float }

let server = mcpServer {
    name "Calculator"
    version "1.0.0"

    tool (TypedTool.define<CalcArgs> "add" "Add two numbers" (fun args -> task {
        return Ok [ Content.text $"{args.a + args.b}" ]
    }) |> unwrapResult)

    tool (TypedTool.define<CalcArgs> "divide" "Divide a by b" (fun args -> task {
        if args.b = 0.0 then return Error (TransportError "Division by zero")
        else return Ok [ Content.text $"{args.a / args.b}" ]
    }) |> unwrapResult)

    useStdio
}

Server.run server |> fun t -> t.GetAwaiter().GetResult()

HTTP transport

dotnet add package FsMcp.Server.Http
open FsMcp.Server.Http

HttpServer.run server (Some "/mcp") "http://localhost:3001"
|> fun t -> t.GetAwaiter().GetResult()

Client

open FsMcp.Core.Validation
open FsMcp.Client

let demo () = task {
    let config = {
        Transport = ClientTransport.stdio "dotnet" ["run"; "--project"; "../Calculator"]
        Name = "TestClient"
        ShutdownTimeout = None
    }
    let! client = McpClient.connect config
    let! tools = McpClient.listTools client

    let toolName = ToolName.create "add" |> unwrapResult
    let args = Map.ofList [
        "a", System.Text.Json.JsonDocument.Parse("10").RootElement
        "b", System.Text.Json.JsonDocument.Parse("20").RootElement
    ]
    let! result = McpClient.callTool client toolName args
    // result : Result<Content list, McpError>
}

Testing

open FsMcp.Testing

// Direct handler invocation — no network, no process spawning
let result =
    TestServer.callTool serverConfig "add"
        (Map.ofList ["a", jsonEl 10; "b", jsonEl 20])
    |> Async.AwaitTask |> Async.RunSynchronously

result |> Expect.mcpHasTextContent "30" "addition works"

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Your F# Code                             │
│   mcpServer { tool ...; resource ...; prompt ... }              │
├──────────────┬──────────────────────────────┬───────────────────┤
│ FsMcp.Server │       FsMcp.Core             │   FsMcp.Client    │
│              │                              │                   │
│ CE builder     Types (DUs, records)         │ Typed wrapper     │
│ TypedHandlers  Validation (smart ctors)     │ Async module      │
│ Middleware     Serialization (JSON)          │                   │
│ Streaming      Interop (internal)           │                   │
│ Telemetry                                   │                   │
├──────────────┴──────────────────────────────┴───────────────────┤
│              Microsoft ModelContextProtocol SDK                  │
├─────────────────────────────────────────────────────────────────┤
│                      .NET 10 Runtime                            │
└─────────────────────────────────────────────────────────────────┘

Packages

Package What it does
FsMcp.Core Domain types, smart constructors, JSON serialization
FsMcp.Server mcpServer { } CE, typed handlers, middleware, stdio transport
FsMcp.Server.Http HTTP/SSE transport via ASP.NET Core (opt-in)
FsMcp.Client Typed client with Result<'T, McpError>
FsMcp.Testing TestServer.callTool, Expect.mcp*, FsCheck generators
FsMcp.TaskApi taskResult { } pipeline via FsToolkit.ErrorHandling
FsMcp.Sampling Server-side LLM invocation via MCP sampling

Features

  • Typed tool handlersTypedTool.define<'T> with TypeShape-powered JSON Schema + caching
  • Nested CEmcpTool { toolName "..."; typedHandler ... }
  • Streaming toolsStreamingTool.define with IAsyncEnumerable<Content>
  • NotificationsContextualTool.define with progress + log callbacks
  • Validation middleware — auto-validates args against schema before handler
  • TelemetryTelemetry.tracing() (Activity/OTel) + MetricsCollector
  • Hot reloadDynamicServer.addTool / removeTool at runtime
  • Error handlingFsToolkit.ErrorHandling integration via FsMcp.TaskApi

Build & Test

dotnet build       # 7 packages
dotnet test        # 306 tests (Expecto + FsCheck)

Examples

See examples/ for runnable MCP servers:

  • EchoServer — echo + reverse tools, resource, prompt
  • Calculator — add/subtract/multiply/divide
  • FileServer — read_file, list_directory, file_info

Design Principles

  1. Wrap, don't reimplement — protocol concerns stay in Microsoft SDK
  2. Idiomatic F# — DUs, Result, CEs, pipe-friendly
  3. Type safety — private constructors, no obj in public API
  4. Test-first — Expecto + FsCheck on every function
  5. Composable — middleware, function handlers, no inheritance

Contributing

See CONTRIBUTING.md. Issues and PRs welcome.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 33 4/3/2026
1.0.0 32 4/3/2026