Pybullet MCP Server

Um servidor mcp para a biblioteca pybullet, que suporta 20 ferramentas (ex: criação de simulação, passos, carregamento de urdf de robôs, etc)

Documentação

PyBullet MCP Server

Um servidor Model Context Protocol (MCP) que permite que assistentes de IA interajam com simulações de física do PyBullet. Crie projetos baseados em física por meio de interações em linguagem natural com agentes de IA.

Recursos

  • 37 Ferramentas MCP: API abrangente para controle de simulações de física, incluindo controle de juntas de robôs
  • Gerenciamento de Simulações: Crie e gerencie múltiplas simulações de física independentes com gravidade configurável
  • Manipulação de Objetos: Adicione formas primitivas (caixa, esfera, cilindro, cápsula) e modelos URDF com controle completo de propriedades
  • Controle de Robôs: Consulte informações de juntas, controle motores (posição/velocidade/torque) e calcule cinemática inversa
  • Controle de Física: Aplique forças, torques e avance nas simulações com passos de tempo configuráveis
  • Persistência de Estado: Salve e carregue estados completos de simulação em/de arquivos JSON
  • Restrições: Crie juntas entre objetos (fixa, prismática, esférica)
  • Detecção de Colisão: Consulte pontos de contato com informações detalhadas de colisão
  • Visualização: Modo GUI opcional com visualização de depuração e controle de câmera
  • Tratamento de Erros: Validação abrangente com mensagens de erro descritivas

Notas Importantes

  • Requisitos de Coordenadas: Todos os vetores devem ser fornecidos como coordenadas 3D completas [x, y, z]
    • Gravidade: [0, 0, -9.81] (não [-9.81])
    • Posições: [x, y, z] (não [x, y] ou [x])
    • Forças/Torques: [fx, fy, fz] (não [fx])
    • Orientações: quaternion [x, y, z, w] (não [w])
  • Restrição de Massa: A massa do objeto deve ser positiva (massa > 0). Use massa grande (ex.: 1000) para objetos estáticos
  • Limitação do GUI: Apenas uma simulação GUI pode estar ativa por vez (limitação do PyBullet)
  • Caminhos URDF: Use caminhos absolutos ou caminhos relativos ao diretório de trabalho do servidor
  • Juntas Revolutas: create_constraint não suporta "revolute" — use generate_revolute_joint + load_urdf em vez disso. Sempre passe um output_path explícito dentro do workspace para generate_revolute_joint; caso contrário, o URDF gerado vai parar em /tmp/ e load_urdf o rejeitará.

Instalação

Pré-requisitos

  • Python 3.9 ou superior
  • Gerenciador de pacotes pip
  • Ambiente virtual (recomendado)

Instalar Dependências

  1. Crie e ative um ambiente virtual:
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Instale FastMCP e PyBullet:
pip install fastmcp pybullet
  1. Para desenvolvimento (inclui ferramentas de teste):
pip install fastmcp pybullet pytest hypothesis pytest-cov

Verificar Instalação

Verifique se os pacotes necessários estão instalados:

python -c "import pybullet; import mcp; print('Installation successful!')"

Início Rápido

Executando o Servidor

Consulte QUICKSTART.md para instruções detalhadas sobre:

  • Iniciar o servidor
  • Configurar o Claude Desktop
  • Exemplos de prompts para explorar todos os recursos
  • Fluxos de trabalho e casos de uso comuns

Comando rápido:

source venv/bin/activate  # On Windows: venv\Scripts\activate
python -m src.server

O servidor iniciará e aguardará conexões de protocolo MCP de assistentes de IA.

Exemplo de Uso com Cliente MCP

Uma vez conectado a um cliente MCP (como o Claude Desktop), você pode interagir por meio de linguagem natural:

1. Crie uma simulação:

Create a new physics simulation with Earth gravity

Isso chama create_simulation com gravidade [0, 0, -9.81].

