Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ export default defineConfig([
},
{ files: ["src/**/*.{js,mjs,cjs,ts}"], languageOptions: { globals: globals.node } },
tseslint.configs.recommended,
{
rules: {
"@typescript-eslint/no-explicit-any": 0,
}
}
]);
70 changes: 33 additions & 37 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "phoenixd-mcp-server",
"version": "1.0.1",
"version": "1.0.2",
"description": "Connect a phoenixd bitcoin lightning wallet to your LLM.",
"keywords": [
"phoenixd",
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Add this to your `claude_desktop_config.json` file:
],
"env": {
"HTTP_PROTOCOL": "<http or https>", // If not set http is the default value.
"HTTP_HOST": "<your_host>", // 127.0.0.1 or your-domain.com
"HTTP_HOST": "<your_host>", // If not set 127.0.0.1 is the default host.
"HTTP_PORT": "<your_phoenixd_port>", // If not set 9740 is the default port.
"HTTP_PASSWORD": "<phoenixd_http_password>"
}
Expand Down
59 changes: 19 additions & 40 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,37 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

import { registerGetBalanceTool } from './tools/get_balance.js';
import { registerGetNodeInfoTool } from './tools/get_node_info.js';
import { registerListChannelsTool } from './tools/list_channels.js';
import { registerCloseChannelTool } from './tools/close_channel.js';
import { registerDecodeInvoiceTool } from './tools/decode_invoice.js';
import { registerDecodeOfferTool } from './tools/decode_offer.js';
import { registerCreateInvoiceTool } from './tools/create_invoice.js';
import { registerPayInvoiceTool } from './tools/pay_invoice.js';
import { registerCreateOfferTool } from './tools/create_offer.js';
import { registerPayOfferTool } from './tools/pay_offer.js';
import { registerPayLightningAddressTool } from './tools/pay_lightning_address.js';
import { registerPayOnChainTool } from './tools/pay_on_chain.js';
import { registerBumpFeeTool } from './tools/bump_fee.js';
import { registerListIncomingPaymentsTool } from './tools/list_incoming_payments.js';
import { registerGetIncomingPaymentTool } from './tools/get_incoming_payment.js';
import { registerListOutgoingPaymentsTool } from './tools/list_outgoing_payments.js';
import { registerGetOutgoingPaymentTool } from './tools/get_outgoing_payment.js';
import { tools } from './tools/index.js';

const config = {
httpPassword: process.env.HTTP_PASSWORD || '',
httpPort: process.env.HTTP_PORT || '9740',
httpHost: process.env.HTTP_HOST || '',
httpHost: process.env.HTTP_HOST || '127.0.0.1',
httpProtocol: process.env.HTTP_PROTOCOL || 'http',
};

if (!process.env.HTTP_PASSWORD || !process.env.HTTP_HOST) {
console.error('HTTP_PASSWORD and HTTP_HOST are required but not set in the environment variables.');
process.exit(1);
}

const server = new McpServer({
name: 'phoenixd-mcp-server',
version: '1.0.1',
});

await registerGetBalanceTool(server, config);
await registerGetNodeInfoTool(server, config);
await registerListChannelsTool(server, config);
await registerCloseChannelTool(server, config);
await registerDecodeInvoiceTool(server, config);
await registerDecodeOfferTool(server, config);
await registerCreateInvoiceTool(server, config);
await registerPayInvoiceTool(server, config);
await registerCreateOfferTool(server, config);
await registerPayOfferTool(server, config);
await registerPayLightningAddressTool(server, config);
await registerPayOnChainTool(server, config);
await registerBumpFeeTool(server, config);
await registerListIncomingPaymentsTool(server, config);
await registerGetIncomingPaymentTool(server, config);
await registerListOutgoingPaymentsTool(server, config);
await registerGetOutgoingPaymentTool(server, config);
await tools.registerGetBalanceTool(server, config);
await tools.registerGetNodeInfoTool(server, config);
await tools.registerListChannelsTool(server, config);
await tools.registerCloseChannelTool(server, config);
await tools.registerDecodeInvoiceTool(server, config);
await tools.registerDecodeOfferTool(server, config);
await tools.registerCreateInvoiceTool(server, config);
await tools.registerPayInvoiceTool(server, config);
await tools.registerCreateOfferTool(server, config);
await tools.registerPayOfferTool(server, config);
await tools.registerPayLightningAddressTool(server, config);
await tools.registerPayOnChainTool(server, config);
await tools.registerBumpFeeTool(server, config);
await tools.registerListIncomingPaymentsTool(server, config);
await tools.registerGetIncomingPaymentTool(server, config);
await tools.registerListOutgoingPaymentsTool(server, config);
await tools.registerGetOutgoingPaymentTool(server, config);

