mcp-yieldshell 0.1.7__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.
- mcp_yieldshell/__init__.py +1 -0
- mcp_yieldshell/__main__.py +17 -0
- mcp_yieldshell/config.py +66 -0
- mcp_yieldshell/process/__init__.py +1 -0
- mcp_yieldshell/process/manager.py +616 -0
- mcp_yieldshell/process/ring_buffer.py +112 -0
- mcp_yieldshell/process/spawn.py +72 -0
- mcp_yieldshell/security.py +47 -0
- mcp_yieldshell/server.py +129 -0
- mcp_yieldshell/types.py +32 -0
- mcp_yieldshell-0.1.7.dist-info/METADATA +266 -0
- mcp_yieldshell-0.1.7.dist-info/RECORD +14 -0
- mcp_yieldshell-0.1.7.dist-info/WHEEL +4 -0
- mcp_yieldshell-0.1.7.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""YieldShell MCP — A drop-in shell MCP that auto-yields long-running commands."""
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""CLI entrypoint: start the YieldShell MCP stdio server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from .config import Config
|
|
6
|
+
from .server import create_server
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main() -> None:
|
|
10
|
+
"""Start the YieldShell MCP server on stdio."""
|
|
11
|
+
config = Config()
|
|
12
|
+
server = create_server(config)
|
|
13
|
+
server.run(transport="stdio")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
main()
|
mcp_yieldshell/config.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Configuration parsed from environment variables at server startup."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Config:
|
|
10
|
+
def __init__(self) -> None:
|
|
11
|
+
self.default_cwd: str = os.environ.get("YIELDSHELL_DEFAULT_CWD", os.getcwd())
|
|
12
|
+
self.allowed_cwd_roots: list[str] = _parse_pathsep(
|
|
13
|
+
os.environ.get("YIELDSHELL_ALLOWED_CWDS", "")
|
|
14
|
+
)
|
|
15
|
+
self.max_output_bytes: int = _parse_int(
|
|
16
|
+
os.environ.get("YIELDSHELL_MAX_OUTPUT_BYTES", ""), 20000
|
|
17
|
+
)
|
|
18
|
+
self.max_processes: int = _parse_int(
|
|
19
|
+
os.environ.get("YIELDSHELL_MAX_PROCESSES", ""), 50
|
|
20
|
+
)
|
|
21
|
+
self.default_yield_ms: int = _parse_int(
|
|
22
|
+
os.environ.get("YIELDSHELL_DEFAULT_YIELD_MS", ""), 5000
|
|
23
|
+
)
|
|
24
|
+
self.max_yield_ms: int = _parse_int(
|
|
25
|
+
os.environ.get("YIELDSHELL_MAX_YIELD_MS", ""), 300000
|
|
26
|
+
)
|
|
27
|
+
self.default_timeout_ms: int = _parse_int(
|
|
28
|
+
os.environ.get("YIELDSHELL_DEFAULT_TIMEOUT_MS", ""), 0
|
|
29
|
+
)
|
|
30
|
+
self.deny_command_regex: re.Pattern[str] | None = _parse_regex(
|
|
31
|
+
os.environ.get("YIELDSHELL_DENY_COMMAND_REGEX", "")
|
|
32
|
+
)
|
|
33
|
+
self.allow_command_regex: re.Pattern[str] | None = _parse_regex(
|
|
34
|
+
os.environ.get("YIELDSHELL_ALLOW_COMMAND_REGEX", "")
|
|
35
|
+
)
|
|
36
|
+
self.redact_env_regex: re.Pattern[str] = _parse_regex_required(
|
|
37
|
+
os.environ.get("YIELDSHELL_REDACT_ENV_REGEX", ""),
|
|
38
|
+
r"TOKEN|KEY|SECRET|PASSWORD",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _parse_pathsep(value: str) -> list[str]:
|
|
43
|
+
if not value:
|
|
44
|
+
return []
|
|
45
|
+
return [p for p in value.split(os.pathsep) if p]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _parse_int(value: str, default: int) -> int:
|
|
49
|
+
if not value:
|
|
50
|
+
return default
|
|
51
|
+
try:
|
|
52
|
+
return int(value)
|
|
53
|
+
except ValueError:
|
|
54
|
+
return default
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _parse_regex(value: str) -> re.Pattern[str] | None:
|
|
58
|
+
if not value:
|
|
59
|
+
return None
|
|
60
|
+
return re.compile(value)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _parse_regex_required(value: str, default: str) -> re.Pattern[str]:
|
|
64
|
+
if not value:
|
|
65
|
+
return re.compile(default)
|
|
66
|
+
return re.compile(value)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Process management sub-package."""
|