Importante: A gravidade deve ser um vetor 3D. O servidor aceita abreviações como [-9.81] e as expande para [0, 0, -9.81].

2. Adicione objetos:

Add a red box at position (0, 0, 1) with dimensions 0.5x0.5x0.5 and mass 1.0

Isso chama add_box para criar um objeto caixa. A posição é automaticamente expandida para [0, 0, 1].

Add a sphere at (2, 0, 1) with radius 0.3

Isso chama add_sphere para criar uma esfera.

Nota: A massa deve ser positiva. Para objetos estáticos (como planos de chão), use valores de massa grandes (ex.: 1000).

3. Execute a simulação:

Step the simulation forward 100 times

Isso chama step_simulation com steps=100.

4. Consulte o estado do objeto:

What is the position and velocity of object 0?

Isso chama get_object_state para recuperar posição, orientação e velocidades.

5. Aplique forças:

Apply a force of [10, 0, 0] to object 0

Isso chama apply_force para empurrar o objeto.

6. Salve a simulação:

Save the current simulation state to simulation.json

Isso chama save_simulation para persistir o estado.

7. Carregue uma simulação:

Load the simulation from simulation.json

Isso chama load_simulation para restaurar o estado salvo.

Configuração do MCP

Para usar este servidor com o Cursor ou qualquer outro cliente compatível com MCP, adicione o seguinte ao seu arquivo de configuração MCP:

{
  "mcpServers": {
    "pybullet": {
      "url": "http://localhost:8000/mcp",
      "disabled": false
    }
  }
}

O servidor executa transporte HTTP por padrão. Você pode alterar o método de transporte editando o ponto de entrada em server.py:

if __name__ == "__main__":
    mcp.run(transport="http", port=8000)

Reinicie seu cliente MCP após atualizar a configuração.

Ferramentas Disponíveis

O servidor expõe 37 ferramentas por meio do protocolo MCP:

Gerenciamento de Simulações (5 ferramentas)

  • create_simulation: Inicialize uma nova simulação de física com gravidade configurável e GUI opcional

    • Parâmetros: gravity (list[float], padrão: [0, 0, -9.81]), gui (bool, padrão: false)
    • Retorna: simulation_id, gravity, gui_enabled
  • list_simulations: Obtenha todos os IDs de simulação ativos

    • Retorna: lista de IDs de simulação
  • destroy_simulation: Limpe e remova uma simulação

    • Parâmetros: sim_id (str)
    • Retorna: mensagem de confirmação
  • step_simulation: Avance a simulação em um ou mais passos de tempo

    • Parâmetros: sim_id (str), steps (int, padrão: 1)
    • Retorna: simulation_id, steps_taken, current_time
  • set_timestep: Configure a duração do passo de tempo para uma simulação

    • Parâmetros: sim_id (str), timestep (float)
    • Retorna: mensagem de confirmação

