mle-kit-mcp 0.2.5__py3-none-any.whl → 1.0.0__py3-none-any.whl

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.
mle_kit_mcp/server.py CHANGED
@@ -1,9 +1,8 @@
1
1
  import os
2
2
  from pathlib import Path
3
- from typing import Optional
3
+ from typing import Optional, Literal
4
4
 
5
5
  import fire # type: ignore
6
- import uvicorn
7
6
  from mcp.server.fastmcp import FastMCP
8
7
  from dotenv import load_dotenv
9
8
 
@@ -21,14 +20,26 @@ from .tools.llm_proxy import (
21
20
  from .files import get_workspace_dir, WorkspaceDirectory
22
21
 
23
22
 
24
- def run(host: str = "0.0.0.0", port: int = 5050, workspace: Optional[str] = None) -> None:
23
+ def run(
24
+ host: str = "0.0.0.0",
25
+ port: int = 5050,
26
+ mount_path: str = "/",
27
+ streamable_http_path: str = "/mcp",
28
+ workspace: Optional[str] = None,
29
+ transport: Literal["stdio", "sse", "streamable-http"] = "streamable-http",
30
+ ) -> None:
25
31
  load_dotenv()
26
32
  if workspace:
27
33
  WorkspaceDirectory.set_dir(Path(workspace))
28
34
  workspace_path = get_workspace_dir()
29
35
  workspace_path.mkdir(parents=True, exist_ok=True)
30
36
 
31
- server = FastMCP("MLE kit MCP", stateless_http=True)
37
+ server = FastMCP(
38
+ "MLE kit MCP",
39
+ stateless_http=True,
40
+ streamable_http_path=streamable_http_path,
41
+ mount_path=mount_path,
42
+ )
32
43
 
33
44
  remote_text_editor = create_remote_text_editor(text_editor)
34
45
 
@@ -41,9 +52,9 @@ def run(host: str = "0.0.0.0", port: int = 5050, workspace: Optional[str] = None
41
52
  server.add_tool(llm_proxy_local)
42
53
  server.add_tool(llm_proxy_remote)
43
54
 
44
- http_app = server.streamable_http_app()
45
-
46
- uvicorn.run(http_app, host=host, port=port)
55
+ server.settings.port = port
56
+ server.settings.host = host
57
+ server.run(transport=transport)
47
58
 
48
59
 
49
60
  if __name__ == "__main__":
mle_kit_mcp/tools/bash.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import atexit
2
2
  import signal
3
+ import shlex
3
4
  from typing import Optional, Any
4
5
 
5
6
  from docker import from_env as docker_from_env # type: ignore
@@ -67,7 +68,11 @@ signal.signal(signal.SIGINT, cleanup_container)
67
68
  signal.signal(signal.SIGTERM, cleanup_container)
68
69
 
69
70
 
70
- def bash(command: str, cwd: Optional[str] = None) -> str:
71
+ def bash(
72
+ command: str,
73
+ cwd: Optional[str] = None,
74
+ timeout: int = 60,
75
+ ) -> str:
71
76
  """
72
77
  Run commands in a bash shell.
73
78
  When invoking this tool, the contents of the "command" parameter does NOT need to be XML-escaped.
@@ -76,22 +81,48 @@ def bash(command: str, cwd: Optional[str] = None) -> str:
76
81
  State is persistent across command calls and discussions with the user.
77
82
  To inspect a particular line range of a file, e.g. lines 10-25, try 'sed -n 10,25p /path/to/the/file'.
78
83
  Please avoid commands that may produce a very large amount of output.
79
- Please run long lived commands in the background, e.g. 'sleep 10 &' or start a server in the background.
80
84
 
81
85
  Args:
82
86
  command: The bash command to run.
83
87
  cwd: The working directory to run the command in. Relative to the workspace directory.
88
+ timeout: Timeout for the command execution in seconds. Kills after this. 60 seconds by default.
84
89
  """
85
-
90
+ assert timeout and timeout > 0, "Timeout must be set and greater than 0"
86
91
  container = get_container()
87
92
  workdir = DOCKER_WORKSPACE_DIR_PATH
88
93
  if cwd:
89
- workdir = DOCKER_WORKSPACE_DIR_PATH + "/" + cwd
94
+ workdir += "/" + cwd
95
+
96
+ wrapped = f"bash -lc {shlex.quote(command)}"
97
+ final_command = f"timeout --signal=TERM --kill-after=5s {int(timeout)}s {wrapped}"
98
+
90
99
  result = container.exec_run(
91
- ["bash", "-c", command],
100
+ ["bash", "-lc", final_command],
92
101
  workdir=workdir,
93
102
  stdout=True,
94
103
  stderr=True,
104
+ demux=True,
95
105
  )
96
- output: str = result.output.decode("utf-8").strip()
106
+ stdout_bytes, stderr_bytes = (
107
+ result.output if isinstance(result.output, tuple) else (result.output, b"")
108
+ )
109
+
110
+ if result.exit_code in (124, 137):
111
+ timeout_msg = (
112
+ f"Command timed out after {int(timeout)} seconds: {command};\n"
113
+ f"You can increase the timeout by changing the parameter of the tool call."
114
+ )
115
+ stderr_bytes = (stderr_bytes or b"") + timeout_msg.encode("utf-8")
116
+
117
+ stdout_text = (stdout_bytes or b"").decode("utf-8", errors="replace").strip()
118
+ stderr_text = (stderr_bytes or b"").decode("utf-8", errors="replace").strip()
119
+
120
+ output_parts = []
121
+ if stdout_text:
122
+ output_parts.append("Command stdout: " + stdout_text)
123
+ if stderr_text:
124
+ output_parts.append("Command stderr: " + stderr_text)
125
+ output = ("\n".join(output_parts)).strip()
126
+ if not output:
127
+ output = "No output from the command"
97
128
  return output
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mle-kit-mcp
3
- Version: 0.2.5
3
+ Version: 1.0.0
4
4
  Summary: MCP server that provides different tools for MLE
5
5
  Author-email: Ilya Gusev <phoenixilya@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/IlyaGusev/mle_kit_mcp
@@ -3,16 +3,16 @@ mle_kit_mcp/__main__.py,sha256=rcmsOtJd3SA82exjrcGBuxuptcoxF8AXI7jNjiVq2BY,59
3
3
  mle_kit_mcp/files.py,sha256=ux53kWw7hBAcOmS9qNI4gpQX8XcQPT2LICC--S5-TGI,635
4
4
  mle_kit_mcp/llm_proxy.py,sha256=01BG6OA8husOQXxgJQ7RnTNEE_1HDczlCNoAVnYWURQ,1225
5
5
  mle_kit_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- mle_kit_mcp/server.py,sha256=R59DC7HVdpPcGHVXghPGUhrRKfn9Uqmy2MPkaYNfyzw,1320
6
+ mle_kit_mcp/server.py,sha256=6KGjhcjjqP9PxKw17X7ZejeRrGfCB8Mk4SmnoTklCMs,1587
7
7
  mle_kit_mcp/utils.py,sha256=iHNcEZZzPD37bEYE18SzJ3WUjLP3Ym-kc91SwcW1vlI,1984
8
8
  mle_kit_mcp/tools/__init__.py,sha256=r2fIg2mZ6zaeq0CzEKCEdeUTjV0pcA9NZaaOfBNVTnE,332
9
- mle_kit_mcp/tools/bash.py,sha256=kunYHc3dyPGOooT-KY9L7eI_N22lBrcDbTlcp_yTTws,2820
9
+ mle_kit_mcp/tools/bash.py,sha256=IDzR3dkGOKGuwEE0FooQMI-Ztx99t8YJKoMu4FjxNGw,3922
10
10
  mle_kit_mcp/tools/llm_proxy.py,sha256=uEPZETqJWGOwLESWfvIjJidL6LSRry5j-qq6rpjtxLM,4623
11
11
  mle_kit_mcp/tools/remote_gpu.py,sha256=2Wjp6fYTGX9i6bZUhSWM5WMKh0eMc73wCdezes04bDg,12546
12
12
  mle_kit_mcp/tools/text_editor.py,sha256=hkobiyYB5um6bs5sWYDQ1S2Y5n31i7I6fOBUDFkNhmM,9531
13
- mle_kit_mcp-0.2.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
14
- mle_kit_mcp-0.2.5.dist-info/METADATA,sha256=pKWNkp9pLxtGAofpzamJA4BuTkzxwf0hqq8CNl1s0ts,1074
15
- mle_kit_mcp-0.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- mle_kit_mcp-0.2.5.dist-info/entry_points.txt,sha256=-iHSUVPN49jkBj1ySpc-P0rVF5-IPHw-KWNayNIiEsk,49
17
- mle_kit_mcp-0.2.5.dist-info/top_level.txt,sha256=XeBtCq_CnVI0gh0Z_daZOLmGl5XPlkA8RgHaj5s5VQY,12
18
- mle_kit_mcp-0.2.5.dist-info/RECORD,,
13
+ mle_kit_mcp-1.0.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
14
+ mle_kit_mcp-1.0.0.dist-info/METADATA,sha256=Imea6N52932F2PMdNOtvpPqtnCR5s17ZHdBbZfFTqyI,1074
15
+ mle_kit_mcp-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ mle_kit_mcp-1.0.0.dist-info/entry_points.txt,sha256=-iHSUVPN49jkBj1ySpc-P0rVF5-IPHw-KWNayNIiEsk,49
17
+ mle_kit_mcp-1.0.0.dist-info/top_level.txt,sha256=XeBtCq_CnVI0gh0Z_daZOLmGl5XPlkA8RgHaj5s5VQY,12
18
+ mle_kit_mcp-1.0.0.dist-info/RECORD,,