mseep-cmd-line-mcp 0.5.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.
@@ -0,0 +1,144 @@
1
+ """Session management for the command-line MCP server."""
2
+
3
+ import time
4
+ import os
5
+ from typing import Dict, Any, Set
6
+
7
+
8
+ class SessionManager:
9
+ """Manage user sessions for command permissions."""
10
+
11
+ def __init__(self):
12
+ """Initialize the session manager."""
13
+ self.sessions: Dict[str, Dict[str, Any]] = {}
14
+
15
+ def get_session(self, session_id: str) -> Dict[str, Any]:
16
+ """Get a session by ID, creating it if it doesn't exist.
17
+
18
+ Args:
19
+ session_id: The session ID
20
+
21
+ Returns:
22
+ The session data
23
+ """
24
+ if session_id not in self.sessions:
25
+ self.sessions[session_id] = {
26
+ "created_at": time.time(),
27
+ "last_active": time.time(),
28
+ "approved_commands": set(),
29
+ "approved_command_types": set(),
30
+ "approved_directories": set(), # New: track approved directories
31
+ }
32
+
33
+ # Update last active time
34
+ self.sessions[session_id]["last_active"] = time.time()
35
+ return self.sessions[session_id]
36
+
37
+ def has_command_approval(self, session_id: str, command: str) -> bool:
38
+ """Check if a command has been approved for a session.
39
+
40
+ Args:
41
+ session_id: The session ID
42
+ command: The command to check
43
+
44
+ Returns:
45
+ True if the command has been approved, False otherwise
46
+ """
47
+ session = self.get_session(session_id)
48
+ return command in session["approved_commands"]
49
+
50
+ def has_command_type_approval(self, session_id: str, command_type: str) -> bool:
51
+ """Check if a command type has been approved for a session.
52
+
53
+ Args:
54
+ session_id: The session ID
55
+ command_type: The command type to check
56
+
57
+ Returns:
58
+ True if the command type has been approved, False otherwise
59
+ """
60
+ session = self.get_session(session_id)
61
+ return command_type in session["approved_command_types"]
62
+
63
+ def approve_command(self, session_id: str, command: str) -> None:
64
+ """Approve a command for a session.
65
+
66
+ Args:
67
+ session_id: The session ID
68
+ command: The command to approve
69
+ """
70
+ session = self.get_session(session_id)
71
+ session["approved_commands"].add(command)
72
+
73
+ def approve_command_type(self, session_id: str, command_type: str) -> None:
74
+ """Approve a command type for a session.
75
+
76
+ Args:
77
+ session_id: The session ID
78
+ command_type: The command type to approve
79
+ """
80
+ session = self.get_session(session_id)
81
+ session["approved_command_types"].add(command_type)
82
+
83
+ def has_directory_approval(self, session_id: str, directory: str) -> bool:
84
+ """Check if a directory has been approved for a session.
85
+
86
+ Args:
87
+ session_id: The session ID
88
+ directory: The directory to check
89
+
90
+ Returns:
91
+ True if the directory has been approved, False otherwise
92
+ """
93
+ session = self.get_session(session_id)
94
+ approved_dirs = session["approved_directories"]
95
+
96
+ # Check if the directory or any of its parents have been approved
97
+ for approved_dir in approved_dirs:
98
+ # Exact match
99
+ if directory == approved_dir:
100
+ return True
101
+
102
+ # Check if directory is a subdirectory of an approved directory
103
+ if directory.startswith(approved_dir + os.sep):
104
+ return True
105
+
106
+ return False
107
+
108
+ def approve_directory(self, session_id: str, directory: str) -> None:
109
+ """Approve a directory for a session.
110
+
111
+ Args:
112
+ session_id: The session ID
113
+ directory: The directory to approve
114
+ """
115
+ session = self.get_session(session_id)
116
+ session["approved_directories"].add(directory)
117
+
118
+ def get_approved_directories(self, session_id: str) -> Set[str]:
119
+ """Get all approved directories for a session.
120
+
121
+ Args:
122
+ session_id: The session ID
123
+
124
+ Returns:
125
+ Set of approved directories
126
+ """
127
+ session = self.get_session(session_id)
128
+ return session["approved_directories"]
129
+
130
+ def clean_old_sessions(self, max_age: int = 3600) -> None:
131
+ """Clean up old sessions.
132
+
133
+ Args:
134
+ max_age: Maximum age of sessions in seconds (default: 1 hour)
135
+ """
136
+ now = time.time()
137
+ to_remove = []
138
+
139
+ for session_id, session in self.sessions.items():
140
+ if now - session["last_active"] > max_age:
141
+ to_remove.append(session_id)
142
+
143
+ for session_id in to_remove:
144
+ del self.sessions[session_id]
@@ -0,0 +1,65 @@
1
+ {
2
+ "server": {
3
+ "name": "cmd-line-mcp",
4
+ "version": "0.4.0",
5
+ "description": "MCP server for safely executing command-line tools",
6
+ "log_level": "INFO"
7
+ },
8
+ "security": {
9
+ "session_timeout": 3600,
10
+ "max_output_size": 102400,
11
+ "allow_user_confirmation": true,
12
+ "require_session_id": false,
13
+ "allow_command_separators": true,
14
+ "whitelisted_directories": [
15
+ "~/Downloads",
16
+ "/tmp",
17
+ "/usr/local/share"
18
+ ],
19
+ "auto_approve_directories_in_desktop_mode": false
20
+ },
21
+ "commands": {
22
+ "read": [
23
+ "ls", "pwd", "cat", "less", "head", "tail", "grep",
24
+ "find", "which", "du", "df", "file", "uname", "hostname",
25
+ "uptime", "date", "whoami", "id", "env", "history", "man",
26
+ "info", "help", "sort", "wc"
27
+ ],
28
+ "write": [
29
+ "cp", "mv", "rm", "mkdir", "rmdir", "touch", "chmod", "chown",
30
+ "ln", "echo", "printf", "export", "tar", "gzip", "zip", "unzip",
31
+ "awk", "sed"
32
+ ],
33
+ "system": [
34
+ "ps", "top", "htop", "who", "netstat", "ifconfig", "ping",
35
+ "ssh", "scp", "curl", "wget", "xargs"
36
+ ],
37
+ "blocked": [
38
+ "sudo", "su", "bash", "sh", "zsh", "ksh", "csh", "fish",
39
+ "screen", "tmux", "nc", "telnet", "nmap",
40
+ "dd", "mkfs", "mount", "umount", "shutdown", "reboot",
41
+ "passwd", "chpasswd", "useradd", "userdel", "groupadd", "groupdel",
42
+ "eval", "exec", "source", "."
43
+ ],
44
+ "dangerous_patterns": [
45
+ "rm\\s+-rf\\s+/",
46
+ ">\\s+/dev/(sd|hd|nvme|xvd)",
47
+ ">\\s+/dev/null",
48
+ ">\\s+/etc/",
49
+ ">\\s+/boot/",
50
+ ">\\s+/bin/",
51
+ ">\\s+/sbin/",
52
+ ">\\s+/usr/bin/",
53
+ ">\\s+/usr/sbin/",
54
+ ">\\s+/usr/local/bin/",
55
+ "2>&1",
56
+ "\\$\\(",
57
+ "\\$\\{\\w+\\}",
58
+ "`"
59
+ ]
60
+ },
61
+ "output": {
62
+ "max_size": 102400,
63
+ "format": "text"
64
+ }
65
+ }
@@ -0,0 +1,347 @@
1
+ Metadata-Version: 2.4
2
+ Name: mseep-cmd-line-mcp
3
+ Version: 0.5.0
4
+ Summary: Command-line MCP server for safe command execution
5
+ Home-page:
6
+ Author: mseep
7
+ Author-email: Your Name <your.email@example.com>
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.6
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: mcp>=1.6.0
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
22
+ Requires-Dist: pytest-asyncio>=0.18.0; extra == "dev"
23
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
24
+ Requires-Dist: black>=22.0.0; extra == "dev"
25
+ Dynamic: author
26
+ Dynamic: license-file
27
+ Dynamic: requires-python
28
+
29
+ # Command-Line MCP Server
30
+
31
+ [![PyPI version](https://badge.fury.io/py/cmd-line-mcp.svg)](https://badge.fury.io/py/cmd-line-mcp)
32
+ [![Python Versions](https://img.shields.io/pypi/pyversions/cmd-line-mcp.svg)](https://pypi.org/project/cmd-line-mcp/)
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
34
+
35
+ A secure Model Control Protocol (MCP) server that allows AI assistants to execute terminal commands with controlled directory access and command permissions.
36
+
37
+ ## Overview
38
+
39
+ Command-Line MCP provides a security layer between AI assistants and your terminal. It implements a dual security model:
40
+
41
+ 1. **Command Permissions**: Commands are categorized as read (safe), write (changes data), or system (affects system state), with different approval requirements
42
+ 2. **Directory Permissions**: Commands can only access explicitly whitelisted directories or directories approved during a session
43
+
44
+ AI assistants interact with this server using standardized MCP tools, enabling safe terminal command execution while preventing access to sensitive files or dangerous operations. You can configure the security level from highly restrictive to more permissive based on your needs.
45
+
46
+ ## Key Features
47
+
48
+ | Security | Usability | Integration |
49
+ |----------|-----------|-------------|
50
+ | Directory whitelisting | Command categorization (read/write/system) | Claude Desktop compatibility |
51
+ | Command filtering | Persistent session permissions | Standard MCP protocol |
52
+ | Pattern matching | Command chaining (pipes, etc.) | Auto-approval options |
53
+ | Dangerous command blocking | Intuitive approval workflow | Multiple config methods |
54
+
55
+ ## Supported Commands (out of the box)
56
+
57
+ ### Read Commands
58
+ - `ls`, `pwd`, `cat`, `less`, `head`, `tail`, `grep`, `find`, `which`, `du`, `df`, `file`, `sort`, etc.
59
+
60
+ ### Write Commands
61
+ - `cp`, `mv`, `rm`, `mkdir`, `rmdir`, `touch`, `chmod`, `chown`, etc.
62
+
63
+ ### System Commands
64
+ - `ps`, `top`, `htop`, `who`, `netstat`, `ifconfig`, `ping`, etc.
65
+
66
+ ## Security Architecture
67
+
68
+ The system implements a multi-layered security approach:
69
+
70
+ ```
71
+ ┌───────────────────────────────────────────────────────────────┐
72
+ │ COMMAND-LINE MCP SERVER │
73
+ ├──────────────────┬────────────────────────┬───────────────────┤
74
+ │ COMMAND SECURITY │ DIRECTORY SECURITY │ SESSION SECURITY │
75
+ ├──────────────────┼────────────────────────┼───────────────────┤
76
+ │ ✓ Read commands │ ✓ Directory whitelist │ ✓ Session IDs │
77
+ │ ✓ Write commands │ ✓ Runtime approvals │ ✓ Persistent │
78
+ │ ✓ System commands│ ✓ Path validation │ permissions │
79
+ │ ✓ Blocked list │ ✓ Home dir expansion │ ✓ Auto timeouts │
80
+ │ ✓ Pattern filters│ ✓ Subdirectory check │ ✓ Desktop mode │
81
+ └──────────────────┴────────────────────────┴───────────────────┘
82
+ ```
83
+
84
+ All security features can be configured from restrictive to permissive based on your threat model and convenience requirements.
85
+
86
+ ## Quick Start
87
+
88
+ ```bash
89
+ # Install
90
+ git clone https://github.com/yourusername/cmd-line-mcp.git
91
+ cd cmd-line-mcp
92
+ python -m venv venv
93
+ source venv/bin/activate
94
+ pip install -e .
95
+ cp config.json.example config.json
96
+
97
+ # Run
98
+ cmd-line-mcp # With default config
99
+ cmd-line-mcp --config config.json # With specific config
100
+ ```
101
+
102
+ ### Configuration Options
103
+
104
+ The server supports four configuration methods in order of precedence:
105
+
106
+ 1. **Built-in default configuration** (default_config.json)
107
+ 2. **JSON configuration file** (recommended for customization)
108
+ ```bash
109
+ cmd-line-mcp --config config.json
110
+ ```
111
+ 3. **Environment variables** (for specific overrides)
112
+ ```bash
113
+ export CMD_LINE_MCP_SECURITY_WHITELISTED_DIRECTORIES="~,/tmp"
114
+ ```
115
+ 4. **.env file** (for environment-specific settings)
116
+ ```bash
117
+ cmd-line-mcp --config config.json --env .env
118
+ ```
119
+
120
+ The default configuration is stored in `default_config.json` and is included with the package. You can copy this file to create your own custom configuration.
121
+
122
+ #### Core Configuration Settings
123
+
124
+ ```json
125
+ {
126
+ "security": {
127
+ "whitelisted_directories": ["/home", "/tmp", "~"],
128
+ "auto_approve_directories_in_desktop_mode": false,
129
+ "require_session_id": false,
130
+ "allow_command_separators": true
131
+ },
132
+ "commands": {
133
+ "read": ["ls", "cat", "grep"],
134
+ "write": ["touch", "mkdir", "rm"],
135
+ "system": ["ps", "ping"]
136
+ }
137
+ }
138
+ ```
139
+
140
+ #### Environment Variable Format
141
+
142
+ Environment variables use a predictable naming pattern:
143
+ ```
144
+ CMD_LINE_MCP_<SECTION>_<SETTING>
145
+ ```
146
+
147
+ Examples:
148
+ ```bash
149
+ # Security settings
150
+ export CMD_LINE_MCP_SECURITY_WHITELISTED_DIRECTORIES="/projects,/var/data"
151
+ export CMD_LINE_MCP_SECURITY_AUTO_APPROVE_DIRECTORIES_IN_DESKTOP_MODE=true
152
+
153
+ # Command additions (these merge with defaults)
154
+ export CMD_LINE_MCP_COMMANDS_READ="awk,jq,wc"
155
+ ```
156
+
157
+ ### Claude Desktop Integration
158
+
159
+ #### Setup
160
+
161
+ 1. Install [Claude for Desktop](https://claude.ai/download)
162
+ 2. Configure in `~/Library/Application Support/Claude/claude_desktop_config.json`:
163
+
164
+ ```json
165
+ {
166
+ "mcpServers": {
167
+ "cmd-line": {
168
+ "command": "/path/to/venv/bin/cmd-line-mcp",
169
+ "args": ["--config", "/path/to/config.json"],
170
+ "env": {
171
+ "CMD_LINE_MCP_SECURITY_REQUIRE_SESSION_ID": "false",
172
+ "CMD_LINE_MCP_SECURITY_AUTO_APPROVE_DIRECTORIES_IN_DESKTOP_MODE": "true"
173
+ }
174
+ }
175
+ }
176
+ }
177
+ ```
178
+
179
+ #### Recommended Claude Desktop Settings
180
+
181
+ For best experience, configure:
182
+ - `require_session_id: false` - Essential to prevent approval loops
183
+ - `auto_approve_directories_in_desktop_mode: true` - Optional for convenient access
184
+ - Include common directories in your whitelist
185
+
186
+ After configuration, restart Claude for Desktop.
187
+
188
+ ## AI Assistant Tools
189
+
190
+ The server provides these MCP tools for AI assistants:
191
+
192
+ | Tool | Purpose | Needs Approval |
193
+ |------|---------|----------------|
194
+ | `execute_command` | Run any command type | Yes, for write/system commands |
195
+ | `execute_read_command` | Run read-only commands | Directory approval only |
196
+ | `approve_directory` | Grant access to a directory | N/A - it's an approval tool |
197
+ | `approve_command_type` | Grant permission for command category | N/A - it's an approval tool |
198
+ | `list_directories` | Show authorized directories | No |
199
+ | `list_available_commands` | Show command categories | No |
200
+ | `get_command_help` | Get command usage guidance | No |
201
+ | `get_configuration` | View current settings | No |
202
+
203
+ ### Tool Examples
204
+
205
+ #### Directory Management
206
+
207
+ ```python
208
+ # Check available directories
209
+ dirs = await list_directories(session_id="session123")
210
+ whitelisted = dirs["whitelisted_directories"]
211
+ approved = dirs["session_approved_directories"]
212
+
213
+ # Request permission for a directory
214
+ if "/projects/my-data" not in whitelisted and "/projects/my-data" not in approved:
215
+ result = await approve_directory(
216
+ directory="/projects/my-data",
217
+ session_id="session123"
218
+ )
219
+ ```
220
+
221
+ #### Command Execution
222
+
223
+ ```python
224
+ # Read commands (read permissions enforced)
225
+ result = await execute_read_command("ls -la ~/Documents")
226
+
227
+ # Any command type (may require command type approval)
228
+ result = await execute_command(
229
+ command="mkdir -p ~/Projects/new-folder",
230
+ session_id="session123"
231
+ )
232
+ ```
233
+
234
+ #### Get Configuration
235
+
236
+ ```python
237
+ # Check current settings
238
+ config = await get_configuration()
239
+ whitelist = config["directory_whitelisting"]["whitelisted_directories"]
240
+ ```
241
+
242
+
243
+ ## Directory Security System
244
+
245
+ The server restricts command execution to specific directories, preventing access to sensitive files.
246
+
247
+ ### Directory Security Modes
248
+
249
+ The system supports three security modes:
250
+
251
+ | Mode | Description | Best For | Configuration |
252
+ |------|-------------|----------|--------------|
253
+ | **Strict** | Only whitelisted directories allowed | Maximum security | `auto_approve_directories_in_desktop_mode: false` |
254
+ | **Approval** | Non-whitelisted directories require explicit approval | Interactive use | Default behavior for standard clients |
255
+ | **Auto-approve** | Auto-approves directories for Claude Desktop | Convenience | `auto_approve_directories_in_desktop_mode: true` |
256
+
257
+ ### Whitelisted Directory Configuration
258
+
259
+ ```json
260
+ "security": {
261
+ "whitelisted_directories": [
262
+ "/home", // System directories
263
+ "/tmp",
264
+ "~", // User's home
265
+ "~/Documents" // Common user directories
266
+ ],
267
+ "auto_approve_directories_in_desktop_mode": false // Set to true for convenience
268
+ }
269
+ ```
270
+
271
+ ### Directory Approval Flow
272
+
273
+ 1. Command is requested in a directory
274
+ 2. System checks:
275
+ - Is the directory in the global whitelist? → **Allow**
276
+ - Has directory been approved in this session? → **Allow**
277
+ - Neither? → **Request approval**
278
+ 3. After approval, directory remains approved for the entire session
279
+
280
+ ### Path Format Support
281
+
282
+ - Absolute paths: `/home/user/documents`
283
+ - Home directory: `~` (expands to user's home)
284
+ - User subdirectories: `~/Downloads`
285
+
286
+ ### Claude Desktop Integration
287
+
288
+ The server maintains a persistent session for Claude Desktop, ensuring directory approvals persist between requests and preventing approval loops.
289
+
290
+ ## Command Customization
291
+
292
+ The system uses command categorization to control access:
293
+
294
+ | Category | Description | Example Commands | Requires Approval |
295
+ |----------|-------------|------------------|-------------------|
296
+ | Read | Safe operations | ls, cat, find | No |
297
+ | Write | Data modification | mkdir, rm, touch | Yes |
298
+ | System | System operations | ps, ping, ifconfig | Yes |
299
+ | Blocked | Dangerous commands | sudo, bash, eval | Always denied |
300
+
301
+ ### Customization Methods
302
+
303
+ ```json
304
+ // In config.json
305
+ {
306
+ "commands": {
307
+ "read": ["ls", "cat", "grep", "awk", "jq"],
308
+ "write": ["mkdir", "touch", "rm"],
309
+ "system": ["ping", "ifconfig", "kubectl"],
310
+ "blocked": ["sudo", "bash", "eval"]
311
+ }
312
+ }
313
+ ```
314
+
315
+ **Environment Variable Method:**
316
+ ```bash
317
+ # Add to existing lists, not replace (comma-separated)
318
+ export CMD_LINE_MCP_COMMANDS_READ="awk,jq"
319
+ export CMD_LINE_MCP_COMMANDS_BLOCKED="npm,pip"
320
+ ```
321
+
322
+ The MCP server merges these additions with existing commands, letting you extend functionality without recreating complete command lists.
323
+
324
+ ### Command Chaining
325
+
326
+ The server supports three command chaining methods:
327
+
328
+ | Method | Symbol | Example | Config Setting |
329
+ |--------|--------|---------|---------------|
330
+ | Pipes | `\|` | `ls \| grep txt` | `allow_command_separators: true` |
331
+ | Sequence | `;` | `mkdir dir; cd dir` | `allow_command_separators: true` |
332
+ | Background | `&` | `find . -name "*.log" &` | `allow_command_separators: true` |
333
+
334
+ All commands in a chain must be from the supported command list. Security checks apply to the entire chain.
335
+
336
+ **Quick Configuration:**
337
+ ```json
338
+ "security": {
339
+ "allow_command_separators": true // Set to false to disable all chaining
340
+ }
341
+ ```
342
+
343
+ To disable specific separators, add them to the `dangerous_patterns` list.
344
+
345
+ ## License
346
+
347
+ MIT
@@ -0,0 +1,12 @@
1
+ cmd_line_mcp/__init__.py,sha256=UKEzBWEKLg9mcsuPrnA2q2Uvx02u-3lcg9v4NGKjeiU,81
2
+ cmd_line_mcp/config.py,sha256=2S6peOVFlKLHvwIQ8I-hI17swf4fVWczO8PFxPJ82gA,15569
3
+ cmd_line_mcp/security.py,sha256=DxxL_6SJX2y2FQXlIsxRk8yuPE0N-YrdfV2FxLBxYhk,15690
4
+ cmd_line_mcp/server.py,sha256=G5nvGBHt3myESqF2xqlBKUpgRlI8kuPxUtAPHNG-SQo,41215
5
+ cmd_line_mcp/session.py,sha256=mSb9LOisKymiXXEr7LDl4kEl0jVEDEiH6_0tMEE9_a8,4664
6
+ mseep_cmd_line_mcp-0.5.0.data/data/default_config.json,sha256=AVBNID4Yijq3ZXwHYJL_t70oqnfj8g8TwwqV-5ODgSw,1804
7
+ mseep_cmd_line_mcp-0.5.0.dist-info/licenses/LICENSE,sha256=aOVb-txipM-E8cp9jtNoqJE4l6yz3T05ZsZmQeYHaPI,1067
8
+ mseep_cmd_line_mcp-0.5.0.dist-info/METADATA,sha256=kA1SfW1Lo0ChmxC6EM5RaAaEy_HQv2kctsD3NPtU-wQ,12306
9
+ mseep_cmd_line_mcp-0.5.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
10
+ mseep_cmd_line_mcp-0.5.0.dist-info/entry_points.txt,sha256=7ufnALgZOundGRNHoaR2OxIo7v_OVsHLV9qVjUyGVdI,58
11
+ mseep_cmd_line_mcp-0.5.0.dist-info/top_level.txt,sha256=TNbegkhclSa2OO_Era8636j0ZvCn2DS0XaYutU5UM7s,13
12
+ mseep_cmd_line_mcp-0.5.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (78.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cmd-line-mcp = cmd_line_mcp.server:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 [Your Name]
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.
@@ -0,0 +1 @@
1
+ cmd_line_mcp