Created
September 29, 2025 10:45
-
-
Save Thorium/46d683453517ca0567f035e78d758449 to your computer and use it in GitHub Desktop.
ModelContextProtocol with FSharp (MCP with F#)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #r "nuget: ModelContextProtocol,0.4.0-preview.1" | |
| open ModelContextProtocol.Client | |
| open ModelContextProtocol.Protocol | |
| open System | |
| open System.Threading.Tasks | |
| module McpClient = | |
| let clientTransport = | |
| StdioClientTransport( | |
| StdioClientTransportOptions( | |
| Name = "Everything", | |
| Command = "npx", | |
| Arguments = | |
| [| "-y"; "@modelcontextprotocol/server-everything" |])) | |
| // Print the list of tools available from the server. | |
| let listTools = | |
| task { | |
| let! client = McpClient.CreateAsync clientTransport | |
| let! tools = client.ListToolsAsync() | |
| let res = | |
| tools | |
| |> Seq.toArray | |
| |> Array.map(fun tool -> | |
| $"{tool.Name} ({tool.Description})") | |
| do! client.DisposeAsync() | |
| res |> Array.iter Console.WriteLine | |
| return () | |
| } | |
| // Execute a tool (this would normally be driven by LLM tool invocations). | |
| let executeTool = | |
| task { | |
| let! client = McpClient.CreateAsync clientTransport | |
| let! result = client.CallToolAsync( | |
| "echo", | |
| readOnlyDict [| "message", ("Hello MCP!" :> obj) |], | |
| cancellationToken = System.Threading.CancellationToken.None | |
| ) | |
| // echo always returns one and only one text content object | |
| let content = | |
| result.Content | |
| |> Seq.toArray | |
| |> Array.find(fun c -> c.Type = "text") | |
| :?> TextContentBlock | |
| |> _.Text | |
| do! client.DisposeAsync() | |
| Console.WriteLine content | |
| return () | |
| } | |
| [| McpClient.listTools; McpClient.executeTool |] | |
| |> Array.map(fun t -> t :> Task) | |
| |> Task.WaitAll |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "servers": { | |
| "MyServer": { | |
| "type": "stdio", | |
| "command": "dotnet", | |
| "args": [ | |
| "fsi", | |
| "C:\\git\\mcp\\Server.fsx" | |
| ] | |
| } | |
| }, | |
| "inputs": [] | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #r "nuget: ModelContextProtocol,0.4.0-preview.1" | |
| #r "nuget: Microsoft.Extensions.Hosting" | |
| open Microsoft.Extensions.DependencyInjection | |
| open Microsoft.Extensions.Hosting | |
| open Microsoft.Extensions.Logging | |
| open ModelContextProtocol.Server | |
| open System | |
| open System.ComponentModel | |
| [<McpServerToolType>] | |
| type EchoTool = | |
| [<McpServerTool; | |
| Description "Echoes the message back to the client.">] | |
| static member Echo (message:string) = $"Hello from F#: {message}" | |
| // Define your urls whatever .NET Core style you like.... | |
| let args = [|"--urls \"http://localhost:5000\""|] | |
| let builder = Host.CreateApplicationBuilder args | |
| builder.Logging.AddConsole(fun consoleLogOptions -> | |
| // Configure all logs to go to stderr | |
| consoleLogOptions.LogToStandardErrorThreshold <- LogLevel.Trace | |
| ) | |
| builder.Services | |
| .AddMcpServer(fun opts -> | |
| opts.ServerInfo <- ModelContextProtocol.Protocol.Implementation( | |
| Name = "MyServer", Version = "1.0", | |
| Title = "My echo server" | |
| ) | |
| ) | |
| .WithStdioServerTransport() | |
| .WithToolsFromAssembly() | |
| builder.Build().RunAsync() | |
| |> System.Threading.Tasks.Task.WaitAny | |
| // Test in VSCode CoPilot: | |
| // Create .vscode\mcp.json file, you can make it like this: | |
| // VSCode: Press Ctrl + Shift + P -> Command (stdio), Command to run: | |
| // dotnet fsi c:\mypath\Server.fsx | |
| // Then Ctrl + Alt + I -> Agents mode, should be available now. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment