- Explore MCP Servers
- haskell-mcp-server
Haskell Mcp Server
What is Haskell Mcp Server
haskell-mcp-server is a fully-featured Haskell library designed for building servers that implement the Model Context Protocol (MCP), enabling robust and type-safe server development.
Use cases
Use cases for haskell-mcp-server include creating interactive applications that require user prompts, managing resources dynamically, and implementing tools that perform specific functions based on user input.
How to use
To use haskell-mcp-server, define your data types for prompts, resources, and tools, implement the corresponding handlers, and run the server using the provided main function. The library leverages Template Haskell for automatic handler derivation.
Key features
Key features include complete MCP implementation, type-safe API, multiple abstractions for control, Template Haskell support for automatic handler generation, and cursor-based pagination for handling large result sets.
Where to use
haskell-mcp-server can be used in various domains such as web services, application backends, and any scenario requiring a structured protocol for data exchange and interaction.
Overview
What is Haskell Mcp Server
haskell-mcp-server is a fully-featured Haskell library designed for building servers that implement the Model Context Protocol (MCP), enabling robust and type-safe server development.
Use cases
Use cases for haskell-mcp-server include creating interactive applications that require user prompts, managing resources dynamically, and implementing tools that perform specific functions based on user input.
How to use
To use haskell-mcp-server, define your data types for prompts, resources, and tools, implement the corresponding handlers, and run the server using the provided main function. The library leverages Template Haskell for automatic handler derivation.
Key features
Key features include complete MCP implementation, type-safe API, multiple abstractions for control, Template Haskell support for automatic handler generation, and cursor-based pagination for handling large result sets.
Where to use
haskell-mcp-server can be used in various domains such as web services, application backends, and any scenario requiring a structured protocol for data exchange and interaction.
Content
mcp-server
A fully-featured Haskell library for building Model Context Protocol (MCP) servers.
Features
- Complete MCP Implementation: Supports MCP 2025-03-26 specification (with backward compatibility for 2024-11-05)
- Type-Safe API: Leverage Haskell’s type system for robust MCP servers
- Multiple Abstractions: Both low-level fine-grained control and high-level derived interfaces
- Template Haskell Support: Automatic handler derivation from data types
- Multiple Transports: STDIO and HTTP Streaming transport (MCP 2025-03-26 Streamable HTTP)
Supported MCP Features
- ✅ Prompts: User-controlled prompt templates with arguments
- ✅ Resources: Application-controlled readable resources
- ✅ Tools: Model-controlled callable functions
- ✅ Initialization Flow: Complete protocol lifecycle with version negotiation
- ✅ Error Handling: Comprehensive error types and JSON-RPC error responses
Quick Start
Add the library mcp-server
to your cabal file:
build-depends: mcp-server
Create a simple module, such as this example below:
Advanced Template Haskell Features
Automatic Naming Conventions
Constructor names are automatically converted to snake_case for MCP names:
data MyTool = GetValue | SetValue | SearchItems -- Becomes: "get_value", "set_value", "search_items"
Automatic Type Conversion
The derivation system automatically converts Text arguments to appropriate Haskell types:
data MyTool = Calculate { number :: Int, factor :: Double, enabled :: Bool } -- Text "42" -> Int 42 -- Text "3.14" -> Double 3.14 -- Text "true" -> Bool True
Supported conversions: Int
, Integer
, Double
, Float
, Bool
, and Text
(no conversion).
Nested Parameter Types
You can nest parameter types with automatic unwrapping:
-- Parameter record types data GetValueParams = GetValueParams { _gvpKey :: Text } data SetValueParams = SetValueParams { _svpKey :: Text, _svpValue :: Text } -- Main tool type data SimpleTool = GetValue GetValueParams | SetValue SetValueParams deriving (Show, Eq)
The Template Haskell derivation recursively unwraps single-parameter constructors until it reaches a record type, then extracts all fields for the MCP schema.
Resource URI Generation
Resources automatically get resource://
URIs based on constructor names:
data MyResource = Menu | Specials -- Generates: "resource://menu", "resource://specials"
Unsupported Patterns
We do not support positional (unnamed) parameters:
-- ❌ This won't work - no field names data SimpleTool = GetValue Int | SetValue Int Text
All parameter types must ultimately resolve to records with named fields to generate proper MCP schemas.
Custom Descriptions
You can provide custom descriptions for constructors and fields using the *WithDescription
variants:
-- Define descriptions for constructors and fields descriptions :: [(String, String)] descriptions = [ ("Recipe", "Generate a recipe for a specific dish") -- Constructor description , ("Search", "Search our menu database") -- Constructor description , ("idea", "The dish you want a recipe for") -- Field description , ("query", "Search terms to find menu items") -- Field description ] -- Use in derivation handlers = McpServerHandlers { prompts = Just $(derivePromptHandlerWithDescription ''MyPrompt 'handlePrompt descriptions) , tools = Just $(deriveToolHandlerWithDescription ''MyTool 'handleTool descriptions) , resources = Just $(deriveResourceHandlerWithDescription ''MyResource 'handleResource descriptions) }
Manual Handler Implementation
For fine-grained control, implement handlers manually:
import MCP.Server -- Manual handler implementation promptListHandler :: IO [PromptDefinition] promptGetHandler :: PromptName -> [(ArgumentName, ArgumentValue)] -> IO (Either Error Content) -- ... implement your custom logic main :: IO () main = runMcpServerStdio serverInfo handlers where handlers = McpServerHandlers { prompts = Just (promptListHandler, promptGetHandler) , resources = Nothing -- Not supported , tools = Nothing -- Not supported }
HTTP Transport (NEW!)
The library now supports MCP 2025-03-26 Streamable HTTP transport:
import MCP.Server.Transport.Http -- Simple HTTP server (localhost:3000/mcp) main = runMcpServerHttp serverInfo handlers -- Custom configuration main = runMcpServerHttpWithConfig customConfig serverInfo handlers where customConfig = HttpConfig { httpPort = 8080 , httpHost = "0.0.0.0" , httpEndpoint = "/api/mcp" , httpVerbose = True -- Enable detailed logging }
Features:
- CORS enabled for web clients
- GET
/mcp
for server discovery - POST
/mcp
for JSON-RPC messages - Full MCP 2025-03-26 compliance
Examples
The library includes several examples:
examples/Simple/
: Basic key-value store using Template Haskell derivation (STDIO)examples/Complete/
: Full-featured example with prompts, resources, and tools (STDIO)examples/HttpSimple/
: HTTP version of the simple key-value store
Docker Usage
I like to build and publish my MCP servers to Docker - which means that it’s much easier to configure assistants such as Claude Desktop to run them.
# Build the image
docker build -t haskell-mcp-server .
# Run different examples
docker run -i --entrypoint="/usr/local/bin/haskell-mcp-server" haskell-mcp-server
And then configure Claude by editing claude_desktop_config.json
:
{
"mcpServers": {
"haskell-mcp-server-example": {
"command": "docker",
"args": [
"run",
"-i",
"--entrypoint=/usr/local/bin/haskell-mcp-server",
"haskell-mcp-server"
]
}
}
}
Documentation
Contributing
Contributions are welcome! Please see the issue tracker for open issues and feature requests.
Disclaimer - AI Assistance
I am not sure whether there is any stigma associated with this but Claude helped me write a lot of this library. I started with a very specific specification of what I wanted to achieve and worked shoulder-to-shoulder with Claude to implement and refactor the library until I was happy with it. A few of the features such as the Derive functions are a little out of my comfort zone to have manually written, so I appreciated having an expert guide me here - however I do suspect that this implementation may be sub-par and I do intend to refactor and rewrite large pieces of this through regular maintenance.
License
BSD-3-Clause