cli-mcp-server 0.2.0__tar.gz → 0.2.1__tar.gz

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.
@@ -1,14 +1,15 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: cli-mcp-server
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Command line interface for MCP clients with secure execution and customizable security policies
5
5
  Project-URL: Homepage, https://github.com/MladenSU/cli-mcp-server
6
6
  Project-URL: Documentation, https://github.com/MladenSU/cli-mcp-server#readme
7
7
  Project-URL: Repository, https://github.com/MladenSU/cli-mcp-server.git
8
8
  Project-URL: Bug Tracker, https://github.com/MladenSU/cli-mcp-server/issues
9
9
  Author-email: Mladen <fangs-lever6n@icloud.com>
10
+ License-File: LICENSE
10
11
  Requires-Python: >=3.10
11
- Requires-Dist: mcp>=1.0.0
12
+ Requires-Dist: mcp>=1.1.0
12
13
  Description-Content-Type: text/markdown
13
14
 
14
15
  # CLI MCP Server
@@ -24,6 +25,8 @@ features.
24
25
  ![MCP Protocol](https://img.shields.io/badge/MCP-Compatible-green)
25
26
  [![smithery badge](https://smithery.ai/badge/cli-mcp-server)](https://smithery.ai/protocol/cli-mcp-server)
26
27
 
28
+ <a href="https://glama.ai/mcp/servers/q89277vzl1"><img width="380" height="200" src="https://glama.ai/mcp/servers/q89277vzl1/badge" /></a>
29
+
27
30
  ---
28
31
 
29
32
  # Table of Contents
@@ -226,4 +229,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
226
229
 
227
230
  ---
228
231
 
229
- For more information or support, please open an issue on the project repository.
232
+ For more information or support, please open an issue on the project repository.
@@ -11,6 +11,8 @@ features.
11
11
  ![MCP Protocol](https://img.shields.io/badge/MCP-Compatible-green)
12
12
  [![smithery badge](https://smithery.ai/badge/cli-mcp-server)](https://smithery.ai/protocol/cli-mcp-server)
13
13
 
14
+ <a href="https://glama.ai/mcp/servers/q89277vzl1"><img width="380" height="200" src="https://glama.ai/mcp/servers/q89277vzl1/badge" /></a>
15
+
14
16
  ---
15
17
 
16
18
  # Table of Contents
@@ -213,4 +215,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
213
215
 
214
216
  ---
215
217
 
216
- For more information or support, please open an issue on the project repository.
218
+ For more information or support, please open an issue on the project repository.
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "cli-mcp-server"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Command line interface for MCP clients with secure execution and customizable security policies"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
- dependencies = ["mcp>=1.0.0"]
7
+ dependencies = ["mcp>=1.1.0"]
8
8
  authors = [
9
9
  { name = "Mladen", email = "fangs-lever6n@icloud.com" },
10
10
  ]
@@ -47,6 +47,8 @@ class SecurityConfig:
47
47
  allowed_flags: set[str]
48
48
  max_command_length: int
49
49
  command_timeout: int
50
+ allow_all_commands: bool = False
51
+ allow_all_flags: bool = False
50
52
 
51
53
 
52
54
  class CommandExecutor:
@@ -109,15 +111,15 @@ class CommandExecutor:
109
111
 
110
112
  command, args = parts[0], parts[1:]
111
113
 
112
- # Validate command
113
- if command not in self.security_config.allowed_commands:
114
+ # Validate command if not in allow-all mode
115
+ if not self.security_config.allow_all_commands and command not in self.security_config.allowed_commands:
114
116
  raise CommandSecurityError(f"Command '{command}' is not allowed")
115
117
 
116
118
  # Process and validate arguments
117
119
  validated_args = []
118
120
  for arg in args:
119
121
  if arg.startswith("-"):
120
- if arg not in self.security_config.allowed_flags:
122
+ if not self.security_config.allow_all_flags and arg not in self.security_config.allowed_flags:
121
123
  raise CommandSecurityError(f"Flag '{arg}' is not allowed")
122
124
  validated_args.append(arg)
123
125
  continue
@@ -224,19 +226,28 @@ def load_security_config() -> SecurityConfig:
224
226
  - allowed_flags: Set of permitted command flags/options
225
227
  - max_command_length: Maximum length of command string
226
228
  - command_timeout: Maximum execution time in seconds
229
+ - allow_all_commands: Whether all commands are allowed
230
+ - allow_all_flags: Whether all flags are allowed
227
231
 
228
232
  Environment Variables:
229
- ALLOWED_COMMANDS: Comma-separated list of allowed commands (default: "ls,cat,pwd")
230
- ALLOWED_FLAGS: Comma-separated list of allowed flags (default: "-l,-a,--help")
231
- ALLOWED_PATTERNS: Comma-separated list of patterns (default: "*.txt,*.log,*.md")
233
+ ALLOWED_COMMANDS: Comma-separated list of allowed commands or 'all' (default: "ls,cat,pwd")
234
+ ALLOWED_FLAGS: Comma-separated list of allowed flags or 'all' (default: "-l,-a,--help")
232
235
  MAX_COMMAND_LENGTH: Maximum command string length (default: 1024)
233
236
  COMMAND_TIMEOUT: Command timeout in seconds (default: 30)
234
237
  """
238
+ allowed_commands = os.getenv("ALLOWED_COMMANDS", "ls,cat,pwd")
239
+ allowed_flags = os.getenv("ALLOWED_FLAGS", "-l,-a,--help")
240
+
241
+ allow_all_commands = allowed_commands.lower() == 'all'
242
+ allow_all_flags = allowed_flags.lower() == 'all'
243
+
235
244
  return SecurityConfig(
236
- allowed_commands=set(os.getenv("ALLOWED_COMMANDS", "ls,cat,pwd").split(",")),
237
- allowed_flags=set(os.getenv("ALLOWED_FLAGS", "-l,-a,--help").split(",")),
245
+ allowed_commands=set() if allow_all_commands else set(allowed_commands.split(",")),
246
+ allowed_flags=set() if allow_all_flags else set(allowed_flags.split(",")),
238
247
  max_command_length=int(os.getenv("MAX_COMMAND_LENGTH", "1024")),
239
248
  command_timeout=int(os.getenv("COMMAND_TIMEOUT", "30")),
249
+ allow_all_commands=allow_all_commands,
250
+ allow_all_flags=allow_all_flags,
240
251
  )
241
252
 
242
253
 
@@ -245,13 +256,16 @@ executor = CommandExecutor(allowed_dir=os.getenv("ALLOWED_DIR", ""), security_co
245
256
 
246
257
  @server.list_tools()
247
258
  async def handle_list_tools() -> list[types.Tool]:
259
+ commands_desc = "all commands" if executor.security_config.allow_all_commands else ", ".join(executor.security_config.allowed_commands)
260
+ flags_desc = "all flags" if executor.security_config.allow_all_flags else ", ".join(executor.security_config.allowed_flags)
261
+
248
262
  return [
249
263
  types.Tool(
250
264
  name="run_command",
251
265
  description=(
252
266
  f"Allows command (CLI) execution in the directory: {executor.allowed_dir}\n\n"
253
- f"Available commands: {', '.join(executor.security_config.allowed_commands)}\n"
254
- f"Available flags: {', '.join(executor.security_config.allowed_flags)}\n\n"
267
+ f"Available commands: {commands_desc}\n"
268
+ f"Available flags: {flags_desc}\n\n"
255
269
  "Note: Shell operators (&&, |, >, >>) are not supported."
256
270
  ),
257
271
  inputSchema={
@@ -314,16 +328,19 @@ async def handle_call_tool(name: str, arguments: Optional[Dict[str, Any]]) -> Li
314
328
  return [types.TextContent(type="text", text=f"Error: {str(e)}", error=True)]
315
329
 
316
330
  elif name == "show_security_rules":
331
+ commands_desc = "All commands allowed" if executor.security_config.allow_all_commands else ", ".join(sorted(executor.security_config.allowed_commands))
332
+ flags_desc = "All flags allowed" if executor.security_config.allow_all_flags else ", ".join(sorted(executor.security_config.allowed_flags))
333
+
317
334
  security_info = (
318
335
  "Security Configuration:\n"
319
336
  f"==================\n"
320
337
  f"Working Directory: {executor.allowed_dir}\n"
321
338
  f"\nAllowed Commands:\n"
322
339
  f"----------------\n"
323
- f"{', '.join(sorted(executor.security_config.allowed_commands))}\n"
340
+ f"{commands_desc}\n"
324
341
  f"\nAllowed Flags:\n"
325
342
  f"-------------\n"
326
- f"{', '.join(sorted(executor.security_config.allowed_flags))}\n"
343
+ f"{flags_desc}\n"
327
344
  f"\nSecurity Limits:\n"
328
345
  f"---------------\n"
329
346
  f"Max Command Length: {executor.security_config.max_command_length} characters\n"
@@ -341,10 +358,10 @@ async def main():
341
358
  write_stream,
342
359
  InitializationOptions(
343
360
  server_name="cli-mcp-server",
344
- server_version="0.2.0",
361
+ server_version="0.2.1",
345
362
  capabilities=server.get_capabilities(
346
363
  notification_options=NotificationOptions(),
347
364
  experimental_capabilities={},
348
365
  ),
349
366
  ),
350
- )
367
+ )
@@ -36,14 +36,14 @@ wheels = [
36
36
 
37
37
  [[package]]
38
38
  name = "cli-mcp-server"
39
- version = "0.2.0"
39
+ version = "0.2.1"
40
40
  source = { editable = "." }
41
41
  dependencies = [
42
42
  { name = "mcp" },
43
43
  ]
44
44
 
45
45
  [package.metadata]
46
- requires-dist = [{ name = "mcp", specifier = ">=1.0.0" }]
46
+ requires-dist = [{ name = "mcp", specifier = ">=1.1.0" }]
47
47
 
48
48
  [[package]]
49
49
  name = "click"
@@ -132,7 +132,7 @@ wheels = [
132
132
 
133
133
  [[package]]
134
134
  name = "mcp"
135
- version = "1.0.0"
135
+ version = "1.1.2"
136
136
  source = { registry = "https://pypi.org/simple" }
137
137
  dependencies = [
138
138
  { name = "anyio" },
@@ -142,9 +142,9 @@ dependencies = [
142
142
  { name = "sse-starlette" },
143
143
  { name = "starlette" },
144
144
  ]
145
- sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891 }
145
+ sdist = { url = "https://files.pythonhosted.org/packages/9b/f3/5cf212e60681ea6da0dbb6e0d1bc0ab2dbf5eebc749b69663d46f114fea1/mcp-1.1.2.tar.gz", hash = "sha256:694aa9df7a8641b24953c935eb72c63136dc948981021525a0add199bdfee402", size = 57628 }
146
146
  wheels = [
147
- { url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361 },
147
+ { url = "https://files.pythonhosted.org/packages/df/40/9883eac3718b860d4006eba1920bfcb628f0a1fe37fac46a4f4e391edca6/mcp-1.1.2-py3-none-any.whl", hash = "sha256:a4d32d60fd80a1702440ba4751b847a8a88957a1f7b059880953143e9759965a", size = 36652 },
148
148
  ]
149
149
 
150
150
  [[package]]
File without changes