Operações com Objetos (9 ferramentas)

  • add_box: Adicione uma forma de caixa à simulação

    • Parâmetros: sim_id, dimensions (list[float]), position (list[float]), mass (float, padrão: 1.0), color (list[float], opcional)
    • Retorna: object_id, shape, position
  • add_sphere: Adicione uma forma de esfera à simulação

    • Parâmetros: sim_id, radius (float), position (list[float]), mass (float, padrão: 1.0), color (list[float], opcional)
    • Retorna: object_id, shape, position
  • add_cylinder: Adicione uma forma de cilindro à simulação

    • Parâmetros: sim_id, radius (float), height (float), position (list[float]), mass (float, padrão: 1.0), color (list[float], opcional)
    • Retorna: object_id, shape, position
  • add_capsule: Adicione uma forma de cápsula à simulação

    • Parâmetros: sim_id, radius (float), height (float), position (list[float]), mass (float, padrão: 1.0), color (list[float], opcional)
    • Retorna: object_id, shape, position
  • load_urdf: Carregue um modelo de robô de um arquivo URDF

    • Parâmetros: sim_id, file_path (str), position (list[float]), orientation (list[float], opcional)
    • Retorna: object_id, file_path, position
  • set_object_pose: Atualize a posição e a orientação do objeto

    • Parâmetros: sim_id, object_id (int), position (list[float]), orientation (list[float])
    • Retorna: mensagem de confirmação
  • get_object_state: Consulte o estado completo do objeto

    • Parâmetros: sim_id, object_id (int)
    • Retorna: position, orientation, linear_velocity, angular_velocity
  • apply_force: Aplique um vetor de força a um objeto

    • Parâmetros: sim_id, object_id (int), force (list[float]), position (list[float], opcional)
    • Retorna: mensagem de confirmação
  • apply_torque: Aplique força rotacional a um objeto

    • Parâmetros: sim_id, object_id (int), torque (list[float])
    • Retorna: mensagem de confirmação
  • set_object_velocity: Defina a velocidade linear e/ou angular de um objeto diretamente

    • Parâmetros: sim_id, object_id (int), linear_velocity (list[float], opcional), angular_velocity (list[float], opcional)
    • Retorna: mensagem de confirmação
  • change_dynamics: Modifique as propriedades físicas do objeto em tempo de execução

    • Parâmetros: sim_id, object_id (int), link_index (int, padrão: -1), mass (float, opcional), lateral_friction (float, opcional), spinning_friction (float, opcional), rolling_friction (float, opcional), restitution (float, opcional), linear_damping (float, opcional), angular_damping (float, opcional), contact_stiffness (float, opcional), contact_damping (float, opcional)
    • Retorna: mensagem de confirmação
  • get_dynamics_info: Consulte as propriedades dinâmicas atuais de um objeto

    • Parâmetros: sim_id, object_id (int), link_index (int, padrão: -1)
    • Retorna: mass, lateral_friction, local_inertia_diagonal, restitution, rolling_friction, spinning_friction, contact_damping, contact_stiffness, body_type, collision_margin

Lançamento de Raios (2 ferramentas)

  • ray_test: Lance um único raio para detectar obstáculos e medir distâncias

    • Parâmetros: sim_id, ray_from (list[float]), ray_to (list[float])
    • Retorna: hit (bool), object_id, link_index, hit_fraction, hit_position, hit_normal
  • ray_test_batch: Lance múltiplos raios de forma eficiente para simulação de lidar/sensores

    • Parâmetros: sim_id, rays_from (list[list[float]]), rays_to (list[list[float]])
    • Retorna: lista de resultados de colisão (mesmos campos do ray_test por raio)

Renderização de Câmera (4 ferramentas)

  • compute_view_matrix: Calcule a matriz de visão a partir dos vetores eye/target/up da câmera

    • Parâmetros: camera_eye_position (list[float]), camera_target_position (list[float]), camera_up_vector (list[float])
    • Retorna: matriz de visão como lista de 16 floats
  • compute_view_matrix_from_yaw_pitch: Calcule a matriz de visão a partir de coordenadas esféricas (câmera orbital)

    • Parâmetros: distance (float), yaw (float), pitch (float), target_position (list[float]), up_axis_index (int, padrão: 2)
    • Retorna: matriz de visão como lista de 16 floats
  • compute_projection_matrix: Calcule a matriz de projeção a partir dos parâmetros da câmera

    • Parâmetros: fov (float), aspect (float), near_plane (float), far_plane (float)
    • Retorna: matriz de projeção como lista de 16 floats
  • get_camera_image: Renderize imagens RGB, profundidade e segmentação a partir de uma câmera virtual

    • Parâmetros: sim_id, width (int), height (int), view_matrix (list[float]), projection_matrix (list[float]), renderer (str, padrão: "ER_BULLET_HARDWARE_OPENGL")
    • Retorna: width, height, rgb (base64 PNG), depth (list[float]), segmentation (list[int])

