How do I change the scope of an object?
In general there is several ways to do it, none of them is the perfect one... 


pointer to mqtt at global scope Adafruit_MQTT_Client * mqtt_ptr; and initialize it by mqtt_ptr = new Adafruit_MQTT_Client(&amp;client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); in setup. Then you have to use arrow operator instead dot to access its methods. Or you can make an alias in loop (or whenever you need it) by Adafruit_MQTT_Client&amp; mqtt = *mqtt_ptr; and access it in the same way as before.
returning reference to static variable created inside of function (singleton), but you have to provide parameters every time, even they're needed only for the first time. The static variable gets constructed only for the first call of function.
For esp8266 there might be available std::optional template. It's similar to pointer, but you don't have to use arrow -&gt; operator. But there might be extraneous copy when you assign (create) it's value.
You can also extend 1. or 2. by own class to hold parameters and then return instance of Adafruit_MQTT_Client