---
- name: "π Resolve {{ application_id }} hosting node + container id"
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
vars:
resolve_service_key: "{{ BASEROW_SERVICE_NAME }}"
resolve_output_prefix: BASEROW
resolve_compose_cid: "{{ BASEROW_CONTAINER }}"
- name: "π Create the MCP endpoint, its owner and its workspace"
ansible.builtin.command:
argv:
- container
- exec
- -i
- -e
- "DJANGO_SETTINGS_MODULE={{ BASEROW_DJANGO_SETTINGS_MODULE }}"
- -e
- "SECRET_KEY={{ BASEROW_SECRET_KEY }}"
- -e
- "BASEROW_SECRET_KEY={{ BASEROW_SECRET_KEY }}"
- -e
- "MCP_OWNER_EMAIL={{ BASEROW_MCP_OWNER_EMAIL }}"
- -e
- "MCP_WORKSPACE_NAME={{ BASEROW_MCP_WORKSPACE_NAME }}"
- -e
- "MCP_ENDPOINT_NAME={{ BASEROW_MCP_ENDPOINT_NAME }}"
- -e
- "MCP_ENDPOINT_KEY={{ BASEROW_MCP_ENDPOINT_KEY }}"
- "{{ BASEROW_LOCAL_CID }}" # nocheck: container-exec-resolver
- "{{ BASEROW_PYTHON }}"
- "{{ BASEROW_MANAGE_PY }}"
- shell
- -c
- "{{ lookup('file', 'python/provision_mcp.py') }}"
register: baserow_mcp_provision
retries: 30
delay: 10
until: baserow_mcp_provision.rc == 0
changed_when: "'CHANGED' in baserow_mcp_provision.stdout"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
delegate_to: "{{ BASEROW_HOST_NODE }}"
run_once: true
- name: "π©Ί Probe the MCP endpoint on the internal origin"
ansible.builtin.command:
argv:
- container
- exec
- -i
- -e
- "MCP_BASE_URL={{ BASEROW_INTERNAL_URL }}"
- -e
- "MCP_ENDPOINT_PATH={{ BASEROW_MCP_ENDPOINT_PATH }}"
- -e
- "MCP_ENDPOINT_KEY={{ BASEROW_MCP_ENDPOINT_KEY }}"
- "{{ BASEROW_LOCAL_CID }}" # nocheck: container-exec-resolver
- "{{ BASEROW_PYTHON }}"
- "-"
stdin: "{{ lookup('file', 'python/probe_mcp_endpoint.py') }}"
register: baserow_mcp_probe
retries: 30
delay: 10
until: baserow_mcp_probe.rc == 0 or 'REJECTED' in baserow_mcp_probe.stderr
failed_when: false
changed_when: false
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
delegate_to: "{{ BASEROW_HOST_NODE }}"
run_once: true
- name: "π Refuse an endpoint that never serves the MCP stream"
ansible.builtin.assert:
that:
- baserow_mcp_probe.rc == 0
fail_msg: >-
{{ BASEROW_INTERNAL_URL }}{{ BASEROW_MCP_ENDPOINT_PATH }} did not answer 401
for an unknown key and text/event-stream for the provisioned one, so every
MCP client would be pointed at a dead or unguarded endpoint.
- name: "π Rebuild the adapter sidecar against the current contract"
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/svc-ai-mcp-adapter/tasks/rebuild.yml') }}"
- name: "π Start the sidecar before probing it"
ansible.builtin.meta: flush_handlers