Gerenciamento de Restrições (2 ferramentas)

  • create_constraint: Crie uma junta entre dois objetos

    • Parâmetros: sim_id, parent_id (int), child_id (int), joint_type (str), joint_axis (list[float], opcional), parent_frame_position (list[float], opcional), child_frame_position (list[float], opcional)
    • Tipos de junta: "fixed", "prismatic", "spherical"
    • Retorna: constraint_id, joint_type
    • Nota: "revolute" NÃO é suportado aqui — use generate_revolute_joint + load_urdf em vez disso.
  • remove_constraint: Remova uma restrição da simulação

    • Parâmetros: sim_id, constraint_id (int)
    • Retorna: mensagem de confirmação

Juntas Revolutas (Dobradiça) — Solução Alternativa

A API de restrições em tempo de execução do PyBullet não suporta juntas revolutas. A solução alternativa é um processo de duas etapas usando estas duas ferramentas: Etapa 1 — Gerar um URDF com a junta rotativa:

  • generate_revolute_joint: Gera um arquivo URDF contendo duas formas conectadas por uma junta rotativa
    • Parâmetros: parent_shape (str: "box"/"sphere"/"cylinder"), child_shape (str), parent_dimensions (list[float]), child_dimensions (list[float]), parent_mass (float), child_mass (float), joint_axis (list[float]), joint_origin (list[float], opcional), joint_lower_limit (float, padrão: -π), joint_upper_limit (float, padrão: π), max_effort (float), max_velocity (float), output_path (str)
    • Retorna: urdf_path, parent_shape, child_shape, joint_type, joint_axis, joint_limits
    • output_path deve ser definido para um caminho dentro do diretório de trabalho do servidor. Se omitido, o arquivo é gravado no diretório temporário do sistema (/tmp/), que está fora do caminho permitido e fará load_urdf falhar com um erro de acesso negado.

Etapa 2 — Carregar o URDF gerado:

  • Chame load_urdf com o urdf_path retornado de generate_revolute_joint
  • Em seguida, use set_joint_motor_control para acionar a junta

Detecção de Colisão (2 ferramentas)

  • get_all_collisions: Consulta todos os pontos de contato na simulação

    • Parâmetros: sim_id
    • Retorna: lista de pontos de contato com posições, normais e forças
  • get_collisions_for_pair: Consulta pontos de contato entre objetos específicos

    • Parâmetros: sim_id, obj_a (int), obj_b (int)
    • Retorna: lista de pontos de contato para o par

Visualização (2 ferramentas)

  • enable_debug_visualization: Habilita a renderização de depuração de pontos de contato e referenciais

    • Parâmetros: sim_id, show_contacts (bool, padrão: true), show_frames (bool, padrão: false)
    • Retorna: mensagem de confirmação
  • set_camera: Configura a posição da câmera e o alvo para o modo GUI

    • Parâmetros: sim_id, distance (float), yaw (float), pitch (float), target (list[float])
    • Retorna: mensagem de confirmação

Persistência (2 ferramentas)

  • save_simulation: Salva o estado da simulação em um arquivo JSON

    • Parâmetros: sim_id, file_path (str)
    • Retorna: confirmação com o caminho do arquivo
  • load_simulation: Carrega o estado da simulação de um arquivo JSON

    • Parâmetros: file_path (str), gui (bool, padrão: false)
    • Retorna: novo simulation_id, file_path