const transport = new StdioServerTransport();
await server.connect(transport);
2 changes: 2 additions & 0 deletions src/tools/bump_fee.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { PhoenixdMcpConfig } from '../types';
import { validateEnv } from '../utils/validate_env.js';

export function registerBumpFeeTool(
server: McpServer,
Expand All @@ -13,6 +14,7 @@ export function registerBumpFeeTool(
feerateSatByte: z.number().describe('The fee rate in satoshis per byte'),
},
async ({ feerateSatByte }) => {
validateEnv(config);
const credentials = btoa(`:${config.httpPassword}`);
const params = new URLSearchParams({
feerateSatByte: feerateSatByte.toString(),
Expand Down
2 changes: 2 additions & 0 deletions src/tools/close_channel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { PhoenixdMcpConfig } from '../types';
import { validateEnv } from '../utils/validate_env.js';

export function registerCloseChannelTool(
server: McpServer,
Expand All @@ -15,6 +16,7 @@ export function registerCloseChannelTool(
feerateSatByte: z.number().describe('The fee rate in satoshis per byte'),
},
async ({ channelId, address, feerateSatByte }) => {
validateEnv(config);
const credentials = btoa(`:${config.httpPassword}`);
const params = new URLSearchParams({
channelId,
Expand Down
2 changes: 2 additions & 0 deletions src/tools/create_invoice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { PhoenixdMcpConfig } from '../types';
import { validateEnv } from '../utils/validate_env.js';

export function registerCreateInvoiceTool(
server: McpServer,
Expand All @@ -18,6 +19,7 @@ export function registerCreateInvoiceTool(
webhookUrl: z.string().optional().describe('A webhook url that will be notified when this specific payment has been received. '),
},
async ({ description, amountSat, expirySeconds, externalId, webhookUrl }) => {
validateEnv(config);
const credentials = btoa(`:${config.httpPassword}`);
const paramsObj: Record<string, string> = {
description,
Expand Down
2 changes: 2 additions & 0 deletions src/tools/create_offer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { PhoenixdMcpConfig } from '../types';
import { validateEnv } from '../utils/validate_env.js';

export function registerCreateOfferTool(
server: McpServer,
Expand All @@ -14,6 +15,7 @@ export function registerCreateOfferTool(
amountSat: z.number().optional().describe('The amount requested by the offer, in satoshi. If not set, the offer can be paid by any amount'),
},
async ({ description, amountSat }) => {
validateEnv(config);
const credentials = btoa(`:${config.httpPassword}`);
const paramsObj: Record<string, string> = {};

Expand Down
2 changes: 2 additions & 0 deletions src/tools/decode_invoice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { PhoenixdMcpConfig } from '../types';
import { validateEnv } from '../utils/validate_env.js';

export function registerDecodeInvoiceTool(
server: McpServer,
Expand All @@ -13,6 +14,7 @@ export function registerDecodeInvoiceTool(
invoice: z.string().describe('The bolt11 invoice to decode'),
},
async ({ invoice }) => {
validateEnv(config);
const credentials = btoa(`:${config.httpPassword}`);
const params = new URLSearchParams({
invoice,
Expand Down
Loading