Skip to content

Commit 8ae0856

Browse files
committed
Add ldk-server-mcp to the workspace
Move the MCP bridge into the ldk-server workspace and switch it to an in-tree client dependency so workspace builds and tests cover it directly. Co-Authored-By: HAL 9000
1 parent 5bd1c61 commit 8ae0856

15 files changed

Lines changed: 3139 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
22
resolver = "2"
3-
members = ["ldk-server-cli", "ldk-server-client", "ldk-server-grpc", "ldk-server"]
3+
members = ["ldk-server-cli", "ldk-server-client", "ldk-server-grpc", "ldk-server", "ldk-server-mcp"]
44
exclude = ["e2e-tests"]
55

66
[profile.release]

ldk-server-cli/src/types.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ impl Amount {
6565
///
6666
/// Returns an error string if the value is not evenly divisible by 1000.
6767
pub fn to_sat(self) -> Result<u64, String> {
68-
if self.msats % 1000 != 0 {
68+
let sats = self.msats / 1000;
69+
if sats * 1000 != self.msats {
6970
Err(format!(
7071
"amount {}msats is not evenly divisible by 1000, cannot convert to whole satoshis",
7172
self.msats

ldk-server-mcp/CLAUDE.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# CLAUDE.md — ldk-server-mcp
2+
3+
MCP (Model Context Protocol) server that exposes LDK Server operations as tools for AI agents.
4+
5+
## Build / Test Commands
6+
7+
```bash
8+
cargo fmt --all
9+
cargo check
10+
cargo test
11+
cargo clippy
12+
```
13+
14+
## Architecture
15+
16+
```
17+
src/
18+
main.rs — Entry point: arg parsing, config, stdio JSON-RPC loop, method dispatch
19+
config.rs — Config loading (TOML + env vars), mirrors ldk-server-cli config
20+
protocol.rs — JSON-RPC 2.0 request/response types
21+
mcp.rs — MCP protocol types (InitializeResult, ToolDefinition, ToolCallResult)
22+
tools/
23+
mod.rs — ToolRegistry: build_tool_registry(), list_tools(), call_tool()
24+
schema.rs — JSON Schema definitions for all tool inputs
25+
handlers.rs — Handler functions: JSON args -> ldk-server-client call -> JSON result
26+
```
27+
28+
## MCP Protocol
29+
30+
- **Version**: `2024-11-05`
31+
- **Spec**: https://spec.modelcontextprotocol.io/
32+
- **Transport**: stdio (one JSON-RPC 2.0 message per line)
33+
- **Methods implemented**: `initialize`, `tools/list`, `tools/call`
34+
- **Notifications handled**: `notifications/initialized` (ignored, no response)
35+
36+
## Config
37+
38+
The server reads configuration in this precedence order (highest first):
39+
40+
1. **Environment variables**: `LDK_BASE_URL`, `LDK_API_KEY`, `LDK_TLS_CERT_PATH`
41+
2. **CLI argument**: `--config <path>` pointing to a TOML file
42+
3. **Default paths**: `~/.ldk-server/config.toml`, `~/.ldk-server/tls.crt`, `~/.ldk-server/{network}/api_key`
43+
44+
TOML config format (same as ldk-server-cli):
45+
```toml
46+
[node]
47+
grpc_service_address = "127.0.0.1:3536"
48+
network = "bitcoin"
49+
50+
[tls]
51+
cert_path = "/path/to/tls.crt"
52+
```
53+
54+
## Adding a New Tool
55+
56+
When a new endpoint is added to `ldk-server-client`:
57+
58+
1. Add a JSON schema function in `src/tools/schema.rs` (follow existing pattern)
59+
2. Add a handler function in `src/tools/handlers.rs`
60+
3. Register in `build_tool_registry()` in `src/tools/mod.rs`
61+
4. Update the expected tool surface in `tests/integration.rs`

ldk-server-mcp/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "ldk-server-mcp"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
ldk-server-client = { path = "../ldk-server-client", features = ["serde"] }
8+
serde = { version = "1.0", features = ["derive"] }
9+
serde_json = "1.0"
10+
tokio = { version = "1.38.0", features = ["rt-multi-thread", "macros", "io-util", "io-std"] }
11+
toml = { version = "0.8", default-features = false, features = ["parse"] }

ldk-server-mcp/README.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# ldk-server-mcp
2+
3+
An [MCP (Model Context Protocol)](https://spec.modelcontextprotocol.io/) server that exposes [LDK Server](https://github.com/lightningdevkit/ldk-server) operations as tools for AI agents. It communicates over JSON-RPC 2.0 via stdio and connects to an LDK Server instance over TLS using the [`ldk-server-client`](https://github.com/lightningdevkit/ldk-server/tree/main/ldk-server-client) library.
4+
5+
## Building
6+
7+
```bash
8+
cargo build --release
9+
```
10+
11+
## Configuration
12+
13+
The server reads configuration in this precedence order (highest wins):
14+
15+
1. **Environment variables**: `LDK_BASE_URL`, `LDK_API_KEY`, `LDK_TLS_CERT_PATH`
16+
2. **CLI argument**: `--config <path>` pointing to a TOML config file
17+
3. **Default paths**: `~/.ldk-server/config.toml`, `~/.ldk-server/tls.crt`, `~/.ldk-server/{network}/api_key`
18+
19+
The TOML config format is the same as used by [`ldk-server-cli`](https://github.com/lightningdevkit/ldk-server/tree/main/ldk-server-cli):
20+
21+
```toml
22+
[node]
23+
grpc_service_address = "127.0.0.1:3536"
24+
network = "signet"
25+
26+
[tls]
27+
cert_path = "/path/to/tls.crt"
28+
```
29+
30+
## Usage
31+
32+
### Standalone
33+
34+
```bash
35+
export LDK_BASE_URL="localhost:3000"
36+
export LDK_API_KEY="your_hex_encoded_api_key"
37+
export LDK_TLS_CERT_PATH="/path/to/tls.crt"
38+
./target/release/ldk-server-mcp
39+
```
40+
41+
Or using a config file:
42+
43+
```bash
44+
./target/release/ldk-server-mcp --config /path/to/config.toml
45+
```
46+
47+
### With Claude Desktop
48+
49+
Add the following to your Claude Desktop MCP configuration (`claude_desktop_config.json`):
50+
51+
```json
52+
{
53+
"mcpServers": {
54+
"ldk-server": {
55+
"command": "/path/to/ldk-server-mcp",
56+
"env": {
57+
"LDK_BASE_URL": "localhost:3000",
58+
"LDK_API_KEY": "your_hex_encoded_api_key",
59+
"LDK_TLS_CERT_PATH": "/path/to/tls.crt"
60+
}
61+
}
62+
}
63+
}
64+
```
65+
66+
### With Claude Code
67+
68+
Add to your Claude Code MCP settings (`.claude/settings.json`):
69+
70+
```json
71+
{
72+
"mcpServers": {
73+
"ldk-server": {
74+
"command": "/path/to/ldk-server-mcp",
75+
"env": {
76+
"LDK_BASE_URL": "localhost:3000",
77+
"LDK_API_KEY": "your_hex_encoded_api_key",
78+
"LDK_TLS_CERT_PATH": "/path/to/tls.crt"
79+
}
80+
}
81+
}
82+
}
83+
```
84+
85+
## Available Tools
86+
87+
The server exposes 37 unary LDK Server RPCs as MCP tools.
88+
89+
Streaming RPCs such as `subscribe_events` and non-RPC HTTP endpoints such as `metrics` are not exposed as tools.
90+
91+
### Node
92+
| Tool | Description |
93+
|------|-------------|
94+
| `get_node_info` | Retrieve node info including node_id, sync status, and best block |
95+
| `get_balances` | Retrieve an overview of all known balances (on-chain and Lightning) |
96+
97+
### On-chain
98+
| Tool | Description |
99+
|------|-------------|
100+
| `onchain_receive` | Generate a new on-chain Bitcoin funding address |
101+
| `onchain_send` | Send an on-chain Bitcoin payment to an address |
102+
103+
### Payments
104+
| Tool | Description |
105+
|------|-------------|
106+
| `bolt11_receive` | Create a BOLT11 Lightning invoice to receive a payment |
107+
| `bolt11_receive_for_hash` | Create a BOLT11 Lightning invoice for a specific payment hash |
108+
| `bolt11_claim_for_hash` | Manually claim a BOLT11 payment for a specific payment hash |
109+
| `bolt11_fail_for_hash` | Manually fail a BOLT11 payment for a specific payment hash |
110+
| `bolt11_receive_via_jit_channel` | Create a BOLT11 Lightning invoice to receive via an LSPS2 JIT channel |
111+
| `bolt11_receive_variable_amount_via_jit_channel` | Create a variable-amount BOLT11 Lightning invoice to receive via an LSPS2 JIT channel |
112+
| `bolt11_send` | Pay a BOLT11 Lightning invoice |
113+
| `bolt12_receive` | Create a BOLT12 offer for receiving Lightning payments |
114+
| `bolt12_send` | Pay a BOLT12 Lightning offer |
115+
| `spontaneous_send` | Send a spontaneous (keysend) payment to a Lightning node |
116+
| `unified_send` | Send a payment given a BIP 21 URI or BIP 353 Human-Readable Name |
117+
118+
### Channels
119+
| Tool | Description |
120+
|------|-------------|
121+
| `open_channel` | Open a new Lightning channel with a remote node |
122+
| `close_channel` | Cooperatively close a Lightning channel |
123+
| `force_close_channel` | Force close a Lightning channel unilaterally |
124+
| `list_channels` | List all known Lightning channels |
125+
| `update_channel_config` | Update forwarding fees and CLTV delta for a channel |
126+
| `splice_in` | Increase a channel's balance by splicing in on-chain funds |
127+
| `splice_out` | Decrease a channel's balance by splicing out to on-chain |
128+
129+
### Payment History
130+
| Tool | Description |
131+
|------|-------------|
132+
| `list_payments` | List all payments (supports pagination via page_token) |
133+
| `get_payment_details` | Get details of a specific payment by its ID |
134+
| `list_forwarded_payments` | List all forwarded payments (supports pagination via page_token) |
135+
136+
### Peers
137+
| Tool | Description |
138+
|------|-------------|
139+
| `connect_peer` | Connect to a Lightning peer without opening a channel |
140+
| `disconnect_peer` | Disconnect from a Lightning peer |
141+
| `list_peers` | List all known Lightning peers |
142+
143+
### Utilities
144+
| Tool | Description |
145+
|------|-------------|
146+
| `decode_invoice` | Decode a BOLT11 invoice and return its parsed fields |
147+
| `decode_offer` | Decode a BOLT12 offer and return its parsed fields |
148+
| `sign_message` | Sign a message with the node's secret key |
149+
| `verify_signature` | Verify a signature against a message and public key |
150+
| `export_pathfinding_scores` | Export the pathfinding scores used by the Lightning router |
151+
152+
## MCP Protocol
153+
154+
- **Protocol version**: `2024-11-05`
155+
- **Transport**: stdio (one JSON-RPC 2.0 message per line)
156+
- **Methods**: `initialize`, `tools/list`, `tools/call`
157+
158+
## Testing
159+
160+
```bash
161+
cargo test
162+
```
163+
164+
## License
165+
166+
Licensed under either of
167+
168+
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
169+
- MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
170+
171+
at your option.

0 commit comments

Comments
 (0)