Controle de Robô (5 ferramentas)

  • get_num_joints: Consulta o número de juntas em um modelo URDF

    • Parâmetros: sim_id (str), object_id (int)
    • Retorna: número de juntas (int)
  • get_joint_info: Obtém propriedades detalhadas da junta

    • Parâmetros: sim_id (str), object_id (int), joint_index (int)
    • Retorna: joint_name, joint_type, lower_limit, upper_limit, max_force, max_velocity, joint_axis
  • get_joint_state: Obtém o estado atual da junta

    • Parâmetros: sim_id (str), object_id (int), joint_index (int)
    • Retorna: joint_position, joint_velocity, reaction_forces, motor_torque
  • set_joint_motor_control: Controla as juntas do robô

    • Parâmetros: sim_id (str), object_id (int), joint_index (int), control_mode (str), target_position (float, opcional), target_velocity (float, opcional), force (float, opcional), position_gain (float, opcional), velocity_gain (float, opcional)
    • Modos de controle: "POSITION_CONTROL", "VELOCITY_CONTROL", "TORQUE_CONTROL"
    • Retorna: mensagem de confirmação
  • calculate_inverse_kinematics: Calcula os ângulos das juntas para a pose alvo do efetuador final

    • Parâmetros: sim_id (str), object_id (int), end_effector_link_index (int), target_position (list[float]), target_orientation (list[float], opcional), lower_limits (list[float], opcional), upper_limits (list[float], opcional), joint_ranges (list[float], opcional), rest_poses (list[float], opcional)
    • Retorna: lista de posições das juntas

Exemplos de Fluxos de Trabalho

Caixa Caindo Básica

Crie uma simulação simples com uma caixa caindo sob gravidade:

# Through MCP client (natural language):
"Create a simulation with Earth gravity"
"Add a box at position (0, 0, 5) with dimensions 1x1x1"
"Step the simulation 200 times"
"What is the position of object 0?"

Objetos Empilhados

Crie uma pilha de objetos:

"Create a simulation"
"Add a box at (0, 0, 0.5) with dimensions 10x10x1 and mass 1000"  # Ground
"Add a box at (0, 0, 1.5) with dimensions 1x1x1"
"Add a sphere at (0, 0, 3) with radius 0.5"
"Step the simulation 300 times"
"Get all collisions"

Objetos com Restrições

Crie objetos conectados por uma junta:

"Create a simulation"
"Add a box at (0, 0, 2) with dimensions 1x1x1"  # Object 0
"Add a sphere at (2, 0, 2) with radius 0.5"     # Object 1
"Create a fixed constraint between object 0 and object 1"
"Apply a torque of [0, 0, 10] to object 1"
"Step the simulation 200 times"

Salvar e Carregar

Persista uma simulação:

"Create a simulation"
"Add a box at (0, 0, 1)"
"Add a sphere at (1, 0, 1)"
"Step the simulation 50 times"
"Save the simulation to my_sim.json"

# Later...
"Load the simulation from my_sim.json"
"Step the simulation 50 more times"

Simulação de Robô

Carregue e controle um modelo de robô URDF:

"Create a simulation with GUI enabled"
"Load URDF from /path/to/robot.urdf at position (0, 0, 1)"
"How many joints does object 0 have?"
"Get information about joint 0 of object 0"
"Get the current state of joint 0"
"Set joint 0 to position 1.57 with position control and force 100"
"Step the simulation 100 times"
"Get the state of joint 0 again to see it moved"
"Calculate inverse kinematics for object 0 end-effector link 6 at position [0.5, 0, 0.5]"

Recursos de Controle de Robô:

  • Consultar o número de juntas e propriedades das juntas (tipo, limites, eixo)
  • Ler estados das juntas (posição, velocidade, forças, torque)
  • Controlar juntas com três modos:
    • Controle de posição: Move a junta para o ângulo/posição alvo
    • Controle de velocidade: Gira a junta na velocidade alvo
    • Controle de torque: Aplica torque diretamente à junta
  • Calcular cinemática inversa para posicionamento do efetuador final

Formato de Arquivo de Persistência

Os estados da simulação são salvos como arquivos JSON com a seguinte estrutura:

