We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/diegofornalha/mcp-shell-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
import streamlit as st
import json
import subprocess
import time
import os
import shlex
import platform
from datetime import datetime
# Classes inspiradas no MCP Shell Server para validação e segurança
class CommandValidator:
"""Simula a validação de comandos do MCP Shell Server"""
def __init__(self, allowed_commands=None):
self.allowed_commands = allowed_commands or []
def is_command_allowed(self, command):
"""Verifica se um comando está na lista de permitidos"""
return command in self.allowed_commands
def validate_no_shell_operators(self, command_str):
"""Detecta operadores shell perigosos"""
shell_operators = [';', '&&', '||', '|', '>', '>>', '<', '<<']
found_operators = []
for op in shell_operators:
if op in command_str:
found_operators.append(op)
return found_operators
def validate_command(self, command_parts):
"""Valida um comando completo"""
if not command_parts:
return False, "Comando vazio"
base_command = command_parts[0]
if not self.is_command_allowed(base_command):
return False, f"Comando não permitido: {base_command}"
# Verificar operadores shell no comando completo
command_str = ' '.join(command_parts)
found_operators = self.validate_no_shell_operators(command_str)
if found_operators:
return False, f"Operadores shell não permitidos: {', '.join(found_operators)}"
return True, ""
class DirectoryManager:
"""Gerencia e valida diretórios de trabalho"""
def validate_directory(self, directory):
"""Valida se um diretório existe e tem permissões"""
if not directory:
return False, "Diretório não especificado"
if not os.path.exists(directory):
return False, f"Diretório não existe: {directory}"
if not os.path.isdir(directory):
return False, f"Não é um diretório: {directory}"
if not os.access(directory, os.R_OK | os.W_OK | os.X_OK):
return False, f"Permissões insuficientes para: {directory}"
return True, ""
class ShellExecutor:
"""Simula o executor shell do MCP"""
def __init__(self, validator, directory_manager):
self.validator = validator
self.directory_manager = directory_manager
def execute(self, command_parts, directory, stdin=None, timeout=None):
"""Executa um comando shell de forma segura"""
# Validar comando
valid_cmd, cmd_error = self.validator.validate_command(command_parts)
if not valid_cmd:
return {
"error": cmd_error,
"status": 1,
"stdout": "",
"stderr": cmd_error,
"execution_time": 0
}
# Validar diretório
valid_dir, dir_error = self.directory_manager.validate_directory(directory)
if not valid_dir:
return {
"error": dir_error,
"status": 1,
"stdout": "",
"stderr": dir_error,
"execution_time": 0
}
# Executar comando
try:
start_time = time.time()
# Preparar processo para entrada stdin se necessário
if stdin:
proc = subprocess.run(
command_parts,
input=stdin,
text=True,
capture_output=True,
timeout=timeout,
cwd=directory
)
else:
proc = subprocess.run(
command_parts,
capture_output=True,
text=True,
timeout=timeout,
cwd=directory
)
execution_time = time.time() - start_time
return {
"stdout": proc.stdout,
"stderr": proc.stderr,
"status": proc.returncode,
"execution_time": execution_time
}
except subprocess.TimeoutExpired:
return {
"error": f"Comando excedeu o tempo limite de {timeout} segundos",
"status": 1,
"stdout": "",
"stderr": f"Timeout após {timeout}s",
"execution_time": timeout
}
except Exception as e:
return {
"error": str(e),
"status": 1,
"stdout": "",
"stderr": str(e),
"execution_time": time.time() - start_time
}
# Configuração da página
st.set_page_config(
page_title="MCP Shell Server Avançado",
page_icon="🔒",
layout="wide"
)
# Título da aplicação
st.title("MCP Shell Server - Demonstração Avançada")
st.write("Uma implementação mais robusta inspirada no código real do MCP Shell Server")
# Sidebar com informações do sistema
st.sidebar.header("Informações do Sistema")
st.sidebar.write(f"**Sistema:** {platform.system()} {platform.release()}")
st.sidebar.write(f"**Python:** {platform.python_version()}")
st.sidebar.write(f"**Data:** {datetime.now().strftime('%d/%m/%Y %H:%M')}")
# Modo de depuração
debug_mode = st.sidebar.checkbox("Modo de depuração")
# Tabs principais
tabs = st.tabs([
"O que é o MCP Shell?",
"Executor de Comandos",
"Validação de Comandos",
"Configuração"
])
# Tab 1: O que é o MCP Shell?
with tabs[0]:
st.header("O que é o MCP Shell Server?")
st.write("""
O MCP Shell Server é um servidor seguro para execução de comandos shell que implementa
o Protocolo de Contexto de Modelo (MCP). Este servidor permite que assistentes de IA
como o Claude executem comandos shell no sistema de forma segura e controlada.
O protocolo MCP (Model Context Protocol) foi desenvolvido pela Anthropic para permitir
que o Claude se comunique com serviços externos e execute ações no sistema operacional.
""")
st.subheader("Arquitetura do MCP Shell Server")
st.write("""
O MCP Shell Server é composto por vários componentes que garantem segurança e flexibilidade:
1. **CommandValidator**: Valida comandos contra uma lista de permitidos e detecta operadores shell perigosos.
2. **DirectoryManager**: Gerencia e valida diretórios de trabalho.
3. **ShellExecutor**: Executa comandos shell de forma segura.
4. **IORedirectionHandler**: Lida com redirecionamento de entrada/saída.
5. **ProcessManager**: Gerencia processos e tempo de execução.
""")
st.subheader("Exemplo de Configuração")
config_json = {
"mcpServers": {
"shell": {
"command": "uvx",
"args": ["mcp-shell-server"],
"env": {
"ALLOW_COMMANDS": "ls,cat,pwd,grep,wc,touch,find"
}
}
}
}
st.code(json.dumps(config_json, indent=2), language="json")
# Tab 2: Executor de Comandos
with tabs[1]:
st.header("Executor de Comandos Avançado")
st.write("""
Esta seção implementa um simulador mais fiel do MCP Shell Server,
com validações e execução de comandos mais robustas.
""")
# Definir comandos permitidos
allowed_commands = st.multiselect(
"Comandos permitidos para teste:",
["ls", "cat", "pwd", "grep", "wc", "touch", "find", "echo", "ps", "date"],
default=["ls", "cat", "pwd", "echo"]
)
# Configurações avançadas
with st.expander("Configurações avançadas"):
col1, col2 = st.columns(2)
with col1:
directory = st.text_input(
"Diretório de trabalho:",
value=os.getcwd(),
help="Diretório onde o comando será executado"
)
with col2:
timeout = st.slider(
"Timeout (segundos):",
min_value=1,
max_value=30,
value=5,
help="Tempo máximo de execução do comando"
)
stdin_input = st.text_area(
"Entrada (stdin):",
value="",
help="Texto a ser passado como entrada para o comando"
)
# Input para comando
st.subheader("Digite um comando para executar:")
command_input = st.text_input("Comando:")
# Parsing e validação do comando
if command_input:
# Inicializar validador e executor
validator = CommandValidator(allowed_commands)
dir_manager = DirectoryManager()
executor = ShellExecutor(validator, dir_manager)
# Processar comando
try:
# Parse do comando respeitando aspas
command_parts = shlex.split(command_input)
base_command = command_parts[0] if command_parts else ""
# Blocos de validação e feedback
st.subheader("Análise do Comando:")
# Validação do comando base
if validator.is_command_allowed(base_command):
st.success(f"✅ Comando base permitido: '{base_command}'")
else:
st.error(f"❌ Comando base não permitido: '{base_command}'")
# Validação de operadores shell
operators = validator.validate_no_shell_operators(command_input)
if operators:
st.warning(f"⚠️ Operadores shell detectados: {', '.join(operators)}")
else:
st.success("✅ Nenhum operador shell detectado")
# Validação do diretório
valid_dir, dir_message = dir_manager.validate_directory(directory)
if valid_dir:
st.success(f"✅ Diretório válido: '{directory}'")
else:
st.error(f"❌ Problema com diretório: {dir_message}")
# Estrutura da requisição
st.subheader("Estrutura da requisição:")
request = {
"command": command_parts,
"directory": directory,
"timeout": timeout
}
if stdin_input:
request["stdin"] = stdin_input
st.json(request)
# Verificar se pode executar
valid_cmd, cmd_message = validator.validate_command(command_parts)
can_execute = valid_cmd and valid_dir
# Botão de execução
if can_execute:
if st.button("Executar Comando"):
with st.spinner(f"Executando '{command_input}' com timeout de {timeout}s..."):
# Executar comando
result = executor.execute(
command_parts,
directory,
stdin_input if stdin_input else None,
timeout
)
# Mostrar resultado
st.subheader("Resultado da Execução:")
st.json(result)
# Mostrar saída se houver
if result.get("stdout"):
st.subheader("Saída (stdout):")
st.code(result["stdout"])
# Mostrar erro se houver
if result.get("stderr"):
st.subheader("Erro (stderr):")
st.code(result["stderr"])
# Modo de depuração
if debug_mode:
st.subheader("Informações de Depuração:")
st.json({
"command_parts": command_parts,
"base_command": base_command,
"valid_dir": valid_dir,
"dir_message": dir_message,
"valid_cmd": valid_cmd,
"cmd_message": cmd_message,
"operators": operators,
"execution_time": result.get("execution_time")
})
else:
if st.button("Simular Resposta de Erro"):
error_msg = cmd_message if not valid_cmd else dir_message
error_response = {
"error": error_msg,
"status": 1,
"stdout": "",
"stderr": error_msg,
"execution_time": 0
}
st.subheader("Resposta de Erro Simulada:")
st.json(error_response)
except Exception as e:
st.error(f"Erro ao processar comando: {str(e)}")
if debug_mode:
st.exception(e)
# Tab 3: Validação de Comandos
with tabs[2]:
st.header("Validação de Comandos")
st.write("""
Esta seção permite testar a validação de comandos sem executá-los.
Você pode ver como o MCP Shell Server valida comandos para garantir a segurança.
""")
# Lista de comandos permitidos para teste
test_allowed_commands = st.multiselect(
"Comandos permitidos para validação:",
["ls", "cat", "pwd", "grep", "wc", "touch", "find", "echo", "ps", "rm", "chmod"],
default=["ls", "cat", "pwd", "echo"]
)
# Campo para testar validação
test_command = st.text_input("Digite um comando para validar:")
if test_command:
# Inicializar validador
test_validator = CommandValidator(test_allowed_commands)
st.subheader("Resultado da Validação:")
try:
# Parse do comando respeitando aspas
test_parts = shlex.split(test_command)
test_base = test_parts[0] if test_parts else ""
# Feedback visual
col1, col2 = st.columns(2)
with col1:
st.write("**Validação do Comando Base:**")
if test_validator.is_command_allowed(test_base):
st.success(f"✅ Comando base permitido: '{test_base}'")
else:
st.error(f"❌ Comando base não permitido: '{test_base}'")
st.write("**Verificação de Operadores Shell:**")
operators = test_validator.validate_no_shell_operators(test_command)
if operators:
st.warning(f"⚠️ Operadores shell detectados: {', '.join(operators)}")
else:
st.success("✅ Nenhum operador shell detectado")
with col2:
st.write("**Validação Completa:**")
valid, message = test_validator.validate_command(test_parts)
if valid:
st.success("✅ Comando válido")
else:
st.error(f"❌ Comando inválido: {message}")
st.write("**Detalhes do Comando:**")
st.json({
"comando_original": test_command,
"comando_parseado": test_parts,
"comando_base": test_base,
"operadores_detectados": operators,
"é_válido": valid,
"mensagem": message or "Comando válido"
})
# Exemplos de validação
with st.expander("Exemplos de Validação"):
st.write("""
**Exemplos de como a validação funciona:**
1. **Comando base não permitido**: `rm -rf /` - Falha porque 'rm' não está na lista de permitidos.
2. **Operadores shell**: `ls && cat file.txt` - Falha devido ao operador '&&'.
3. **Comando vazio**: ` ` - Falha porque o comando está vazio.
4. **Comando válido**: `ls -la` - Passa se 'ls' estiver na lista de permitidos.
""")
except Exception as e:
st.error(f"Erro ao validar comando: {str(e)}")
if debug_mode:
st.exception(e)
# Tab 4: Configuração
with tabs[3]:
st.header("Configuração do MCP Shell Server")
st.write("""
Esta seção mostra como configurar o MCP Shell Server para uso com o Claude.
Você pode personalizar a lista de comandos permitidos e outros parâmetros.
""")
# Lista de comandos permitidos
config_allowed_commands = st.multiselect(
"Selecione os comandos a serem permitidos:",
["ls", "cat", "pwd", "grep", "wc", "touch", "find", "echo", "ps", "date",
"mkdir", "rm", "cp", "mv", "chmod", "chown", "curl", "wget", "head", "tail"],
default=["ls", "cat", "pwd", "grep", "wc", "touch", "find"]
)
# Aviso sobre comandos perigosos
dangerous_commands = ["rm", "chmod", "chown"]
selected_dangerous = [cmd for cmd in config_allowed_commands if cmd in dangerous_commands]
if selected_dangerous:
st.warning(f"""
⚠️ **Atenção:** Você selecionou os seguintes comandos potencialmente perigosos:
**{', '.join(selected_dangerous)}**
Estes comandos podem modificar ou remover arquivos e permissões. Use com cuidado!
""")
# Configuração do Claude Desktop
st.subheader("Configuração para o Claude Desktop")
config_json = {
"mcpServers": {
"shell": {
"command": "uvx",
"args": ["mcp-shell-server"],
"env": {
"ALLOW_COMMANDS": ",".join(config_allowed_commands)
}
}
}
}
st.code(json.dumps(config_json, indent=2), language="json")
st.info("""
Para configurar o Claude Desktop:
1. Edite o arquivo de configuração:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\\Claude\\claude_desktop_config.json`
2. Cole o JSON acima no arquivo.
3. Instale o MCP Shell Server via pip:
```
pip install mcp-shell-server
```
4. Reinicie o Claude Desktop.
""")
# Variáveis de ambiente
st.subheader("Variáveis de Ambiente")
env_vars = f"ALLOW_COMMANDS=\"{','.join(config_allowed_commands)}\""
st.code(f"""
# Para iniciar o servidor manualmente:
{env_vars} uvx mcp-shell-server
# Ou usando pip:
{env_vars} python -m mcp_shell_server
""", language="bash")
# Dicas de segurança
with st.expander("Dicas de Segurança"):
st.write("""
**Recomendações de segurança:**
1. **Princípio do menor privilégio**: Permita apenas os comandos estritamente necessários.
2. **Evite comandos destrutivos**: Comandos como `rm` podem excluir dados importantes.
3. **Teste em ambiente controlado**: Antes de usar em produção, teste em um ambiente seguro.
4. **Monitore a execução**: Mantenha um registro dos comandos executados.
5. **Atualize regularmente**: Mantenha o MCP Shell Server atualizado para receber correções de segurança.
""")
# Rodapé
st.markdown("---")
st.markdown("MCP Shell Server - Demonstração Avançada | Baseada no código real do MCP Shell Server")