weztermcp 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kentaro Hiraishi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # WezTerm MCP Server
2
+
3
+ ## Overview
4
+
5
+ This is a MCP server for WezTerm.
6
+ It allows you to control WezTerm from Claude Desktop and other MCP clients.
7
+
8
+ ## Tools
9
+
10
+ | Tool | Required Args | Optional Args | Description |
11
+ |---|---|---|---|
12
+ | `wezterm_pane_write` | `command: string`, `pane_id: number` | — | Writes text or runs a command in the specified pane |
13
+ | `wezterm_pane_read` | — | `lines: number` (default 50), `pane_id: number` | Reads output from a pane's scrollback buffer |
14
+ | `wezterm_pane_send_key` | `character: string`, `pane_id: number` | — | Sends a control character to the specified pane (e.g. `"c"` for Ctrl+C) |
15
+ | `wezterm_pane_list` | — | — | Lists all panes in the current WezTerm session |
16
+ | `wezterm_pane_switch` | `pane_id: number` | — | Switches focus to the specified pane |
17
+ | `wezterm_pane_close` | `pane_id: number` | — | Closes the specified pane |
18
+ | `wezterm_pane_split` | `pane_id: number`, `direction: "Right"\|"Left"\|"Top"\|"Bottom"` | — | Splits the specified pane and returns the new pane ID |
19
+
20
+ ## Security
21
+
22
+ This server gives an MCP client the ability to run arbitrary shell commands in any open WezTerm pane, with the full permissions of the user running WezTerm. There is no sandboxing, allowlisting, or command filtering — `wezterm_pane_write` will execute anything sent to it, including destructive operations like `rm -rf`, force pushes, or database migrations.
23
+
24
+ **Risk model:**
25
+ - Any agent connected to this server can read, write, and close panes it did not open, including ones with unrelated work in progress.
26
+ - `wezterm_pane_write` and `wezterm_pane_close` are flagged in their tool descriptions as requiring user confirmation before destructive or irreversible actions, but this is advisory only — the server itself does not block or intercept any command.
27
+ - Only connect this server to trusted MCP clients, and review agent-issued commands before they run if your client supports that.
28
+
29
+ ## Installation
30
+
31
+ To use with Claude Desktop, add the server config:
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "weztermcp": {
37
+ "command": "npx",
38
+ "args": ["-y", "weztermcp"]
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ ## Releasing
45
+
46
+ Publishing to npm is automated via `.github/workflows/publish.yml`. On every push to `main`, CI runs the test suite and build, then publishes to npm if `package.json`'s `version` field isn't already published — no publish happens if the version is unchanged.
47
+
48
+ To cut a release:
49
+
50
+ 1. Bump `version` in `package.json` (e.g. `npm version patch`, `npm version minor`, or edit directly).
51
+ 2. Commit and push to `main`.
52
+ 3. CI runs tests, builds, and publishes automatically if the tests pass and the version is new.
53
+
54
+ Publishing uses [npm trusted publishing](https://docs.npmjs.com/trusted-publishers) via OIDC — no npm token or repository secret is needed. The `weztermcp` package on npmjs.com must have this repo's `publish.yml` workflow configured as a trusted publisher (Package Settings → Trusted Publisher on npmjs.com), and the workflow's `publish` job grants itself `id-token: write` to mint the short-lived OIDC credential at publish time.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ import WeztermExecutor from "./wezterm_executor.js";
6
+ import WeztermOutputReader from "./wezterm_output_reader.js";
7
+ import SendControlCharacter from "./send_control_character.js";
8
+ const server = new Server({
9
+ name: "weztermcp",
10
+ version: "0.1.0",
11
+ }, {
12
+ capabilities: {
13
+ tools: {},
14
+ },
15
+ });
16
+ // Tool definitions
17
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
18
+ return {
19
+ tools: [
20
+ {
21
+ name: "wezterm_pane_write",
22
+ title: "Write to WezTerm Pane",
23
+ description: "EXECUTION TOOL. Transmits a command or text to a specific WezTerm pane by ID and executes it. WHEN: 'run this command', 'execute in pane', 'send to terminal'. Returns confirmation text only — does NOT return command output; follow with wezterm_pane_read to capture results. SECURITY: this runs arbitrary shell commands with the user's full permissions in a live terminal. Confirm with the user before sending destructive or irreversible commands (e.g. rm, git push --force, database migrations). Example: write 'npm test' to pane 3.",
24
+ inputSchema: {
25
+ type: "object",
26
+ properties: {
27
+ command: {
28
+ type: "string",
29
+ description: "Text to send to the pane. A newline (\\n) is automatically appended, causing the shell to execute the input as a command. To type text without executing, omit a trailing newline by ending with a space or partial input — but note this tool always appends \\n, so use wezterm_pane_send_key for raw control sequences instead.",
30
+ },
31
+ pane_id: {
32
+ type: "number",
33
+ description: "Integer ID of the target pane. Obtain valid IDs from wezterm_pane_list. Must be a currently open pane.",
34
+ },
35
+ },
36
+ required: ["command", "pane_id"],
37
+ },
38
+ },
39
+ {
40
+ name: "wezterm_pane_read",
41
+ title: "Read WezTerm Pane Output",
42
+ description: "EXECUTION TOOL. Captures recent visible text from a WezTerm pane's scrollback buffer. WHEN: 'show terminal output', 'what did the command print', 'read pane output'. Returns up to N lines of text (default 50). Does NOT execute commands; use wezterm_pane_write first. Example: read 100 lines from pane 2 after running a build.",
43
+ inputSchema: {
44
+ type: "object",
45
+ properties: {
46
+ lines: {
47
+ type: "number",
48
+ description: "Number of lines to read from the scrollback buffer. Default: 50. Use 0 or a negative value to read the current screen only (no scrollback). Large values (e.g. 500) capture more history but may include stale output.",
49
+ },
50
+ pane_id: {
51
+ type: "number",
52
+ description: "Integer ID of the pane to read from. Default: the currently active pane. Obtain valid IDs from wezterm_pane_list.",
53
+ },
54
+ },
55
+ },
56
+ },
57
+ {
58
+ name: "wezterm_pane_send_key",
59
+ title: "Send Control Key to WezTerm Pane",
60
+ description: "EXECUTION TOOL. Injects a terminal control character (Ctrl+key) into a specific WezTerm pane. WHEN: 'interrupt process', 'send Ctrl+C', 'stop running command', 'send EOF'. Supported keys: c d z l a e k u w. Does NOT send printable text — use wezterm_pane_write for that. Returns confirmation; no output captured. Example: send 'c' to pane 1 to kill a hung process.",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {
64
+ character: {
65
+ type: "string",
66
+ description: "Single letter key to combine with Ctrl. Case-insensitive. Supported values: 'c' (SIGINT), 'd' (EOF), 'z' (SIGTSTP), 'l' (clear screen), 'a' (start of line), 'e' (end of line), 'k' (kill to end), 'u' (kill to start), 'w' (kill word). Any other value returns an error.",
67
+ },
68
+ pane_id: {
69
+ type: "number",
70
+ description: "Integer ID of the target pane. Obtain valid IDs from wezterm_pane_list. Must be a currently open pane.",
71
+ },
72
+ },
73
+ required: ["character", "pane_id"],
74
+ },
75
+ },
76
+ {
77
+ name: "wezterm_pane_list",
78
+ title: "List WezTerm Panes",
79
+ description: "EXECUTION TOOL. Enumerates all open panes in the current WezTerm session, returning pane IDs, active state, and titles. WHEN: 'what panes are open', 'show pane list', 'which pane is active', 'find pane ID'. Does NOT switch focus or read pane content. Use returned pane_id values with other tools. Example: call before wezterm_pane_write to discover the target pane_id.",
80
+ inputSchema: {
81
+ type: "object",
82
+ properties: {},
83
+ },
84
+ },
85
+ {
86
+ name: "wezterm_pane_switch",
87
+ title: "Switch WezTerm Pane Focus",
88
+ description: "EXECUTION TOOL. Activates a WezTerm pane by ID, moving keyboard focus to it. WHEN: 'switch to pane', 'focus pane', 'activate pane', 'move to terminal'. Returns confirmation only — does NOT read content or send input. Use wezterm_pane_list first to resolve the correct pane_id. Example: switch to pane 2 to bring an editor pane into focus.",
89
+ inputSchema: {
90
+ type: "object",
91
+ properties: {
92
+ pane_id: {
93
+ type: "number",
94
+ description: "Integer ID of the pane to activate. Obtain valid IDs from wezterm_pane_list. Must be a currently open pane.",
95
+ },
96
+ },
97
+ required: ["pane_id"],
98
+ },
99
+ },
100
+ {
101
+ name: "wezterm_pane_close",
102
+ title: "Close WezTerm Pane",
103
+ description: "EXECUTION TOOL. Terminates and removes a WezTerm pane by ID, killing any process running inside it. WHEN: 'close pane', 'kill pane', 'remove terminal', 'clean up pane'. Destructive and irreversible — any unsaved state in the pane is lost. Does NOT close tabs or windows. Returns confirmation only. SECURITY: confirm with the user before closing a pane that may be running an unsaved or long-lived process. Example: close pane 4 after a finished build job.",
104
+ inputSchema: {
105
+ type: "object",
106
+ properties: {
107
+ pane_id: {
108
+ type: "number",
109
+ description: "Integer ID of the pane to close. Obtain valid IDs from wezterm_pane_list. Closing the last pane in a tab will close the tab.",
110
+ },
111
+ },
112
+ required: ["pane_id"],
113
+ },
114
+ },
115
+ {
116
+ name: "wezterm_pane_split",
117
+ title: "Split WezTerm Pane",
118
+ description: "EXECUTION TOOL. Divides an existing WezTerm pane into two by splitting in the given direction (Right, Left, Top, Bottom), opening a new shell in the new pane. WHEN: 'split terminal', 'open new pane', 'create side-by-side panes'. Returns the new pane's ID — store it to target subsequent commands. Does NOT send any input to the new pane. Example: split pane 1 Right, then wezterm_pane_write to the returned pane ID.",
119
+ inputSchema: {
120
+ type: "object",
121
+ properties: {
122
+ pane_id: {
123
+ type: "number",
124
+ description: "Integer ID of the pane to split. Obtain valid IDs from wezterm_pane_list. The existing pane retains its content; the new pane opens a fresh shell.",
125
+ },
126
+ direction: {
127
+ type: "string",
128
+ enum: ["Right", "Left", "Top", "Bottom"],
129
+ description: "Direction in which to create the new pane relative to the existing one. 'Right' and 'Left' split vertically (side by side); 'Top' and 'Bottom' split horizontally (stacked). Must be exactly one of: Right, Left, Top, Bottom (case-sensitive).",
130
+ },
131
+ },
132
+ required: ["pane_id", "direction"],
133
+ },
134
+ },
135
+ ],
136
+ };
137
+ });
138
+ // Tool execution
139
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
140
+ const executor = new WeztermExecutor();
141
+ const outputReader = new WeztermOutputReader();
142
+ const controlCharSender = new SendControlCharacter();
143
+ switch (request.params.name) {
144
+ case "wezterm_pane_write":
145
+ return await executor.writeToTerminal(request.params.arguments.command, request.params.arguments.pane_id);
146
+ case "wezterm_pane_read":
147
+ const lines = request.params.arguments.lines || 50;
148
+ const paneId = request.params.arguments.pane_id;
149
+ return await outputReader.readOutput(lines, paneId);
150
+ case "wezterm_pane_send_key":
151
+ return await controlCharSender.send(request.params.arguments.character, request.params.arguments.pane_id);
152
+ case "wezterm_pane_list":
153
+ return await executor.listPanes();
154
+ case "wezterm_pane_switch":
155
+ return await executor.switchPane(request.params.arguments.pane_id);
156
+ case "wezterm_pane_close":
157
+ return await executor.closePane(request.params.arguments.pane_id);
158
+ case "wezterm_pane_split":
159
+ return await executor.splitPane(request.params.arguments.pane_id, request.params.arguments.direction);
160
+ default:
161
+ throw new Error(`Unknown tool: ${request.params.name}`);
162
+ }
163
+ });
164
+ async function main() {
165
+ const transport = new StdioServerTransport();
166
+ await server.connect(transport);
167
+ }
168
+ main().catch((error) => {
169
+ console.error("Server error:", error);
170
+ process.exit(1);
171
+ });
172
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export default class SendControlCharacter {
2
+ private weztermCli;
3
+ constructor();
4
+ send(character: string, paneId?: number): Promise<{
5
+ content: any[];
6
+ }>;
7
+ }
8
+ //# sourceMappingURL=send_control_character.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send_control_character.d.ts","sourceRoot":"","sources":["../src/send_control_character.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,UAAU,CAAS;;IAMrB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CAoC5E"}
@@ -0,0 +1,46 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ import { assertWeztermInstalled, notInstalledResult } from "./wezterm_check.js";
4
+ const execAsync = promisify(exec);
5
+ export default class SendControlCharacter {
6
+ weztermCli;
7
+ constructor() {
8
+ this.weztermCli = "wezterm cli";
9
+ }
10
+ async send(character, paneId) {
11
+ const err = await assertWeztermInstalled();
12
+ if (err)
13
+ return notInstalledResult();
14
+ try {
15
+ const controlMap = {
16
+ c: "\\x03", // Ctrl+C
17
+ d: "\\x04", // Ctrl+D
18
+ z: "\\x1a", // Ctrl+Z
19
+ l: "\\x0c", // Ctrl+L
20
+ a: "\\x01", // Ctrl+A
21
+ e: "\\x05", // Ctrl+E
22
+ k: "\\x0b", // Ctrl+K
23
+ u: "\\x15", // Ctrl+U
24
+ w: "\\x17", // Ctrl+W
25
+ };
26
+ const controlSeq = controlMap[character.toLowerCase()];
27
+ if (!controlSeq) {
28
+ throw new Error(`Unknown control character: ${character}`);
29
+ }
30
+ const paneFlag = paneId !== undefined ? ` --pane-id ${paneId}` : "";
31
+ await execAsync(`${this.weztermCli} send-text${paneFlag} $'${controlSeq}'`);
32
+ return {
33
+ content: [
34
+ {
35
+ type: "text",
36
+ text: `Sent control character: Ctrl+${character.toUpperCase()}`,
37
+ },
38
+ ],
39
+ };
40
+ }
41
+ catch (error) {
42
+ throw new Error(`Failed to send control character: ${error.message}`);
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=send_control_character.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send_control_character.js","sourceRoot":"","sources":["../src/send_control_character.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,CAAC,OAAO,OAAO,oBAAoB;IAC/B,UAAU,CAAS;IAE3B;QACE,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAe;QAC3C,MAAM,GAAG,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC3C,IAAI,GAAG;YAAE,OAAO,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,UAAU,GAA8B;gBAC5C,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;gBACrB,CAAC,EAAE,OAAO,EAAE,SAAS;aACtB,CAAC;YAEF,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;YACvD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,UAAU,aAAa,QAAQ,MAAM,UAAU,GAAG,CAAC,CAAC;YAE5E,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,gCAAgC,SAAS,CAAC,WAAW,EAAE,EAAE;qBAChE;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export declare const NOT_INSTALLED_MSG = "WezTerm is not installed or not on PATH. Install it from https://wezfurlong.org/wezterm/ and ensure 'wezterm' is accessible.";
2
+ export declare function assertWeztermInstalled(): Promise<string | null>;
3
+ export declare function notInstalledResult(): {
4
+ content: any[];
5
+ };
6
+ //# sourceMappingURL=wezterm_check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wezterm_check.d.ts","sourceRoot":"","sources":["../src/wezterm_check.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,iIACkG,CAAC;AAEjI,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUrE;AAED,wBAAgB,kBAAkB,IAAI;IAAE,OAAO,EAAE,GAAG,EAAE,CAAA;CAAE,CAEvD"}
@@ -0,0 +1,20 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ const execAsync = promisify(exec);
4
+ export const NOT_INSTALLED_MSG = "WezTerm is not installed or not on PATH. Install it from https://wezfurlong.org/wezterm/ and ensure 'wezterm' is accessible.";
5
+ export async function assertWeztermInstalled() {
6
+ try {
7
+ const { stdout } = await execAsync("wezterm --version");
8
+ if (!stdout.trim()) {
9
+ return NOT_INSTALLED_MSG;
10
+ }
11
+ return null;
12
+ }
13
+ catch {
14
+ return NOT_INSTALLED_MSG;
15
+ }
16
+ }
17
+ export function notInstalledResult() {
18
+ return { content: [{ type: "text", text: NOT_INSTALLED_MSG }] };
19
+ }
20
+ //# sourceMappingURL=wezterm_check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wezterm_check.js","sourceRoot":"","sources":["../src/wezterm_check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,iBAAiB,GAC5B,8HAA8H,CAAC;AAEjI,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,iBAAiB,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,20 @@
1
+ export default class WeztermExecutor {
2
+ private weztermCli;
3
+ constructor();
4
+ writeToTerminal(command: string, paneId: number): Promise<{
5
+ content: any[];
6
+ }>;
7
+ listPanes(): Promise<{
8
+ content: any[];
9
+ }>;
10
+ switchPane(paneId: number): Promise<{
11
+ content: any[];
12
+ }>;
13
+ closePane(paneId: number): Promise<{
14
+ content: any[];
15
+ }>;
16
+ splitPane(paneId: number, direction: "Right" | "Left" | "Top" | "Bottom"): Promise<{
17
+ content: any[];
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=wezterm_executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wezterm_executor.d.ts","sourceRoot":"","sources":["../src/wezterm_executor.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,OAAO,eAAe;IAClC,OAAO,CAAC,UAAU,CAAS;;IAMrB,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IA4BxB,SAAS,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAyBxC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAyBvD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAetD,SAAS,CACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAC7C,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CA2B/B"}
@@ -0,0 +1,133 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ import { assertWeztermInstalled, notInstalledResult } from "./wezterm_check.js";
4
+ const execAsync = promisify(exec);
5
+ export default class WeztermExecutor {
6
+ weztermCli;
7
+ constructor() {
8
+ this.weztermCli = "wezterm cli";
9
+ }
10
+ async writeToTerminal(command, paneId) {
11
+ const err = await assertWeztermInstalled();
12
+ if (err)
13
+ return notInstalledResult();
14
+ try {
15
+ const escapedCommand = command.replace(/'/g, "'\"'\"'");
16
+ await execAsync(`${this.weztermCli} send-text --pane-id ${paneId} --no-paste '${escapedCommand}\n'`);
17
+ return {
18
+ content: [
19
+ {
20
+ type: "text",
21
+ text: `Command sent to pane ${paneId}: ${command}`,
22
+ },
23
+ ],
24
+ };
25
+ }
26
+ catch (error) {
27
+ return {
28
+ content: [
29
+ {
30
+ type: "text",
31
+ text: `Failed to write to terminal: ${error.message}\nMake sure WezTerm is running and the mux server is enabled.`,
32
+ },
33
+ ],
34
+ };
35
+ }
36
+ }
37
+ async listPanes() {
38
+ const err = await assertWeztermInstalled();
39
+ if (err)
40
+ return notInstalledResult();
41
+ try {
42
+ const { stdout } = await execAsync(`${this.weztermCli} list`);
43
+ return {
44
+ content: [
45
+ {
46
+ type: "text",
47
+ text: stdout,
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ catch (error) {
53
+ return {
54
+ content: [
55
+ {
56
+ type: "text",
57
+ text: `Failed to list panes: ${error.message}\nMake sure WezTerm is running and the mux server is enabled.`,
58
+ },
59
+ ],
60
+ };
61
+ }
62
+ }
63
+ async switchPane(paneId) {
64
+ const err = await assertWeztermInstalled();
65
+ if (err)
66
+ return notInstalledResult();
67
+ try {
68
+ await execAsync(`${this.weztermCli} activate-pane --pane-id ${paneId}`);
69
+ return {
70
+ content: [
71
+ {
72
+ type: "text",
73
+ text: `Switched to pane ${paneId}`,
74
+ },
75
+ ],
76
+ };
77
+ }
78
+ catch (error) {
79
+ return {
80
+ content: [
81
+ {
82
+ type: "text",
83
+ text: `Failed to switch pane: ${error.message}\nMake sure the pane ID ${paneId} exists.`,
84
+ },
85
+ ],
86
+ };
87
+ }
88
+ }
89
+ async closePane(paneId) {
90
+ const err = await assertWeztermInstalled();
91
+ if (err)
92
+ return notInstalledResult();
93
+ try {
94
+ await execAsync(`${this.weztermCli} kill-pane --pane-id ${paneId}`);
95
+ return {
96
+ content: [{ type: "text", text: `Closed pane ${paneId}` }],
97
+ };
98
+ }
99
+ catch (error) {
100
+ return {
101
+ content: [{ type: "text", text: `Failed to close pane ${paneId}: ${error.message}` }],
102
+ };
103
+ }
104
+ }
105
+ async splitPane(paneId, direction) {
106
+ const err = await assertWeztermInstalled();
107
+ if (err)
108
+ return notInstalledResult();
109
+ const dirFlag = `--${direction.toLowerCase()}`;
110
+ try {
111
+ const { stdout } = await execAsync(`${this.weztermCli} split-pane --pane-id ${paneId} ${dirFlag}`);
112
+ return {
113
+ content: [
114
+ {
115
+ type: "text",
116
+ text: `Split pane ${paneId} ${direction}. New pane id: ${stdout.trim()}`,
117
+ },
118
+ ],
119
+ };
120
+ }
121
+ catch (error) {
122
+ return {
123
+ content: [
124
+ {
125
+ type: "text",
126
+ text: `Failed to split pane: ${error.message}`,
127
+ },
128
+ ],
129
+ };
130
+ }
131
+ }
132
+ }
133
+ //# sourceMappingURL=wezterm_executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wezterm_executor.js","sourceRoot":"","sources":["../src/wezterm_executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export default class WeztermOutputReader {
2
+ private weztermCli;
3
+ constructor();
4
+ readOutput(lines?: number, paneId?: number): Promise<{
5
+ content: any[];
6
+ }>;
7
+ readCurrentScreen(paneId?: number): Promise<{
8
+ content: any[];
9
+ }>;
10
+ }
11
+ //# sourceMappingURL=wezterm_output_reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wezterm_output_reader.d.ts","sourceRoot":"","sources":["../src/wezterm_output_reader.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,OAAO,mBAAmB;IACtC,OAAO,CAAC,UAAU,CAAS;;IAMrB,UAAU,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAoC5E,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CA4BtE"}
@@ -0,0 +1,73 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ import { assertWeztermInstalled, notInstalledResult } from "./wezterm_check.js";
4
+ const execAsync = promisify(exec);
5
+ export default class WeztermOutputReader {
6
+ weztermCli;
7
+ constructor() {
8
+ this.weztermCli = "wezterm cli";
9
+ }
10
+ async readOutput(lines = 50, paneId) {
11
+ const err = await assertWeztermInstalled();
12
+ if (err)
13
+ return notInstalledResult();
14
+ try {
15
+ let command;
16
+ const paneOption = paneId !== undefined ? ` --pane-id ${paneId}` : '';
17
+ if (lines <= 0) {
18
+ command = `${this.weztermCli} get-text --escapes${paneOption}`;
19
+ }
20
+ else {
21
+ const startLine = -lines;
22
+ command = `${this.weztermCli} get-text --escapes --start-line ${startLine}${paneOption}`;
23
+ }
24
+ const { stdout } = await execAsync(command);
25
+ return {
26
+ content: [
27
+ {
28
+ type: "text",
29
+ text: stdout || "(empty output)",
30
+ },
31
+ ],
32
+ };
33
+ }
34
+ catch (error) {
35
+ return {
36
+ content: [
37
+ {
38
+ type: "text",
39
+ text: `Failed to read terminal output: ${error.message}\nMake sure WezTerm is running and the mux server is enabled.\nTry running: wezterm cli list`,
40
+ },
41
+ ],
42
+ };
43
+ }
44
+ }
45
+ async readCurrentScreen(paneId) {
46
+ const err = await assertWeztermInstalled();
47
+ if (err)
48
+ return notInstalledResult();
49
+ try {
50
+ const paneOption = paneId !== undefined ? ` --pane-id ${paneId}` : '';
51
+ const { stdout } = await execAsync(`${this.weztermCli} get-text --escapes${paneOption}`);
52
+ return {
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: stdout || "(empty output)",
57
+ },
58
+ ],
59
+ };
60
+ }
61
+ catch (error) {
62
+ return {
63
+ content: [
64
+ {
65
+ type: "text",
66
+ text: `Failed to read current screen: ${error.message}`,
67
+ },
68
+ ],
69
+ };
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=wezterm_output_reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wezterm_output_reader.js","sourceRoot":"","sources":["../src/wezterm_output_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAC9B,UAAU,CAAS;IAE3B;QACE,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,EAAE,MAAe;QAClD,MAAM,GAAG,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC3C,IAAI,GAAG;YAAE,OAAO,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,IAAI,OAAe,CAAC;YACpB,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAEtE,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;gBACf,OAAO,GAAG,GAAG,IAAI,CAAC,UAAU,sBAAsB,UAAU,EAAE,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC;gBACzB,OAAO,GAAG,GAAG,IAAI,CAAC,UAAU,oCAAoC,SAAS,GAAG,UAAU,EAAE,CAAC;YAC3F,CAAC;YAED,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;YAE5C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM,IAAI,gBAAgB;qBACjC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mCAAmC,KAAK,CAAC,OAAO,8FAA8F;qBACrJ;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,MAAe;QACrC,MAAM,GAAG,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC3C,IAAI,GAAG;YAAE,OAAO,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,GAAG,IAAI,CAAC,UAAU,sBAAsB,UAAU,EAAE,CACrD,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM,IAAI,gBAAgB;qBACjC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,kCAAkC,KAAK,CAAC,OAAO,EAAE;qBACxD;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "weztermcp",
3
+ "version": "0.1.0",
4
+ "description": "mcp server for wezterm ",
5
+ "homepage": "https://github.com/ajmarkow/weztermcp#readme",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ajmarkow/weztermcp.git"
9
+ },
10
+ "author": "AJ Markow",
11
+ "bin": {
12
+ "weztermcp": "./build/index.js"
13
+ },
14
+ "files": [
15
+ "build"
16
+ ],
17
+ "bugs": {
18
+ "url": "https://github.com/ajmarkow/weztermcp/issues"
19
+ },
20
+ "type": "module",
21
+ "scripts": {
22
+ "build": "tsc && chmod +x build/index.js",
23
+ "watch": "tsc --watch",
24
+ "prepare": "npm run build",
25
+ "inspector": "npx @modelcontextprotocol/inspector build/index.js",
26
+ "test": "jest",
27
+ "test:watch": "jest --watch",
28
+ "test:coverage": "jest --coverage"
29
+ },
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@modelcontextprotocol/sdk": "^1.8.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/jest": "^29.5.14",
36
+ "@types/node": "^22.15.23",
37
+ "jest": "^29.7.0",
38
+ "ts-jest": "^29.4.11",
39
+ "ts-node": "^10.9.2",
40
+ "typescript": "^5.8.3"
41
+ }
42
+ }