{
  "gravity": [0.0, 0.0, -9.81],
  "timestep": 0.01,
  "objects": [
    {
      "object_id": 0,
      "type": "primitive",
      "shape": "box",
      "dimensions": [0.5, 0.5, 0.5],
      "position": [0.0, 0.0, 1.0],
      "orientation": [0.0, 0.0, 0.0, 1.0],
      "linear_velocity": [0.0, 0.0, -0.98],
      "angular_velocity": [0.0, 0.0, 0.0],
      "mass": 1.0,
      "color": [1.0, 0.0, 0.0, 1.0]
    },
    {
      "object_id": 1,
      "type": "urdf",
      "urdf_path": "/path/to/model.urdf",
      "position": [2.0, 0.0, 0.5],
      "orientation": [0.0, 0.0, 0.0, 1.0],
      "linear_velocity": [0.0, 0.0, 0.0],
      "angular_velocity": [0.0, 0.0, 0.0]
    }
  ],
  "constraints": [
    {
      "constraint_id": 0,
      "parent_id": 0,
      "child_id": 1,
      "joint_type": "fixed"
    }
  ]
}

Notas de Compatibilidade

  • IDs de Objetos: Os IDs de objetos são reatribuídos ao carregar (podem diferir dos IDs salvos)
  • Arquivos URDF: Os caminhos dos arquivos URDF devem ser válidos ao carregar. Use caminhos absolutos para maior confiabilidade
  • ID da Simulação: Um novo ID de simulação é gerado ao carregar
  • Versão do Formato: O formato atual é compatível com PyBullet 3.2.5+
  • Restrições: As restrições são totalmente serializadas e restauradas

Problemas Comuns e Soluções

Erros de Coordenadas

Problema: "force needs a 3 coordinates [x,y,z]" ou erros semelhantes

Solução: Sempre forneça vetores 3D completos:

# Wrong
gravity = [-9.81]
position = [1, 2]
force = [10]

# Correct
gravity = [0, 0, -9.81]
position = [1, 2, 0]
force = [10, 0, 0]

Erro de Validação de Massa

Problema: "Mass must be positive, got 0.0"

Solução: O PyBullet requer massa positiva. Para objetos estáticos, use massa grande:

# Wrong
add_box(mass=0)  # Error!

# Correct
add_box(mass=1000)  # Heavy static object

Janela GUI Não Aparece

Problema: A janela GUI não aparece quando gui=true

Solução:

  • Apenas uma simulação GUI é permitida por instância do servidor
  • Destrua a simulação GUI existente antes de criar uma nova
  • Alguns ambientes (Docker, SSH sem X11) não suportam GUI
  • No Linux, garanta que o X11 esteja disponível: echo $DISPLAY

Falha no Carregamento do URDF

Problema: "Failed to load URDF: File not found"

Solução:

  • Use caminhos absolutos: /full/path/to/robot.urdf
  • Ou use caminhos relativos ao diretório de trabalho do servidor
  • Verifique se o arquivo existe: ls -la /path/to/robot.urdf
  • Confirme que os arquivos de malha referenciados no URDF também estejam acessíveis

Objetos Caem Através do Chão

Problema: Os objetos passam pelo plano do chão

Solução:

  • Certifique-se de estar avançando a simulação: step_simulation(steps=100)
  • Use um passo de tempo adequado (o padrão 0.01 geralmente é bom)
  • Dê ao plano do chão dimensões grandes e massa alta (ex.: 1000)
  • Verifique se os objetos têm massa positiva

Solução de Problemas

Problemas Comuns

1. Erros de importação ao iniciar o servidor

ModuleNotFoundError: No module named 'mcp' or 'pybullet'

Solução: Certifique-se de que seu ambiente virtual esteja ativado e as dependências estejam instaladas:

source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install fastmcp pybullet

2. Erros de versão do Python

SyntaxError or version compatibility issues

Solução: Verifique a versão do Python (deve ser 3.9+):

python --version

Se necessário, crie um venv com uma versão específica do Python:

python3.9 -m venv venv

3. GUI do PyBullet não aparece

GUI window doesn't appear when gui=true

