Haskell bindings to Anthropic's Claude API using servant.
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
import Claude.V1
import Claude.V1.Messages
import Data.Foldable (traverse_)
import qualified Data.Text as Text
import qualified Data.Text.IO as Text.IO
import qualified System.Environment as Environment
main :: IO ()
main = do
key <- Environment.getEnv "ANTHROPIC_KEY"
clientEnv <- getClientEnv "https://api.anthropic.com"
let Methods{ createMessage } = makeMethods clientEnv (Text.pack key) (Just "2023-06-01")
MessageResponse{ content } <- createMessage _CreateMessage
{ model = "claude-sonnet-4-5-20250929"
, messages = [ Message{ role = User, content = [ textContent "Hello!" ] } ]
, max_tokens = 1024
}
let display (ContentBlock_Text{ text }) = Text.IO.putStrLn text
display _ = pure ()
traverse_ display content- Ensure you have Nix with flakes enabled
- Copy the sample environment file:
cp .envrc.sample .envrc- Edit
.envrcwith your Anthropic API key - Run
direnv allow
cabal buildSet your Anthropic API key as an environment variable:
# Option 1: Set directly in your shell
export ANTHROPIC_KEY="your-anthropic-api-key"
# Option 2: Using .envrc with direnv (recommended)
cp .envrc.sample .envrc
# Edit .envrc to add your API key
direnv allowThe API key is needed for running the test suite and example programs.
Run the test suite:
cabal testSee examples for descriptions.
cabal run claude-example
cabal run claude-stream-example
cabal run claude-tool-example
cabal run claude-vision-example
cabal run claude-tool-search-example
cabal run claude-programmatic-tool-calling-example
cabal run claude-structured-outputs-example- Structured Outputs: Constrain Claude's responses to follow a specific JSON schema, or validate tool parameters with strict mode
The following examples require beta features:
Tool Search & Programmatic Tool Calling (advanced-tool-use-2025-11-20):
- Tool Search Tool: Server-side tool search for efficiently handling large numbers of tools
- Programmatic Tool Calling (PTC): Claude writes and executes code to call multiple tools and aggregate results
To enable beta features, use makeMethodsWith with the appropriate beta header:
let options = defaultClientOptions
{ apiKey = key
, anthropicBeta = Just "advanced-tool-use-2025-11-20"
}
let Methods{ createMessage } = makeMethodsWith clientEnv options