@willjackson/claude-code-bridge 0.3.0 → 0.4.1

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.
package/README.md CHANGED
@@ -62,13 +62,15 @@ Claude Code Bridge connects two Claude Code instances running on different machi
62
62
  ### Global Installation (Recommended)
63
63
 
64
64
  ```bash
65
- npm install -g claude-code-bridge
65
+ npm install -g @willjackson/claude-code-bridge
66
66
  ```
67
67
 
68
+ After installation, the `claude-bridge` command will be available globally.
69
+
68
70
  ### Run Without Installing
69
71
 
70
72
  ```bash
71
- npx claude-code-bridge start
73
+ npx @willjackson/claude-code-bridge start
72
74
  ```
73
75
 
74
76
  ### Install from Source
@@ -91,25 +93,25 @@ npm link # Makes 'claude-bridge' available globally
91
93
  claude-bridge start --port 8766
92
94
  ```
93
95
 
94
- **Step 2: Start the bridge in your container and connect**
96
+ **Step 2: Start the bridge on the remote machine and connect**
95
97
 
96
98
  ```bash
97
- # Inside the container (Docksal, DDEV, or Docker)
98
- claude-bridge start --port 8765 --connect ws://host.docker.internal:8766
99
+ # On remote machine (replace MACHINE_A_IP with actual IP)
100
+ claude-bridge start --port 8765 --connect ws://MACHINE_A_IP:8766
99
101
  ```
100
102
 
101
103
  ### Scenario 2: Peer-to-Peer Mode
102
104
 
103
105
  Both instances can initiate communication:
104
106
 
105
- **Terminal 1 (Mac):**
107
+ **Machine A:**
106
108
  ```bash
107
109
  claude-bridge start --port 8766
108
110
  ```
109
111
 
110
- **Terminal 2 (Container):**
112
+ **Machine B:**
111
113
  ```bash
112
- claude-bridge start --port 8765 --connect ws://host.docker.internal:8766
114
+ claude-bridge start --port 8765 --connect ws://MACHINE_A_IP:8766
113
115
  ```
114
116
 
115
117
  Once connected, either side can send context or delegate tasks to the other.
@@ -118,17 +120,17 @@ Once connected, either side can send context or delegate tasks to the other.
118
120
 
119
121
  Enable file operations on the remote to allow reading, writing, and deleting files:
120
122
 
121
- **Terminal 1 (Mac - relay mode, no handlers):**
123
+ **Machine A (relay mode, no handlers):**
122
124
  ```bash
123
125
  claude-bridge start --port 8766
124
126
  ```
125
127
 
126
- **Terminal 2 (Container - with file handlers):**
128
+ **Machine B (with file handlers):**
127
129
  ```bash
128
- claude-bridge start --with-handlers --connect ws://host.docker.internal:8766
130
+ claude-bridge start --with-handlers --connect ws://MACHINE_A_IP:8766
129
131
  ```
130
132
 
131
- Now you can read, write, and edit files on the remote container from your Mac.
133
+ Now you can read, write, and edit files on Machine B from Machine A.
132
134
 
133
135
  ## CLI Reference
134
136
 
@@ -175,9 +177,65 @@ claude-bridge start --connect ws://192.168.1.100:8765
175
177
  claude-bridge start --daemon
176
178
 
177
179
  # Start with file operation handlers enabled
178
- claude-bridge start --with-handlers --connect ws://host.docker.internal:8766
180
+ claude-bridge start --with-handlers --connect ws://192.168.1.100:8766
181
+ ```
182
+
183
+ ### Daemon Mode
184
+
185
+ Daemon mode runs the bridge as a background process, allowing you to close your terminal while the bridge continues running.
186
+
187
+ #### Starting in Daemon Mode
188
+
189
+ ```bash
190
+ # Start bridge in background
191
+ claude-bridge start --daemon
192
+
193
+ # Start with additional options
194
+ claude-bridge start --daemon --port 8766 --with-handlers
195
+
196
+ # Start daemon and connect to remote
197
+ claude-bridge start --daemon --connect ws://192.168.1.100:8765
198
+ ```
199
+
200
+ When started in daemon mode, the bridge:
201
+ - Detaches from the terminal and runs in the background
202
+ - Writes its PID and status to `~/.claude-bridge/status.json`
203
+ - Continues running until explicitly stopped
204
+
205
+ #### Checking Daemon Status
206
+
207
+ ```bash
208
+ claude-bridge status
209
+ ```
210
+
211
+ This shows whether a daemon is running, its PID, listening port, and connected peers.
212
+
213
+ #### Stopping the Daemon
214
+
215
+ ```bash
216
+ claude-bridge stop
217
+ ```
218
+
219
+ This reads the PID from the status file and gracefully shuts down the background process.
220
+
221
+ #### Status File
222
+
223
+ The daemon writes its status to `~/.claude-bridge/status.json`:
224
+
225
+ ```json
226
+ {
227
+ "running": true,
228
+ "pid": 12345,
229
+ "port": 8766,
230
+ "host": "0.0.0.0",
231
+ "instanceName": "bridge-12345",
232
+ "startedAt": "2024-01-15T10:30:00.000Z",
233
+ "peers": []
234
+ }
179
235
  ```
