|
1 | 1 | import { PokeTunnel, getToken } from "poke"; |
| 2 | +import { readFileSync, writeFileSync, mkdirSync } from "node:fs"; |
| 3 | +import { join } from "node:path"; |
| 4 | +import { homedir } from "node:os"; |
| 5 | + |
| 6 | +const CONFIG_DIR = process.env.XDG_CONFIG_HOME || join(homedir(), ".config"); |
| 7 | +const STATE_PATH = join(CONFIG_DIR, "poke-gate", "state.json"); |
| 8 | + |
| 9 | +function loadState() { |
| 10 | + try { |
| 11 | + return JSON.parse(readFileSync(STATE_PATH, "utf-8")); |
| 12 | + } catch { |
| 13 | + return {}; |
| 14 | + } |
| 15 | +} |
| 16 | + |
| 17 | +function saveState(state) { |
| 18 | + mkdirSync(join(CONFIG_DIR, "poke-gate"), { recursive: true }); |
| 19 | + writeFileSync(STATE_PATH, JSON.stringify(state, null, 2)); |
| 20 | +} |
| 21 | + |
| 22 | +async function cleanupOldConnection(apiKey) { |
| 23 | + const state = loadState(); |
| 24 | + if (!state.connectionId) return; |
| 25 | + |
| 26 | + const token = getToken() || apiKey; |
| 27 | + const base = process.env.POKE_API ?? "https://poke.com/api/v1"; |
| 28 | + |
| 29 | + try { |
| 30 | + await fetch(`${base}/mcp/connections/${state.connectionId}`, { |
| 31 | + method: "DELETE", |
| 32 | + headers: { Authorization: `Bearer ${token}` }, |
| 33 | + }); |
| 34 | + } catch {} |
| 35 | +} |
2 | 36 |
|
3 | 37 | export async function startTunnel({ apiKey, mcpUrl, onEvent }) { |
| 38 | + await cleanupOldConnection(apiKey); |
| 39 | + |
4 | 40 | const token = getToken(); |
5 | 41 |
|
6 | 42 | const tunnel = new PokeTunnel({ |
7 | 43 | url: mcpUrl, |
8 | 44 | name: "poke-gate", |
9 | 45 | token: token || apiKey, |
| 46 | + cleanupOnStop: false, |
10 | 47 | }); |
11 | 48 |
|
12 | | - tunnel.on("connected", (info) => onEvent("connected", info)); |
| 49 | + tunnel.on("connected", (info) => { |
| 50 | + saveState({ connectionId: info.connectionId }); |
| 51 | + onEvent("connected", info); |
| 52 | + }); |
13 | 53 | tunnel.on("disconnected", () => onEvent("disconnected")); |
14 | 54 | tunnel.on("error", (err) => onEvent("error", err.message)); |
15 | 55 | tunnel.on("toolsSynced", ({ toolCount }) => onEvent("tools-synced", toolCount)); |
|
0 commit comments