@lightninglabs/lightning-mcp-server 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.claude-plugin/marketplace.json +36 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/README.md +307 -0
  4. package/bin/lightning-mcp-server +15 -0
  5. package/docs/architecture.md +455 -0
  6. package/docs/commerce.md +357 -0
  7. package/docs/l402-and-lnget.md +267 -0
  8. package/docs/mcp-server.md +285 -0
  9. package/docs/quickref.md +263 -0
  10. package/docs/security.md +298 -0
  11. package/docs/two-agent-setup.md +394 -0
  12. package/package.json +52 -0
  13. package/postinstall.js +160 -0
  14. package/skills/aperture/SKILL.md +330 -0
  15. package/skills/aperture/scripts/install.sh +68 -0
  16. package/skills/aperture/scripts/setup.sh +155 -0
  17. package/skills/aperture/scripts/start.sh +81 -0
  18. package/skills/aperture/scripts/stop.sh +57 -0
  19. package/skills/aperture/templates/aperture-regtest.yaml +36 -0
  20. package/skills/aperture/templates/aperture.yaml.template +64 -0
  21. package/skills/aperture/templates/docker-compose-aperture.yml +59 -0
  22. package/skills/commerce/SKILL.md +211 -0
  23. package/skills/lib/config-gen.sh +127 -0
  24. package/skills/lib/rest.sh +69 -0
  25. package/skills/lightning-security-module/SKILL.md +253 -0
  26. package/skills/lightning-security-module/references/architecture.md +133 -0
  27. package/skills/lightning-security-module/scripts/docker-start.sh +117 -0
  28. package/skills/lightning-security-module/scripts/docker-stop.sh +53 -0
  29. package/skills/lightning-security-module/scripts/export-credentials.sh +268 -0
  30. package/skills/lightning-security-module/scripts/install.sh +178 -0
  31. package/skills/lightning-security-module/scripts/setup-signer.sh +307 -0
  32. package/skills/lightning-security-module/scripts/start-signer.sh +152 -0
  33. package/skills/lightning-security-module/scripts/stop-signer.sh +240 -0
  34. package/skills/lightning-security-module/templates/docker-compose-signer.yml +35 -0
  35. package/skills/lightning-security-module/templates/signer-lnd.conf.template +69 -0
  36. package/skills/lnd/SKILL.md +441 -0
  37. package/skills/lnd/profiles/debug.env +4 -0
  38. package/skills/lnd/profiles/default.env +3 -0
  39. package/skills/lnd/profiles/regtest.env +4 -0
  40. package/skills/lnd/profiles/taproot.env +3 -0
  41. package/skills/lnd/profiles/wumbo.env +3 -0
  42. package/skills/lnd/references/security.md +156 -0
  43. package/skills/lnd/scripts/create-wallet.sh +464 -0
  44. package/skills/lnd/scripts/docker-start.sh +256 -0
  45. package/skills/lnd/scripts/docker-stop.sh +109 -0
  46. package/skills/lnd/scripts/import-credentials.sh +145 -0
  47. package/skills/lnd/scripts/install.sh +195 -0
  48. package/skills/lnd/scripts/lncli.sh +150 -0
  49. package/skills/lnd/scripts/start-lnd.sh +241 -0
  50. package/skills/lnd/scripts/stop-lnd.sh +218 -0
  51. package/skills/lnd/scripts/unlock-wallet.sh +134 -0
  52. package/skills/lnd/templates/docker-compose-regtest.yml +122 -0
  53. package/skills/lnd/templates/docker-compose-watchonly.yml +71 -0
  54. package/skills/lnd/templates/docker-compose.yml +49 -0
  55. package/skills/lnd/templates/litd-regtest.conf.template +61 -0
  56. package/skills/lnd/templates/litd-watchonly.conf.template +57 -0
  57. package/skills/lnd/templates/litd.conf.template +88 -0
  58. package/skills/lnd/templates/lnd.conf.template +91 -0
  59. package/skills/lnget/SKILL.md +288 -0
  60. package/skills/lnget/scripts/install.sh +69 -0
  61. package/skills/macaroon-bakery/SKILL.md +179 -0
  62. package/skills/macaroon-bakery/scripts/bake.sh +337 -0
  63. package/skills/mcp-lnc/SKILL.md +280 -0
  64. package/skills/mcp-lnc/scripts/configure.sh +130 -0
  65. package/skills/mcp-lnc/scripts/install.sh +103 -0
  66. package/skills/mcp-lnc/scripts/setup-claude-config.sh +162 -0
  67. package/skills/mcp-lnc/templates/env.template +16 -0
  68. package/versions.env +23 -0
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env bash
2
+ # Bake, inspect, and manage lnd macaroons for least-privilege agent access.
3
+ #
4
+ # Usage:
5
+ # bake.sh --role pay-only # Bake a preset role
6
+ # bake.sh --role invoice-only # Invoice-only agent
7
+ # bake.sh --role read-only # Read-only agent
8
+ # bake.sh --role channel-admin # Channel management agent
9
+ # bake.sh --role signer-only # Remote signer scoped macaroon
10
+ # bake.sh --custom uri:/lnrpc.Lightning/... # Custom permissions
11
+ # bake.sh --inspect <macaroon-path> # Inspect a macaroon
12
+ # bake.sh --list-permissions # List all available permissions
13
+ # bake.sh --container sam --role pay-only # Bake inside a Docker container
14
+ # bake.sh --rpcserver remote:10009 \ # Bake on a remote node
15
+ # --tlscertpath ~/tls.cert \
16
+ # --macaroonpath ~/admin.macaroon --role pay-only
17
+
18
+ set -e
19
+
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ LND_DIR="${LND_DIR:-}"
22
+ NETWORK="${NETWORK:-testnet}"
23
+ RPC_PORT=""
24
+ SAVE_TO=""
25
+ ROLE=""
26
+ INSPECT=""
27
+ LIST_PERMS=false
28
+ CUSTOM_PERMS=()
29
+ CONTAINER=""
30
+ RPCSERVER=""
31
+ TLSCERTPATH=""
32
+ MACAROONPATH=""
33
+
34
+ # Parse arguments.
35
+ while [[ $# -gt 0 ]]; do
36
+ case $1 in
37
+ --role)
38
+ ROLE="$2"
39
+ shift 2
40
+ ;;
41
+ --custom)
42
+ shift
43
+ # Collect all remaining non-flag args as permissions.
44
+ while [[ $# -gt 0 ]] && [[ ! "$1" =~ ^-- ]]; do
45
+ CUSTOM_PERMS+=("$1")
46
+ shift
47
+ done
48
+ ;;
49
+ --inspect)
50
+ INSPECT="$2"
51
+ shift 2
52
+ ;;
53
+ --list-permissions)
54
+ LIST_PERMS=true
55
+ shift
56
+ ;;
57
+ --save-to)
58
+ SAVE_TO="$2"
59
+ shift 2
60
+ ;;
61
+ --network)
62
+ NETWORK="$2"
63
+ shift 2
64
+ ;;
65
+ --lnddir)
66
+ LND_DIR="$2"
67
+ shift 2
68
+ ;;
69
+ --rpc-port)
70
+ RPC_PORT="$2"
71
+ shift 2
72
+ ;;
73
+ --container)
74
+ CONTAINER="$2"
75
+ shift 2
76
+ ;;
77
+ --rpcserver)
78
+ RPCSERVER="$2"
79
+ shift 2
80
+ ;;
81
+ --tlscertpath)
82
+ TLSCERTPATH="$2"
83
+ shift 2
84
+ ;;
85
+ --macaroonpath)
86
+ MACAROONPATH="$2"
87
+ shift 2
88
+ ;;
89
+ -h|--help)
90
+ echo "Usage: bake.sh [options]"
91
+ echo ""
92
+ echo "Bake, inspect, and manage lnd macaroons."
93
+ echo ""
94
+ echo "Actions:"
95
+ echo " --role ROLE Bake a preset role macaroon"
96
+ echo " --custom URI [URI...] Bake with custom permission URIs"
97
+ echo " --inspect PATH Inspect a macaroon file"
98
+ echo " --list-permissions List all available permission URIs"
99
+ echo ""
100
+ echo "Preset roles: pay-only, invoice-only, read-only, channel-admin, signer-only"
101
+ echo ""
102
+ echo "Options:"
103
+ echo " --save-to PATH Output path (default: auto-generated)"
104
+ echo " --network NETWORK Bitcoin network (default: testnet)"
105
+ echo " --lnddir DIR lnd data directory (default: ~/.lnd)"
106
+ echo " --rpc-port PORT lnd RPC port (for non-default setups)"
107
+ echo " --container NAME Run lncli inside a Docker container"
108
+ echo " --rpcserver HOST:PORT Connect to a remote lnd node"
109
+ echo " --tlscertpath PATH TLS certificate for remote connection"
110
+ echo " --macaroonpath PATH Macaroon for remote authentication"
111
+ exit 0
112
+ ;;
113
+ *)
114
+ echo "Unknown option: $1" >&2
115
+ exit 1
116
+ ;;
117
+ esac
118
+ done
119
+
120
+ # Apply default lnddir if not set.
121
+ if [ -z "$LND_DIR" ]; then
122
+ if [ -n "$CONTAINER" ]; then
123
+ LND_DIR="/root/.lnd"
124
+ else
125
+ LND_DIR="$HOME/.lnd"
126
+ fi
127
+ fi
128
+
129
+ # Build lncli base command as an array (preserves paths with spaces).
130
+ LNCLI_CMD=()
131
+ if [ -n "$CONTAINER" ]; then
132
+ LNCLI_CMD+=(docker exec "$CONTAINER")
133
+ fi
134
+ LNCLI_CMD+=(lncli "--network=$NETWORK" "--lnddir=$LND_DIR")
135
+ if [ -n "$RPCSERVER" ]; then
136
+ LNCLI_CMD+=("--rpcserver=$RPCSERVER")
137
+ elif [ -n "$RPC_PORT" ]; then
138
+ LNCLI_CMD+=("--rpcserver=localhost:$RPC_PORT")
139
+ fi
140
+ if [ -n "$TLSCERTPATH" ]; then
141
+ LNCLI_CMD+=("--tlscertpath=$TLSCERTPATH")
142
+ fi
143
+ if [ -n "$MACAROONPATH" ]; then
144
+ LNCLI_CMD+=("--macaroonpath=$MACAROONPATH")
145
+ fi
146
+
147
+ # Verify lncli is available.
148
+ if [ -n "$CONTAINER" ]; then
149
+ if ! docker exec "$CONTAINER" which lncli &>/dev/null; then
150
+ echo "Error: lncli not found in container '$CONTAINER'." >&2
151
+ exit 1
152
+ fi
153
+ elif ! command -v lncli &>/dev/null; then
154
+ echo "Error: lncli not found. Run the lnd skill's install.sh first." >&2
155
+ exit 1
156
+ fi
157
+
158
+ # --- Inspect mode ---
159
+ if [ -n "$INSPECT" ]; then
160
+ if [ -n "$CONTAINER" ]; then
161
+ # The macaroon may be on the host or inside the container. If it
162
+ # exists on the host, copy it into the container for inspection.
163
+ if [ -f "$INSPECT" ]; then
164
+ CONTAINER_TMP="/tmp/inspect-$(date +%s).macaroon"
165
+ docker cp "$INSPECT" "$CONTAINER:$CONTAINER_TMP"
166
+ INSPECT_PATH="$CONTAINER_TMP"
167
+ elif docker exec "$CONTAINER" test -f "$INSPECT" 2>/dev/null; then
168
+ INSPECT_PATH="$INSPECT"
169
+ else
170
+ echo "Error: Macaroon file not found: $INSPECT" >&2
171
+ exit 1
172
+ fi
173
+ elif [ ! -f "$INSPECT" ]; then
174
+ echo "Error: Macaroon file not found: $INSPECT" >&2
175
+ exit 1
176
+ else
177
+ INSPECT_PATH="$INSPECT"
178
+ fi
179
+ echo "=== Macaroon: $(basename "$INSPECT") ==="
180
+ echo "Path: $INSPECT"
181
+ if [ -n "$CONTAINER" ]; then
182
+ echo "Container: $CONTAINER"
183
+ fi
184
+ echo ""
185
+ "${LNCLI_CMD[@]}" printmacaroon --macaroon_file "$INSPECT_PATH"
186
+ # Clean up temporary copy if we created one.
187
+ if [ -n "$CONTAINER" ] && [ -f "$INSPECT" ]; then
188
+ docker exec "$CONTAINER" rm -f "$INSPECT_PATH" 2>/dev/null || true
189
+ fi
190
+ exit 0
191
+ fi
192
+
193
+ # --- List permissions mode ---
194
+ if [ "$LIST_PERMS" = true ]; then
195
+ echo "=== Available Macaroon Permissions ==="
196
+ echo ""
197
+ "${LNCLI_CMD[@]}" listpermissions | jq -r '.method_permissions | to_entries[] | .key' | sort
198
+ exit 0
199
+ fi
200
+
201
+ # --- Bake mode ---
202
+
203
+ # Resolve permissions from role or custom.
204
+ PERMS=()
205
+
206
+ if [ -n "$ROLE" ]; then
207
+ case $ROLE in
208
+ pay-only)
209
+ PERMS=(
210
+ "uri:/lnrpc.Lightning/SendPaymentSync"
211
+ "uri:/routerrpc.Router/SendPaymentV2"
212
+ "uri:/lnrpc.Lightning/DecodePayReq"
213
+ "uri:/lnrpc.Lightning/GetInfo"
214
+ )
215
+ ;;
216
+ invoice-only)
217
+ PERMS=(
218
+ "uri:/lnrpc.Lightning/AddInvoice"
219
+ "uri:/invoicesrpc.Invoices/AddHoldInvoice"
220
+ "uri:/lnrpc.Lightning/LookupInvoice"
221
+ "uri:/lnrpc.Lightning/ListInvoices"
222
+ "uri:/lnrpc.Lightning/GetInfo"
223
+ )
224
+ ;;
225
+ read-only)
226
+ PERMS=(
227
+ "uri:/lnrpc.Lightning/GetInfo"
228
+ "uri:/lnrpc.Lightning/WalletBalance"
229
+ "uri:/lnrpc.Lightning/ChannelBalance"
230
+ "uri:/lnrpc.Lightning/ListChannels"
231
+ "uri:/lnrpc.Lightning/ListPeers"
232
+ "uri:/lnrpc.Lightning/ListPayments"
233
+ "uri:/lnrpc.Lightning/ListInvoices"
234
+ "uri:/lnrpc.Lightning/GetNodeInfo"
235
+ "uri:/lnrpc.Lightning/GetChanInfo"
236
+ )
237
+ ;;
238
+ channel-admin)
239
+ PERMS=(
240
+ "uri:/lnrpc.Lightning/GetInfo"
241
+ "uri:/lnrpc.Lightning/WalletBalance"
242
+ "uri:/lnrpc.Lightning/ChannelBalance"
243
+ "uri:/lnrpc.Lightning/ListChannels"
244
+ "uri:/lnrpc.Lightning/ListPeers"
245
+ "uri:/lnrpc.Lightning/ConnectPeer"
246
+ "uri:/lnrpc.Lightning/DisconnectPeer"
247
+ "uri:/lnrpc.Lightning/OpenChannelSync"
248
+ "uri:/lnrpc.Lightning/CloseChannel"
249
+ "uri:/lnrpc.Lightning/ClosedChannels"
250
+ "uri:/lnrpc.Lightning/GetNodeInfo"
251
+ "uri:/lnrpc.Lightning/GetChanInfo"
252
+ )
253
+ ;;
254
+ signer-only)
255
+ PERMS=(
256
+ "uri:/signrpc.Signer/SignOutputRaw"
257
+ "uri:/signrpc.Signer/ComputeInputScript"
258
+ "uri:/signrpc.Signer/MuSig2Sign"
259
+ "uri:/signrpc.Signer/MuSig2Cleanup"
260
+ "uri:/signrpc.Signer/MuSig2CreateSession"
261
+ "uri:/signrpc.Signer/MuSig2RegisterNonces"
262
+ "uri:/signrpc.Signer/MuSig2CombineSig"
263
+ "uri:/walletrpc.WalletKit/DeriveKey"
264
+ "uri:/walletrpc.WalletKit/DeriveNextKey"
265
+ "uri:/lnrpc.Lightning/GetInfo"
266
+ )
267
+ ;;
268
+ *)
269
+ echo "Error: Unknown role '$ROLE'." >&2
270
+ echo "Available roles: pay-only, invoice-only, read-only, channel-admin, signer-only" >&2
271
+ exit 1
272
+ ;;
273
+ esac
274
+ elif [ ${#CUSTOM_PERMS[@]} -gt 0 ]; then
275
+ PERMS=("${CUSTOM_PERMS[@]}")
276
+ else
277
+ echo "Error: Specify --role, --custom, --inspect, or --list-permissions." >&2
278
+ echo "Run bake.sh --help for usage." >&2
279
+ exit 1
280
+ fi
281
+
282
+ # Determine output path.
283
+ if [ -z "$SAVE_TO" ]; then
284
+ if [ -n "$CONTAINER" ] || [ -n "$RPCSERVER" ]; then
285
+ # Container/remote mode: save locally, not inside the container or on the remote.
286
+ MACAROON_DIR="$HOME/.lnget/macaroons"
287
+ else
288
+ MACAROON_DIR="$LND_DIR/data/chain/bitcoin/$NETWORK"
289
+ fi
290
+ if [ -n "$ROLE" ]; then
291
+ SAVE_TO="$MACAROON_DIR/${ROLE}.macaroon"
292
+ else
293
+ SAVE_TO="$MACAROON_DIR/custom-$(date +%s).macaroon"
294
+ fi
295
+ fi
296
+
297
+ # Ensure output directory exists.
298
+ mkdir -p "$(dirname "$SAVE_TO")"
299
+
300
+ echo "=== Baking Macaroon ==="
301
+ if [ -n "$ROLE" ]; then
302
+ echo "Role: $ROLE"
303
+ fi
304
+ echo "Permissions: ${#PERMS[@]}"
305
+ echo "Output: $SAVE_TO"
306
+ echo ""
307
+
308
+ # Bake the macaroon.
309
+ if [ -n "$CONTAINER" ]; then
310
+ # Bake inside container, then copy out to local path.
311
+ CONTAINER_TMP="/tmp/baked-$(date +%s).macaroon"
312
+ "${LNCLI_CMD[@]}" bakemacaroon "${PERMS[@]}" --save_to="$CONTAINER_TMP"
313
+ docker cp "$CONTAINER:$CONTAINER_TMP" "$SAVE_TO"
314
+ docker exec "$CONTAINER" rm -f "$CONTAINER_TMP"
315
+ else
316
+ "${LNCLI_CMD[@]}" bakemacaroon "${PERMS[@]}" --save_to="$SAVE_TO"
317
+ fi
318
+
319
+ # Set restrictive permissions.
320
+ chmod 600 "$SAVE_TO"
321
+
322
+ echo ""
323
+ echo "=== Macaroon Baked ==="
324
+ echo "Saved to: $SAVE_TO (mode 0600)"
325
+ echo ""
326
+ echo "Permissions granted:"
327
+ for p in "${PERMS[@]}"; do
328
+ echo " $p"
329
+ done
330
+ echo ""
331
+ echo "To verify:"
332
+ echo " bake.sh --inspect $SAVE_TO"
333
+ echo ""
334
+ echo "To use with lnget:"
335
+ echo " ln:"
336
+ echo " lnd:"
337
+ echo " macaroon: $SAVE_TO"
@@ -0,0 +1,280 @@
1
+ ---
2
+ name: mcp-lnc
3
+ description: Build and configure the MCP server for Lightning Node Connect (LNC). Connects AI assistants to lnd nodes via encrypted WebSocket tunnels using pairing phrases — no direct network access or TLS certs needed. Read-only by default (18 tools for querying node state, channels, payments, invoices, peers, on-chain data).
4
+ ---
5
+
6
+ # MCP LNC Server
7
+
8
+ Build and configure the MCP server that connects AI assistants to Lightning
9
+ nodes via **Lightning Node Connect (LNC)**. LNC uses encrypted WebSocket tunnels
10
+ through a mailbox relay, so the agent never needs direct gRPC access, TLS
11
+ certificates, or macaroons — just a 10-word pairing phrase from Lightning
12
+ Terminal.
13
+
14
+ The MCP server is **read-only by default** — it exposes 18 tools for querying
15
+ node state but cannot send payments or modify channels.
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # 1. Build the MCP server binary
21
+ skills/mcp-lnc/scripts/install.sh
22
+
23
+ # 2. Configure environment (mailbox server, dev mode, etc.)
24
+ skills/mcp-lnc/scripts/configure.sh
25
+
26
+ # 3. Add to Claude Code as an MCP server
27
+ skills/mcp-lnc/scripts/setup-claude-config.sh
28
+ ```
29
+
30
+ Then restart Claude Code. The `lnc_connect` tool will be available to connect
31
+ to any lnd node using a pairing phrase.
32
+
33
+ ## How It Works
34
+
35
+ ```
36
+ Claude Code <--stdio--> mcp-lnc-server <--LNC WebSocket--> Mailbox <--> lnd
37
+ ```
38
+
39
+ 1. Claude Code launches `mcp-lnc-server` as a subprocess (stdio transport)
40
+ 2. Agent calls `lnc_connect` with a pairing phrase and password
41
+ 3. Server generates an ephemeral ECDSA keypair and opens an encrypted WebSocket
42
+ tunnel through the mailbox relay
43
+ 4. Once connected, the agent can call any of the 18 read-only tools
44
+ 5. `lnc_disconnect` closes the tunnel
45
+
46
+ No keys, certs, or macaroons are stored on disk — the pairing phrase is the
47
+ only credential, and it's handled in-memory only.
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ # Build from source (requires Go 1.24+)
53
+ skills/mcp-lnc/scripts/install.sh
54
+
55
+ # Verify
56
+ mcp-lnc-server -version
57
+ ```
58
+
59
+ The install script builds from the `mcp-server/` directory in this repo.
60
+
61
+ ## Configuration
62
+
63
+ ```bash
64
+ # Generate .env with defaults
65
+ skills/mcp-lnc/scripts/configure.sh
66
+
67
+ # Production (mainnet via Lightning Terminal)
68
+ skills/mcp-lnc/scripts/configure.sh --production
69
+
70
+ # Development (local regtest)
71
+ skills/mcp-lnc/scripts/configure.sh --dev --mailbox aperture:11110
72
+ ```
73
+
74
+ Configuration is stored in `mcp-server/.env`. Key settings:
75
+
76
+ | Variable | Default | Description |
77
+ |----------|---------|-------------|
78
+ | `LNC_MAILBOX_SERVER` | `mailbox.terminal.lightning.today:443` | Mailbox relay server |
79
+ | `LNC_DEV_MODE` | `false` | Enable development mode |
80
+ | `LNC_INSECURE` | `false` | Skip TLS verification (dev only) |
81
+ | `LNC_CONNECT_TIMEOUT` | `30` | Connection timeout in seconds |
82
+
83
+ ## Claude Code Integration
84
+
85
+ ### Option 1: `claude mcp add` (recommended)
86
+
87
+ Register the MCP server with a single command — no build step required:
88
+
89
+ ```bash
90
+ # Zero-install via npx (downloads pre-built binary)
91
+ claude mcp add --transport stdio lnc -- npx -y @lightninglabs/lightning-mcp-server
92
+
93
+ # With environment variables for production
94
+ claude mcp add --transport stdio \
95
+ --env LNC_MAILBOX_SERVER=mailbox.terminal.lightning.today:443 \
96
+ lnc -- npx -y @lightninglabs/lightning-mcp-server
97
+
98
+ # For development/regtest
99
+ claude mcp add --transport stdio \
100
+ --env LNC_MAILBOX_SERVER=localhost:11110 \
101
+ --env LNC_DEV_MODE=true \
102
+ --env LNC_INSECURE=true \
103
+ lnc -- npx -y @lightninglabs/lightning-mcp-server
104
+ ```
105
+
106
+ Scope options: `--scope local` (default, just you), `--scope project` (shared
107
+ via `.mcp.json`), `--scope user` (all your projects).
108
+
109
+ ### Option 2: Setup script (from source)
110
+
111
+ ```bash
112
+ # Add mcp-lnc-server to Claude Code's MCP config
113
+ skills/mcp-lnc/scripts/setup-claude-config.sh
114
+
115
+ # Project-level config (current project only)
116
+ skills/mcp-lnc/scripts/setup-claude-config.sh --scope project
117
+
118
+ # Global config (all projects)
119
+ skills/mcp-lnc/scripts/setup-claude-config.sh --scope global
120
+ ```
121
+
122
+ This adds the server to Claude Code's `.mcp.json` (project) or
123
+ `~/.claude.json` (global) configuration. After restarting Claude Code, the
124
+ LNC tools will be available.
125
+
126
+ ### Option 3: Manual configuration
127
+
128
+ Add to `.mcp.json` in your project root:
129
+
130
+ ```json
131
+ {
132
+ "mcpServers": {
133
+ "lnc": {
134
+ "command": "npx",
135
+ "args": ["-y", "@lightninglabs/lightning-mcp-server"],
136
+ "env": {
137
+ "LNC_MAILBOX_SERVER": "mailbox.terminal.lightning.today:443"
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ Or with a locally built binary:
145
+
146
+ ```json
147
+ {
148
+ "mcpServers": {
149
+ "lnc": {
150
+ "command": "mcp-lnc-server",
151
+ "env": {
152
+ "LNC_MAILBOX_SERVER": "mailbox.terminal.lightning.today:443"
153
+ }
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ Or run via Docker:
160
+
161
+ ```json
162
+ {
163
+ "mcpServers": {
164
+ "lnc": {
165
+ "command": "docker",
166
+ "args": [
167
+ "run", "--rm", "-i", "--network", "host",
168
+ "--env", "LNC_MAILBOX_SERVER",
169
+ "--env", "LNC_DEV_MODE",
170
+ "--env", "LNC_INSECURE",
171
+ "mcp-lnc-server"
172
+ ]
173
+ }
174
+ }
175
+ }
176
+ ```
177
+
178
+ ## Available Tools (18)
179
+
180
+ ### Connection
181
+
182
+ | Tool | Description |
183
+ |------|-------------|
184
+ | `lnc_connect` | Connect to lnd via LNC pairing phrase |
185
+ | `lnc_disconnect` | Close active LNC connection |
186
+
187
+ ### Node
188
+
189
+ | Tool | Description |
190
+ |------|-------------|
191
+ | `lnc_get_info` | Node alias, version, sync status, block height |
192
+ | `lnc_get_balance` | Wallet balance (on-chain) and channel balance |
193
+
194
+ ### Channels
195
+
196
+ | Tool | Description |
197
+ |------|-------------|
198
+ | `lnc_list_channels` | Active/inactive channels with capacity, balances |
199
+ | `lnc_pending_channels` | Channels being opened or closed |
200
+
201
+ ### Invoices
202
+
203
+ | Tool | Description |
204
+ |------|-------------|
205
+ | `lnc_decode_invoice` | Decode a BOLT11 invoice |
206
+ | `lnc_list_invoices` | List invoices with pagination |
207
+ | `lnc_lookup_invoice` | Look up invoice by payment hash |
208
+
209
+ ### Payments
210
+
211
+ | Tool | Description |
212
+ |------|-------------|
213
+ | `lnc_list_payments` | Payment history with pagination |
214
+ | `lnc_track_payment` | Track specific payment by hash |
215
+
216
+ ### Peers & Network
217
+
218
+ | Tool | Description |
219
+ |------|-------------|
220
+ | `lnc_list_peers` | Connected peers with stats |
221
+ | `lnc_describe_graph` | Lightning Network topology sample |
222
+ | `lnc_get_node_info` | Detailed info about a specific node |
223
+
224
+ ### On-Chain
225
+
226
+ | Tool | Description |
227
+ |------|-------------|
228
+ | `lnc_list_unspent` | UTXOs with confirmations |
229
+ | `lnc_get_transactions` | On-chain transaction history |
230
+ | `lnc_estimate_fee` | Fee estimates for confirmation targets |
231
+
232
+ ## Security Model
233
+
234
+ - **No stored credentials:** Pairing phrase is handled in-memory only. Ephemeral
235
+ ECDSA keypairs are generated per session.
236
+ - **Read-only:** No payment, channel, or state-changing operations are exposed.
237
+ The agent can observe but not modify.
238
+ - **Encrypted tunnels:** All traffic is encrypted end-to-end through the mailbox
239
+ relay. The mailbox cannot read the traffic.
240
+ - **No direct access:** The agent machine never connects directly to the lnd
241
+ node's gRPC port — all traffic goes through the mailbox.
242
+
243
+ ### Comparison with Direct gRPC Access
244
+
245
+ | | MCP LNC Server | Direct lncli/gRPC |
246
+ |---|---|---|
247
+ | **Credential** | Pairing phrase (in-memory) | TLS cert + macaroon (on disk) |
248
+ | **Network** | WebSocket via mailbox relay | Direct TCP to gRPC port |
249
+ | **Firewall** | No inbound ports needed | Port 10009 must be reachable |
250
+ | **Permissions** | Read-only (hardcoded) | Depends on macaroon scope |
251
+ | **Setup** | Pairing phrase from Lightning Terminal | Export cert + macaroon files |
252
+
253
+ ## Prerequisites
254
+
255
+ - **Go 1.24+** for building from source
256
+ - **Lightning Terminal (litd)** on the target node for generating pairing phrases
257
+ - **Claude Code** for MCP integration
258
+
259
+ ## Troubleshooting
260
+
261
+ ### "pairing phrase must be exactly 10 words"
262
+ The pairing phrase is generated by Lightning Terminal. It must be exactly 10
263
+ space-separated words.
264
+
265
+ ### "connection timeout"
266
+ Check that the mailbox server is reachable. For production, ensure
267
+ `mailbox.terminal.lightning.today:443` is not blocked by a firewall.
268
+
269
+ ### "TLS handshake failure"
270
+ If using a local regtest setup, enable dev mode and insecure mode:
271
+ ```bash
272
+ skills/mcp-lnc/scripts/configure.sh --dev --insecure
273
+ ```
274
+
275
+ ### Tools not appearing in Claude Code
276
+ Restart Claude Code after running `setup-claude-config.sh`. Check that
277
+ `mcp-lnc-server` is on your `$PATH`:
278
+ ```bash
279
+ which mcp-lnc-server
280
+ ```