--- - name: Deploy MCPO as a system service hosts: mcpo handlers: - name: restart mcpo become: true ansible.builtin.systemd: name: mcpo state: restarted tasks: - name: Create MCPO group become: true ansible.builtin.group: name: "{{mcpo_group}}" system: true - name: Create MCPO User become: true ansible.builtin.user: name: "{{mcpo_user}}" group: "{{mcpo_group}}" comment: "{{mcpo_user}}" system: true - name: Add keeper_user to mcpo group become: true ansible.builtin.user: name: "{{keeper_user}}" groups: "{{mcpo_group}}" append: true - name: Create required directories become: true ansible.builtin.file: path: "{{mcpo_directory}}" owner: "{{mcpo_user}}" group: "{{mcpo_group}}" state: directory mode: '750' - name: Check if config.json exists ansible.builtin.stat: path: "{{mcpo_directory}}/config.json" register: config_file - name: Backup existing config if present become: true ansible.builtin.copy: src: "{{mcpo_directory}}/config.json" dest: "{{mcpo_directory}}/config.json.bak" remote_src: yes owner: "{{mcpo_user}}" group: "{{mcpo_group}}" mode: '0660' when: config_file.stat.exists - name: Deploy config.json from template become: true ansible.builtin.template: src: "config.json.j2" dest: "{{mcpo_directory}}/config.json" owner: "{{mcpo_user}}" group: "{{mcpo_group}}" mode: '0660' notify: restart mcpo - name: Add NodeSource repository for Node.js 22.x become: true ansible.builtin.deb822_repository: name: nodesource types: [deb] uris: https://deb.nodesource.com/node_22.x suites: [nodistro] components: [main] signed_by: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key state: present - name: Install nodejs and Python 3.12 packages become: true apt: name: [nodejs, python3.12, python3.12-venv, python3.12-dev, python3-pip] state: latest update_cache: true - name: Create virtual environment become: true become_user: "{{mcpo_user}}" ansible.builtin.command: python3.12 -m venv {{mcpo_directory}}/.venv args: creates: "{{mcpo_directory}}/.venv/bin/activate" vars: ansible_common_remote_group: "{{mcpo_group}}" allow_world_readable_tmpfiles: true - name: Install pip packages in virtual environment become: true become_user: "{{mcpo_user}}" ansible.builtin.pip: name: - wheel - mcpo - mcp-server-time state: latest virtualenv: "{{mcpo_directory}}/.venv" vars: ansible_common_remote_group: "{{mcpo_group}}" allow_world_readable_tmpfiles: true - name: Pre-install Context7 MCP package become: true become_user: "{{mcpo_user}}" ansible.builtin.command: npx -y @upstash/context7-mcp --help args: chdir: "{{mcpo_directory}}" vars: ansible_common_remote_group: "{{mcpo_group}}" allow_world_readable_tmpfiles: true ignore_errors: true - name: Create systemd service file become: true ansible.builtin.template: src: mcpo.service.j2 dest: /etc/systemd/system/mcpo.service mode: '660' - name: Reload systemd and enable mcpo service become: true ansible.builtin.systemd: name: mcpo daemon_reload: true enabled: true state: started register: mcpo_service_status - name: Verify MCPO service is running ansible.builtin.debug: msg: "MCPO service is running and enabled" when: mcpo_service_status.state == "started" - name: Check if MCPO service is responding ansible.builtin.uri: url: http://localhost:{{mcpo_port}}/docs method: GET status_code: 200 register: health_check ignore_errors: yes retries: 5 delay: 5 - name: Report MCPO health status ansible.builtin.debug: msg: "MCPO health check {{ 'succeeded' if health_check.status == 200 else 'failed' }}" when: not health_check.failed - name: Verify Grafana MCP backend is reachable ansible.builtin.uri: url: "http://localhost:{{grafana_mcp_port}}/mcp" method: GET status_code: [200, 405] register: grafana_mcp_check ignore_errors: true retries: 3 delay: 3 when: grafana_mcp_port is defined - name: Report Grafana MCP backend status ansible.builtin.debug: msg: "Grafana MCP backend {{ 'reachable' if not grafana_mcp_check.failed else 'UNREACHABLE - MCPO grafana proxy will not work until grafana_mcp/deploy.yml is run' }}" when: grafana_mcp_port is defined and grafana_mcp_check is defined