Solução:

  • O modo GUI deve ser explicitamente habilitado: create_simulation(gui=true)
  • Alguns sistemas (servidores, Docker) não suportam o modo GUI — use o modo headless
  • No Linux, garanta que o X11 esteja disponível: echo $DISPLAY

4. Erros de permissão de arquivo

PermissionError when saving/loading simulations

Solução:

  • Garanta permissões de escrita no diretório de destino
  • Use caminhos absolutos: /full/path/to/simulation.json
  • Verifique o espaço em disco: df -h

5. O cliente MCP não consegue se conectar ao servidor

Server not responding

Solução:

  • Verifique se o servidor está em execução: python -m src.server
  • Confirme se a URL na sua configuração MCP corresponde à porta do servidor (padrão: http://localhost:8000/mcp)
  • Reinicie o cliente MCP após alterações na configuração
  • Verifique a saída do terminal do servidor para mensagens de erro

6. A simulação se comporta de forma inesperada

Objects fall through the ground or constraints don't work

Solução:

  • Certifique-se de estar avançando a simulação: step_simulation(sim_id, steps=100)
  • Verifique o valor do passo de tempo (o padrão 0.01 geralmente é bom)
  • Verifique se as massas dos objetos são positivas
  • Para planos de chão, use uma caixa com dimensões grandes e massa=1000

7. Falha no carregamento do URDF

ToolError: Failed to load URDF

Solução:

  • Verifique se o caminho do arquivo URDF está correto e acessível
  • Use caminhos absolutos para arquivos URDF
  • Confirme se os arquivos de malha referenciados no URDF também estão acessíveis
  • Valide a sintaxe do URDF diretamente com o PyBullet

Modo de Depuração

Para ver mensagens de erro detalhadas, verifique a saída do servidor no seu terminal. O servidor registra todas as operações e erros.

Obtendo Ajuda

Se você encontrar problemas não abordados aqui:

  1. Verifique os logs do servidor para mensagens de erro detalhadas
  2. Verifique sua configuração do cliente MCP
  3. Teste o servidor diretamente com Python para isolar problemas entre MCP e PyBullet
  4. Revise a documentação do PyBullet para perguntas específicas de física

Arquitetura

O servidor segue uma arquitetura em camadas:

MCP Client (Claude Desktop)
         ↓
   MCP Protocol
         ↓
FastMCP Server (37 tools)
         ↓
Manager Classes (helpers)
         ↓
PyBullet Physics Engine

Componentes Principais:

  • Servidor FastMCP (src/server.py): Expõe 37 ferramentas MCP usando decoradores @mcp.tool
  • SimulationManager: Gerencia clientes de física do PyBullet e o ciclo de vida da simulação
  • ObjectManager: Lida com criação de objetos, manipulação e consultas de estado
  • ConstraintManager: Cria e gerencia juntas entre objetos
  • PersistenceHandler: Serializa/desserializa o estado da simulação para JSON
  • CollisionQueryHandler: Consulta pontos de contato e informações de colisão

Cada ferramenta MCP valida entradas, chama o gerenciador apropriado e retorna objetos Python (dict/list/str/int) diretamente — o FastMCP lida com a conversão do protocolo MCP automaticamente.

Contribuindo

Contribuições são bem-vindas! Por favor, garanta que:

  • Todos os testes passem: pytest
  • O código esteja formatado: black src tests
  • O código passe na análise estática (lint): ruff check src tests
  • As dicas de tipo estejam corretas: mypy src
  • Novos recursos incluam testes (unitários + baseados em propriedades)
  • A documentação esteja atualizada

Agradecimentos

  • Construído com FastMCP por Jeremiah Lowin
  • Simulação de física fornecida por PyBullet
  • Testes baseados em propriedades com Hypothesis

Suporte

Para problemas, perguntas ou contribuições:

  • Revise este README e a seção de solução de problemas
  • Revise a documentação do PyBullet para perguntas específicas de física