emerald/SKILL.md

203 lines
5.8 KiB
Markdown
Raw Normal View History

# 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
```bash
cabal build mcp-example
```
This compiles the example server along with its dependencies (`mcp-types` and
`mcp`).
## Run
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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.
```bash
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
```bash
cabal test all
```
This runs the full integration test suite (42 tests) for the `mcp` library.