webtool-log-cleaner-mcp 1.0.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/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # webtool-log-cleaner
2
+
3
+ A Python MCP server that captures raw logs from clipboard, files, shell commands, Docker, and Docker Compose, then deduplicates and compresses noisy output for AI debugging sessions.
4
+
5
+ ## Tools
6
+
7
+ - `clean_clipboard_logs`
8
+ - `clean_log_file`
9
+ - `clean_command_logs`
10
+ - `clean_docker_logs`
11
+ - `clean_compose_logs`
12
+
13
+ ## Reliability guardrails
14
+
15
+ - Default timeout: 30 seconds
16
+ - Output capture cap: 8 MB
17
+ - Max processed lines: 50,000
18
+ - Timed out/truncated captures are returned as partial cleaned summaries with explicit notes
19
+
20
+ ## Installation
21
+
22
+ ### 1) PyPI + pipx (recommended)
23
+
24
+ ```bash
25
+ pipx install webtool-log-cleaner
26
+ ```
27
+
28
+ MCP config:
29
+
30
+ ```json
31
+ {
32
+ "command": "webtool-log-cleaner",
33
+ "args": []
34
+ }
35
+ ```
36
+
37
+ ### 2) Plain pip (no pipx required)
38
+
39
+ ```bash
40
+ python3 -m pip install --user webtool-log-cleaner
41
+ ```
42
+
43
+ MCP config:
44
+
45
+ ```json
46
+ {
47
+ "command": "python3",
48
+ "args": ["-m", "webtool_log_cleaner.server"]
49
+ }
50
+ ```
51
+
52
+ ### 3) npx wrapper
53
+
54
+ ```bash
55
+ npx -y webtool-log-cleaner-mcp
56
+ ```
57
+
58
+ MCP config:
59
+
60
+ ```json
61
+ {
62
+ "command": "npx",
63
+ "args": ["-y", "webtool-log-cleaner-mcp"]
64
+ }
65
+ ```
66
+
67
+ Notes:
68
+ - The npm wrapper still needs Python 3.11+ installed.
69
+ - On first run, it bootstraps the Python package with `pip --user` if missing.
70
+
71
+ ## Local development
72
+
73
+ ```bash
74
+ uv run pytest -q
75
+ uv run webtool-log-cleaner
76
+ ```
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn, spawnSync } = require("node:child_process");
4
+ const fs = require("node:fs");
5
+ const path = require("node:path");
6
+
7
+ const PYTHON_PACKAGE = "webtool-log-cleaner";
8
+ const MODULE_ENTRYPOINT = "webtool_log_cleaner.server";
9
+ const args = process.argv.slice(2);
10
+
11
+ function fail(message, code = 1) {
12
+ console.error(`[webtool-log-cleaner-mcp] ${message}`);
13
+ process.exit(code);
14
+ }
15
+
16
+ function runSync(command, commandArgs, options = {}) {
17
+ return spawnSync(command, commandArgs, {
18
+ stdio: "inherit",
19
+ ...options,
20
+ });
21
+ }
22
+
23
+ function resolveLocalSourcePath() {
24
+ const candidate = path.resolve(__dirname, "..", "src");
25
+ const packagePath = path.join(candidate, "webtool_log_cleaner");
26
+ if (fs.existsSync(packagePath)) {
27
+ return candidate;
28
+ }
29
+ return null;
30
+ }
31
+
32
+ function resolveLocalVenvPython() {
33
+ const venvPath = process.platform === "win32"
34
+ ? path.resolve(__dirname, "..", ".venv", "Scripts", "python.exe")
35
+ : path.resolve(__dirname, "..", ".venv", "bin", "python");
36
+ return fs.existsSync(venvPath) ? venvPath : null;
37
+ }
38
+
39
+ function withLocalPythonPath(localSrcPath) {
40
+ const delimiter = process.platform === "win32" ? ";" : ":";
41
+ const existing = process.env.PYTHONPATH;
42
+ return existing ? `${localSrcPath}${delimiter}${existing}` : localSrcPath;
43
+ }
44
+
45
+ function selectPython() {
46
+ const localVenvPython = resolveLocalVenvPython();
47
+ const candidates = process.platform === "win32"
48
+ ? [
49
+ ...(localVenvPython ? [{ command: localVenvPython, baseArgs: [] }] : []),
50
+ { command: "py", baseArgs: ["-3"] },
51
+ { command: "python", baseArgs: [] },
52
+ { command: "python3", baseArgs: [] },
53
+ ]
54
+ : [
55
+ ...(localVenvPython ? [{ command: localVenvPython, baseArgs: [] }] : []),
56
+ { command: "python3", baseArgs: [] },
57
+ { command: "python", baseArgs: [] },
58
+ ];
59
+
60
+ for (const candidate of candidates) {
61
+ const probe = spawnSync(candidate.command, [...candidate.baseArgs, "--version"], {
62
+ stdio: "ignore",
63
+ });
64
+ if (probe.status === 0) {
65
+ return candidate;
66
+ }
67
+ }
68
+
69
+ return null;
70
+ }
71
+
72
+ function ensurePythonPackageInstalled(python) {
73
+ const importProbe = spawnSync(
74
+ python.command,
75
+ [...python.baseArgs, "-c", `import ${MODULE_ENTRYPOINT.split(".")[0]}`],
76
+ { stdio: "ignore" }
77
+ );
78
+
79
+ if (importProbe.status === 0) {
80
+ return null;
81
+ }
82
+
83
+ const localSourcePath = resolveLocalSourcePath();
84
+ if (localSourcePath) {
85
+ const localProbe = spawnSync(
86
+ python.command,
87
+ [...python.baseArgs, "-c", `import ${MODULE_ENTRYPOINT.split(".")[0]}`],
88
+ {
89
+ stdio: "ignore",
90
+ env: {
91
+ ...process.env,
92
+ PYTHONPATH: withLocalPythonPath(localSourcePath),
93
+ },
94
+ }
95
+ );
96
+
97
+ if (localProbe.status === 0) {
98
+ return {
99
+ PYTHONPATH: withLocalPythonPath(localSourcePath),
100
+ };
101
+ }
102
+ }
103
+
104
+ console.error(`[webtool-log-cleaner-mcp] Installing ${PYTHON_PACKAGE} with pip --user...`);
105
+ const install = runSync(python.command, [
106
+ ...python.baseArgs,
107
+ "-m",
108
+ "pip",
109
+ "install",
110
+ "--user",
111
+ "--upgrade",
112
+ PYTHON_PACKAGE,
113
+ ], {
114
+ env: {
115
+ ...process.env,
116
+ PIP_REQUIRE_VIRTUALENV: "0",
117
+ },
118
+ });
119
+
120
+ if (install.status !== 0) {
121
+ fail(
122
+ "Could not install Python package. Install manually with `pipx install webtool-log-cleaner` or `python3 -m pip install --user webtool-log-cleaner`."
123
+ );
124
+ }
125
+
126
+ return null;
127
+ }
128
+
129
+ function launchServer(python, forwardedArgs, envOverrides) {
130
+ const child = spawn(
131
+ python.command,
132
+ [...python.baseArgs, "-m", MODULE_ENTRYPOINT, ...forwardedArgs],
133
+ {
134
+ stdio: "inherit",
135
+ env: {
136
+ ...process.env,
137
+ ...(envOverrides || {}),
138
+ },
139
+ }
140
+ );
141
+
142
+ child.on("error", (err) => {
143
+ fail(`Failed to start Python MCP server: ${err.message}`);
144
+ });
145
+
146
+ child.on("exit", (code, signal) => {
147
+ if (signal) {
148
+ process.kill(process.pid, signal);
149
+ return;
150
+ }
151
+ process.exit(code ?? 1);
152
+ });
153
+ }
154
+
155
+ function main() {
156
+ const python = selectPython();
157
+ if (!python) {
158
+ fail("Python 3.11+ is required but was not found in PATH.");
159
+ }
160
+
161
+ const envOverrides = ensurePythonPackageInstalled(python);
162
+
163
+ if (args.includes("--bootstrap-check")) {
164
+ console.log("webtool-log-cleaner-mcp bootstrap check: OK");
165
+ process.exit(0);
166
+ }
167
+
168
+ launchServer(python, args, envOverrides);
169
+ }
170
+
171
+ main();
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "webtool-log-cleaner-mcp",
3
+ "version": "1.0.0",
4
+ "description": "npx launcher for the Python webtool-log-cleaner MCP server",
5
+ "bin": {
6
+ "webtool-log-cleaner-mcp": "bin/webtool-log-cleaner-mcp.cjs"
7
+ },
8
+ "files": [
9
+ "bin/webtool-log-cleaner-mcp.cjs",
10
+ "README.md"
11
+ ],
12
+ "license": "MIT",
13
+ "engines": {
14
+ "node": ">=18"
15
+ }
16
+ }