emerald/SKILL.md
2026-03-19 14:47:09 +00:00

5.8 KiB

Example MCP Server — Build & Test Skill

This skill explains how to build, run, and test the example MCP server that demonstrates the mcp Haskell library.

Prerequisites

  • GHC 9.12.2 and cabal-install
  • The project root is at the repository root (where cabal.project lives)

Build

cabal build mcp-example

This compiles the example server along with its dependencies (mcp-types and mcp).

Run

cabal run mcp-example

The server starts on http://localhost:8080/mcp and prints a JWT bearer token to stdout. Copy this token — you need it for all requests.

Test with curl

Replace $TOKEN with the token printed by the server.

1. Initialize the session

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

2. Send initialized notification

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":null}'

3. List tools

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

4. Call the echo tool

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"echo","arguments":{"message":"Hello from MCP!"}}}'

5. Call the add tool

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"add","arguments":{"a":17,"b":25}}}'

6. Call the current-time tool

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"current-time","arguments":{}}}'

7. List resources

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":6,"method":"resources/list","params":{}}'

8. Read a resource

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":7,"method":"resources/read","params":{"uri":"resource://example/readme"}}'

9. List resource templates

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":8,"method":"resources/templates/list","params":{}}'

10. Read a templated resource

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":9,"method":"resources/read","params":{"uri":"resource://example/users/42"}}'

11. List prompts

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":10,"method":"prompts/list","params":{}}'

12. Get a prompt

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":11,"method":"prompts/get","params":{"name":"summarize","arguments":{"text":"The MCP protocol enables AI models to interact with external tools."}}}'

13. Request completions

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":12,"method":"completion/complete","params":{"ref":{"type":"ref/prompt","name":"summarize"},"argument":{"name":"text","value":"Hel"}}}'

14. Set log level

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":13,"method":"logging/setLevel","params":{"level":"debug"}}'

15. Ping

curl -s -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":14,"method":"ping","params":{}}'

Available Features

Feature Methods
Tools tools/list, tools/call
Resources resources/list, resources/read
Resource Templates resources/templates/list
Prompts prompts/list, prompts/get
Completions completion/complete
Logging logging/setLevel
Lifecycle initialize, notifications/initialized
Health ping

Run the agent test (Claude Agent SDK)

A Node.js test in test/ uses the Claude Agent SDK to start the server and exercise every tool endpoint through a Claude agent.

cd mcp-server/example/test
pnpm install
pnpm test   # requires ANTHROPIC_API_KEY

The script starts the server, captures its JWT token, connects a Claude agent, and verifies that all 3 tool checks pass (echo, add, current-time). See test/README.md for details.

Run the library tests

cabal test all

This runs the full integration test suite (42 tests) for the mcp library.