180
236
 
237
+ This file is automatically removed when the daemon stops cleanly.
238
+
181
239
  #### `stop` - Stop the Running Bridge
182
240
 
183
241
  ```bash
@@ -213,7 +271,7 @@ Arguments:
213
271
 
214
272
  ```bash
215
273
  claude-bridge connect ws://localhost:8765
216
- claude-bridge connect ws://host.docker.internal:8766
274
+ claude-bridge connect ws://192.168.1.100:8766
217
275
  ```
218
276
 
219
277
  #### `info` - Show System Information
@@ -251,7 +309,6 @@ listen:
251
309
  # Connection to remote bridge
252
310
  connect:
253
311
  url: ws://localhost:8765
254
- hostGateway: true # Use host.docker.internal
255
312
 
256
313
  # Context sharing settings
257
314
  contextSharing:
@@ -283,7 +340,6 @@ interaction:
283
340
  | `listen.port` | number | 8765 | Port to listen on |
284
341
  | `listen.host` | string | 0.0.0.0 | Host to bind to |
285
342
  | `connect.url` | string | - | WebSocket URL of remote bridge |
286
- | `connect.hostGateway` | boolean | false | Use `host.docker.internal` |
287
343
  | `contextSharing.autoSync` | boolean | true | Automatically sync context |
288
344
  | `contextSharing.syncInterval` | number | 5000 | Sync interval in ms |
289
345
  | `contextSharing.maxChunkTokens` | number | 4000 | Max tokens per context chunk |
@@ -461,20 +517,6 @@ await bridge.delegateTask({
461
517
 
462
518
  > **Security Note:** All file operations are restricted to the project directory where the bridge is running. Paths outside the project root are rejected.
463
519
 
464
- ### Environment Detection
465
-
466
- ```typescript
467
- import { detectEnvironment, getHostGateway } from 'claude-code-bridge';
468
-
469
- const env = detectEnvironment();
470
- console.log('Environment:', env.type); // 'native', 'docksal', 'ddev', 'lando', 'docker'
471
- console.log('Is Container:', env.isContainer);
472
- console.log('Project Name:', env.projectName);
473
-
474
- const gateway = getHostGateway();
475
- console.log('Host Gateway:', gateway); // 'host.docker.internal' or IP address
476
- ```
477
-
478
520
  ### Context Manager
479
521
 
480
522
  ```typescript
