FsMcp.Server 1.0.1

dotnet add package FsMcp.Server --version 1.0.1
                    
NuGet\Install-Package FsMcp.Server -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" 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" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="FsMcp.Server" />
                    
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 --version 1.0.1
                    
#r "nuget: FsMcp.Server, 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@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&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=FsMcp.Server&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 (3)

Showing the top 3 NuGet packages that depend on FsMcp.Server:

Package Downloads
FsMcp.Testing

Testing utilities for MCP servers: assertions, FsCheck generators, and in-process test server

FsMcp.Server.Http

HTTP/SSE transport for FsMcp MCP servers via ASP.NET Core

FsMcp.Sampling

MCP Sampling support — let server-side tools invoke LLM reasoning via the client

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 35 4/3/2026
1.0.0 73 4/3/2026