{
  "info": {
    "name": "CCSM MCP | AGENTE → MCP · equipo instalado",
    "_postman_id": "70f4abbc-4a8d-4ccb-8b44-08f1c44e43be",
    "description": "Agente real inicia búsqueda por DNS de dominio confiable, GET /.well-known/ccsm-bridge.json SIN token, y después heartbeat + pull + result autenticados con UUID/token. Postman simula las peticiones, NO ejecuta comandos Linux. No existen IPs Linux fijas ni push desde MCP.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Agente instalado: sondeo de tareas y envío de resultados",
      "item": [
        {
          "name": "00 · Encontrar y verificar MCP (agente → DNS → gateway)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/.well-known/ccsm-bridge.json",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                ".well-known",
                "ccsm-bridge.json"
              ]
            },
            "description": "Simula el primer paso real del agente Linux: DNS resuelve el hostname de base_url en la conexión. El agente consulta el manifiesto HTTPS SIN token, comprueba identidad, versión y ruta API; solo después usa agent_token en heartbeat/pull/result. No depende de IP del Linux ni acepta redirecciones del MCP a terceros."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('HTTP 200: MCP descubierto', () => pm.response.to.have.status(200));",
                  "const manifest = pm.response.json();",
                  "pm.test('Servicio institucional verificado', () => pm.expect(manifest.service).to.eql('ccsm-linux-bridge'));",
                  "pm.test('Contrato de agente compatible', () => pm.expect(manifest.schema_version).to.eql(1));",
                  "pm.test('La API no cambia de origen', () => pm.expect(manifest.agent_api_path).to.eql('/api/v1/agent'));",
                  "pm.test('Sin credenciales en la petición', () => pm.expect(pm.request.headers.get('Authorization')).to.be.undefined);"
                ]
              }
            }
          ]
        },
        {
          "name": "Enviar heartbeat",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{agent_token}}"
              },
              {
                "key": "X-Bridge-Agent-ID",
                "value": "{{agent_id}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/agent/heartbeat",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "agent",
                "heartbeat"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"HTTP 200\", function () { pm.response.to.have.status(200); });"
                ]
              }
            }
          ]
        },
        {
          "name": "Consultar cola (HTTP 204 si vacía)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{agent_token}}"
              },
              {
                "key": "X-Bridge-Agent-ID",
                "value": "{{agent_id}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/agent/pull",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "agent",
                "pull"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "ACTOR AGENTE -> MCP: sondeo saliente periódico. El MCP NO se conecta al equipo ni envía push directo; contesta 200 con JSON task_id/command/expires_at, o 204 sin tarea. El agente comprueba operación permitida antes de ejecutar."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 tarea o 204 sin tareas\",()=>pm.expect([200,204]).to.include(pm.response.code));",
                  "if(pm.response.code===200){const x=pm.response.json();pm.environment.set(\"task_id\",x.task_id);}"
                ]
              }
            }
          ]
        },
        {
          "name": "Entregar resultado de tarea",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{agent_token}}"
              },
              {
                "key": "X-Bridge-Agent-ID",
                "value": "{{agent_id}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/agent/tasks/{{task_id}}/result",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "agent",
                "tasks",
                "{{task_id}}",
                "result"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"exit_code\": 0,\n  \"stdout\": \"Resultado de prueba Postman\",\n  \"stderr\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "ACTOR AGENTE -> MCP: informa exit_code/stdout/stderr de una tarea obtenida mediante pull. El MCP guarda el resultado y la IA lo recupera usando get_bridge_task. Postman solo simula el transporte; NO ejecuta el comando."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"HTTP 200\", function () { pm.response.to.have.status(200); });"
                ]
              }
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "http://127.0.0.1:8011",
      "type": "string"
    },
    {
      "key": "agent_token",
      "value": "",
      "type": "string"
    },
    {
      "key": "agent_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "task_id",
      "value": "",
      "type": "string"
    }
  ]
}