@@ -507,13 +549,13 @@ for (const change of delta.changes) {
507
549
 
508
550
  ### Connection Issues
509
551
 
510
- **Problem:** Cannot connect to bridge from container
552
+ **Problem:** Cannot connect to bridge from remote machine
511
553
 
512
554
  **Solutions:**
513
555
  1. Ensure the host bridge is running: `claude-bridge status`
514
556
  2. Check firewall settings allow the port
515
- 3. Verify `host.docker.internal` resolves: `ping host.docker.internal`
516
- 4. Try using the host IP directly: `claude-bridge connect ws://192.168.1.100:8766`
557
+ 3. Verify the IP address is correct and reachable: `ping MACHINE_IP`
558
+ 4. Try using the full URL: `claude-bridge connect ws://192.168.1.100:8766`
517
559
 
518
560
  **Problem:** Connection keeps dropping
519
561
 
@@ -621,12 +663,6 @@ npm test -- tests/unit/bridge/protocol.test.ts
621
663
  npm test -- --grep "WebSocket"
622
664
  ```
623
665
 
624
- ## Documentation
625
-
626
- - [CLAUDE.md](./CLAUDE.md) - Detailed project specification and architecture
627
- - [AGENTS.md](./AGENTS.md) - Guidelines for AI agents working on this codebase
628
- - [instructions.md](./instructions.md) - Development phases and testing strategy
629
-
630
666
  ## License
631
667
 
632
668
  MIT License - see [LICENSE](./LICENSE) for details.
@@ -1,7 +1,7 @@
1
1
  // src/utils/logger.ts
2
2
  import pino from "pino";
3
- function isDevelopment() {
4
- return process.env.NODE_ENV !== "production";
3
+ function usePrettyPrint() {
4
+ return process.env.NODE_ENV === "development";
5
5
  }
6
6
  function getDefaultLevel() {
7
7
  const envLevel = process.env.LOG_LEVEL?.toLowerCase();
@@ -17,7 +17,7 @@ function createLogger(name, level) {
17
17
  name,
18
18
  level: logLevel
19
19
  };
20
- if (isDevelopment()) {
20
+ if (usePrettyPrint()) {
21
21
  options.transport = {
22
22
  target: "pino-pretty",
23
23
  options: {
@@ -1717,6 +1717,406 @@ function loadConfigSync(configPath) {
1717
1717
  return { ...DEFAULT_CONFIG };
1718
1718
  }
1719
1719
 
1720
+ // src/mcp/tools.ts
1721
+ import { z as z2 } from "zod";
1722
+ var logger3 = createLogger("mcp:tools");
1723
+ var ReadFileInputSchema = z2.object({
1724
+ path: z2.string().describe("Path to the file to read")
1725
+ });
1726
+ var WriteFileInputSchema = z2.object({
1727
+ path: z2.string().describe("Path to the file to write"),
1728
+ content: z2.string().describe("Content to write to the file")
1729
+ });
1730
+ var DeleteFileInputSchema = z2.object({
1731
+ path: z2.string().describe("Path to the file to delete")
1732
+ });
1733
+ var ListDirectoryInputSchema = z2.object({
1734
+ path: z2.string().describe("Path to the directory to list")
1735
+ });
1736
+ var DelegateTaskInputSchema = z2.object({
1737
+ description: z2.string().describe("Description of the task to delegate"),
1738
+ scope: z2.enum(["execute", "analyze", "suggest"]).describe("Task scope"),
1739
+ data: z2.record(z2.unknown()).optional().describe("Additional task data")
1740
+ });
1741
+ var RequestContextInputSchema = z2.object({
1742
+ query: z2.string().describe("Query describing what files to retrieve")
1743
+ });
1744
+ var TOOL_DEFINITIONS = [
1745
+ {
1746
+ name: "bridge_read_file",
1747
+ description: "Read a file from the remote connected instance",
1748
+ inputSchema: ReadFileInputSchema
1749
+ },
1750
+ {
1751
+ name: "bridge_write_file",
1752
+ description: "Write a file to the remote connected instance",
1753
+ inputSchema: WriteFileInputSchema
1754
+ },
1755
+ {
1756
+ name: "bridge_delete_file",
1757
+ description: "Delete a file on the remote connected instance",
1758
+ inputSchema: DeleteFileInputSchema
1759
+ },
1760
+ {
1761
+ name: "bridge_list_directory",
1762
+ description: "List files and folders in a directory on the remote connected instance",
1763
+ inputSchema: ListDirectoryInputSchema
1764
+ },
1765
+ {
1766
+ name: "bridge_delegate_task",
1767
+ description: "Delegate a custom task to the remote connected instance",
1768
+ inputSchema: DelegateTaskInputSchema
1769
+ },
1770
+ {
1771
+ name: "bridge_request_context",
1772
+ description: "Request files matching a query from the remote connected instance",
1773
+ inputSchema: RequestContextInputSchema
1774
+ },
1775
+ {
1776
+ name: "bridge_status",
1777
+ description: "Get bridge status and connected peers",
1778
+ inputSchema: z2.object({})
1779
+ }
1780
+ ];
1781
+ function createToolHandlers(bridge) {
1782
+ const handlers = {};
1783
+ function errorResponse(message) {
1784
+ return {
1785
+ content: [{ type: "text", text: `Error: ${message}` }],
1786
+ isError: true
1787
+ };
1788
+ }
1789
+ function successResponse(text) {
1790
+ return {
1791
+ content: [{ type: "text", text }]
1792
+ };
1793
+ }
1794
+ async function delegateFileTask(action, data, description) {
1795
+ const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1796
+ return bridge.delegateTask({
1797
+ id: taskId,
1798
+ description,
1799
+ scope: "execute",
1800
+ data: { action, ...data }
1801
+ });
1802
+ }
1803
+ handlers["bridge_read_file"] = async (args) => {
1804
+ const input = ReadFileInputSchema.parse(args);
1805
+ logger3.debug({ path: input.path }, "Reading file");
1806
+ try {
1807
+ const result = await delegateFileTask(
1808
+ "read_file",
1809
+ { path: input.path },
1810
+ `Read file: ${input.path}`
1811
+ );
1812
+ if (!result.success) {
1813
+ return errorResponse(result.error || "Failed to read file");
1814
+ }
1815
+ return successResponse(result.data.content);
1816
+ } catch (err) {
1817
+ logger3.error({ error: err.message, path: input.path }, "Failed to read file");
1818
+ return errorResponse(err.message);
1819
+ }
1820
+ };
1821
+ handlers["bridge_write_file"] = async (args) => {
1822
+ const input = WriteFileInputSchema.parse(args);
1823
+ logger3.debug({ path: input.path, contentLength: input.content.length }, "Writing file");
1824
+ try {
1825
+ const result = await delegateFileTask(
1826
+ "write_file",
1827
+ { path: input.path, content: input.content },
1828
+ `Write file: ${input.path}`
1829
+ );
1830
+ if (!result.success) {
1831
+ return errorResponse(result.error || "Failed to write file");
1832
+ }
1833
+ return successResponse(`File written successfully: ${input.path} (${result.data.bytesWritten} bytes)`);
1834
+ } catch (err) {
1835
+ logger3.error({ error: err.message, path: input.path }, "Failed to write file");
1836
+ return errorResponse(err.message);
1837
+ }
1838
+ };
1839
+ handlers["bridge_delete_file"] = async (args) => {
1840
+ const input = DeleteFileInputSchema.parse(args);
1841
+ logger3.debug({ path: input.path }, "Deleting file");
1842
+ try {
1843
+ const result = await delegateFileTask(
1844
+ "delete_file",
1845
+ { path: input.path },
1846
+ `Delete file: ${input.path}`
1847
+ );
1848
+ if (!result.success) {
1849
+ return errorResponse(result.error || "Failed to delete file");
1850
+ }
1851
+ return successResponse(`File deleted successfully: ${input.path}`);
1852
+ } catch (err) {
1853
+ logger3.error({ error: err.message, path: input.path }, "Failed to delete file");
1854
+ return errorResponse(err.message);
1855
+ }
1856
+ };
1857
+ handlers["bridge_list_directory"] = async (args) => {
1858
+ const input = ListDirectoryInputSchema.parse(args);
1859
+ logger3.debug({ path: input.path }, "Listing directory");
1860
+ try {
1861
+ const result = await delegateFileTask(
1862
+ "list_directory",
1863
+ { path: input.path },
1864
+ `List directory: ${input.path}`
1865
+ );
1866
+ if (!result.success) {
1867
+ return errorResponse(result.error || "Failed to list directory");
1868
+ }
1869
+ const entries = result.data.entries;
1870
+ if (!entries || entries.length === 0) {
1871
+ return successResponse(`Directory is empty: ${input.path}`);
1872
+ }
1873
+ const listing = entries.map((e) => `${e.type === "directory" ? "\u{1F4C1}" : "\u{1F4C4}"} ${e.name}`).join("\n");
1874
+ return successResponse(`Contents of ${input.path}:
1875
+ ${listing}`);
1876
+ } catch (err) {
1877
+ logger3.error({ error: err.message, path: input.path }, "Failed to list directory");
1878
+ return errorResponse(err.message);
1879
+ }
1880
+ };
1881
+ handlers["bridge_delegate_task"] = async (args) => {
1882
+ const input = DelegateTaskInputSchema.parse(args);
1883
+ logger3.debug({ description: input.description, scope: input.scope }, "Delegating task");
1884
+ try {
1885
+ const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1886
+ const result = await bridge.delegateTask({
1887
+ id: taskId,
1888
+ description: input.description,
1889
+ scope: input.scope,
1890
+ data: input.data
1891
+ });
1892
+ if (!result.success) {
1893
+ return errorResponse(result.error || "Task failed");
1894
+ }
1895
+ return successResponse(JSON.stringify(result.data, null, 2));
1896
+ } catch (err) {
1897
+ logger3.error({ error: err.message }, "Failed to delegate task");
1898
+ return errorResponse(err.message);
1899
+ }
1900
+ };
1901
+ handlers["bridge_request_context"] = async (args) => {
1902
+ const input = RequestContextInputSchema.parse(args);
1903
+ logger3.debug({ query: input.query }, "Requesting context");
1904
+ try {
1905
+ const files = await bridge.requestContext(input.query);
1906
+ if (files.length === 0) {
1907
+ return successResponse("No files found matching the query.");
1908
+ }
1909
+ const fileResults = files.map((f) => {
1910
+ const header = `=== ${f.path} ===`;
1911
+ const content = f.content;
1912
+ return `${header}
1913
+ ${content}`;
1914
+ }).join("\n\n");
1915
+ return successResponse(`Found ${files.length} file(s):
1916
+
1917
+ ${fileResults}`);
1918
+ } catch (err) {
1919
+ logger3.error({ error: err.message }, "Failed to request context");
1920
+ return errorResponse(err.message);
1921
+ }
1922
+ };
1923
+ handlers["bridge_status"] = async () => {
1924
+ logger3.debug("Getting bridge status");
1925
+ const peers = bridge.getPeers();
1926
+ const peerCount = bridge.getPeerCount();
1927
+ const isStarted = bridge.isStarted();
1928
+ const mode = bridge.getMode();
1929
+ const instanceName = bridge.getInstanceName();
1930
+ const status = {
1931
+ instanceName,
1932
+ mode,
1933
+ started: isStarted,
1934
+ peerCount,
1935
+ peers: peers.map((p) => ({
1936
+ id: p.id,
1937
+ name: p.name,
1938
+ connectedAt: new Date(p.connectedAt).toISOString(),
1939
+ lastActivity: new Date(p.lastActivity).toISOString()
1940
+ }))
1941
+ };
1942
+ return successResponse(JSON.stringify(status, null, 2));
1943
+ };
1944
+ return handlers;
1945
+ }
1946
+ function zodToJsonSchema(schema) {
1947
+ if (schema instanceof z2.ZodObject) {
1948
+ const shape = schema.shape;
1949
+ const properties = {};
1950
+ const required = [];
1951
+ for (const [key, value] of Object.entries(shape)) {
1952
+ const zodValue = value;
1953
+ properties[key] = zodToJsonSchema(zodValue);
1954
+ if (!(zodValue instanceof z2.ZodOptional)) {
1955
+ required.push(key);
1956
+ }
1957
+ }
1958
+ return {
1959
+ type: "object",
1960
+ properties,
1961
+ ...required.length > 0 ? { required } : {}
1962
+ };
1963
+ }
1964
+ if (schema instanceof z2.ZodString) {
1965
+ const result = { type: "string" };
1966
+ if (schema.description) {
1967
+ result.description = schema.description;
1968
+ }
1969
+ return result;
1970
+ }
1971
+ if (schema instanceof z2.ZodEnum) {
1972
+ return {
1973
+ type: "string",
1974
+ enum: schema.options
1975
+ };
1976
+ }
1977
+ if (schema instanceof z2.ZodOptional) {
1978
+ return zodToJsonSchema(schema.unwrap());
1979
+ }
1980
+ if (schema instanceof z2.ZodRecord) {
1981
+ return {
1982
+ type: "object",
1983
+ additionalProperties: true
1984
+ };
1985
+ }
1986
+ if (schema instanceof z2.ZodUnknown) {
1987
+ return {};
1988
+ }
1989
+ return { type: "string" };
1990
+ }
1991
+
1992
+ // src/mcp/server.ts
1993
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
1994
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1995
+ import {
1996
+ CallToolRequestSchema,
1997
+ ListToolsRequestSchema
1998
+ } from "@modelcontextprotocol/sdk/types.js";
1999
+ var logger4 = createLogger("mcp:server");
2000
+ var BridgeMcpServer = class {
2001
+ server;
2002
+ bridge;
2003
+ config;
2004
+ toolHandlers = null;
2005
+ constructor(config) {
2006
+ this.config = config;
2007
+ this.server = new Server(
2008
+ {
2009
+ name: config.name ?? "claude-bridge",
2010
+ version: config.version ?? "0.4.0"
2011
+ },
2012
+ {
2013
+ capabilities: {
2014
+ tools: {}
2015
+ }
2016
+ }
2017
+ );
2018
+ const bridgeConfig = {
2019
+ mode: "client",
2020
+ instanceName: config.instanceName ?? `mcp-server-${process.pid}`,
2021
+ connect: {
2022
+ url: config.bridgeUrl
2023
+ },
2024
+ taskTimeout: config.taskTimeout ?? 6e4
2025
+ };
2026
+ this.bridge = new Bridge(bridgeConfig);
2027
+ this.registerHandlers();
2028
+ }
2029
+ /**
2030
+ * Register MCP request handlers
2031
+ */
2032
+ registerHandlers() {
2033
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
2034
+ logger4.debug("Listing tools");
2035
+ return {
2036
+ tools: TOOL_DEFINITIONS.map((tool) => ({
2037
+ name: tool.name,
2038
+ description: tool.description,
2039
+ inputSchema: zodToJsonSchema(tool.inputSchema)
2040
+ }))
2041
+ };
2042
+ });
2043
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
2044
+ const { name, arguments: args } = request.params;
2045
+ logger4.debug({ tool: name }, "Tool call received");
2046
+ if (!this.toolHandlers) {
2047
+ this.toolHandlers = createToolHandlers(this.bridge);
2048
+ }
2049
+ const handler = this.toolHandlers[name];
2050
+ if (!handler) {
2051
+ logger4.warn({ tool: name }, "Unknown tool requested");
2052
+ return {
2053
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
2054
+ isError: true
2055
+ };
2056
+ }
2057
+ try {
2058
+ const result = await handler(args ?? {});
2059
+ logger4.debug({ tool: name, isError: result.isError }, "Tool call completed");
2060
+ return {
2061
+ content: result.content,
2062
+ isError: result.isError
2063
+ };
2064
+ } catch (err) {
2065
+ logger4.error({ tool: name, error: err.message }, "Tool call failed");
2066
+ return {
2067
+ content: [{ type: "text", text: `Error: ${err.message}` }],
2068
+ isError: true
2069
+ };
2070
+ }
2071
+ });
2072
+ }
2073
+ /**
2074
+ * Start the MCP server
2075
+ * Connects to bridge daemon and starts listening on stdio
2076
+ */
2077
+ async start() {
2078
+ console.error("[MCP] Starting bridge MCP server...");
2079
+ console.error(`[MCP] Connecting to bridge at ${this.config.bridgeUrl}`);
2080
+ try {
2081
+ await this.bridge.start();
2082
+ console.error("[MCP] Connected to bridge daemon");
2083
+ this.toolHandlers = createToolHandlers(this.bridge);
2084
+ const transport = new StdioServerTransport();
2085
+ await this.server.connect(transport);
2086
+ console.error("[MCP] MCP server started and listening on stdio");
2087
+ logger4.info("MCP server started");
2088
+ } catch (err) {
2089
+ console.error(`[MCP] Failed to start: ${err.message}`);
2090
+ throw err;
2091
+ }
2092
+ }
2093
+ /**
2094
+ * Stop the MCP server
2095
+ */
2096
+ async stop() {
2097
+ console.error("[MCP] Stopping MCP server...");
2098
+ try {
2099
+ await this.bridge.stop();
2100
+ await this.server.close();
2101
+ console.error("[MCP] MCP server stopped");
2102
+ logger4.info("MCP server stopped");
2103
+ } catch (err) {
2104
+ console.error(`[MCP] Error during shutdown: ${err.message}`);
2105
+ }
2106
+ }
2107
+ /**
2108
+ * Get the bridge instance
2109
+ */
2110
+ getBridge() {
2111
+ return this.bridge;
2112
+ }
2113
+ };
2114
+ async function startMcpServer(config) {
2115
+ const server = new BridgeMcpServer(config);
2116
+ await server.start();
2117
+ return server;
2118
+ }
2119
+
1720
2120
  export {
1721
2121
  createLogger,
1722
2122
  createChildLogger,
@@ -1745,6 +2145,10 @@ export {
1745
2145
  DEFAULT_CONFIG,
1746
2146
  mergeConfig,
1747
2147
  loadConfig,
1748
- loadConfigSync
2148
+ loadConfigSync,
2149
+ TOOL_DEFINITIONS,
2150
+ createToolHandlers,
2151
+ BridgeMcpServer,
2152
+ startMcpServer
1749
2153
  };
1750
- //# sourceMappingURL=chunk-LUL3SX2F.js.map
2154
+ //# sourceMappingURL=chunk-MHUQYPTB.js.map