diff --git a/asyncmsg/NameService.h b/asyncmsg/NameService.h
index 9fc9494b2dec2fbca44015b1750baf7900039320..fd68e65f7eb4257dfdf1c92c94d4a398d614570b 100644
--- a/asyncmsg/NameService.h
+++ b/asyncmsg/NameService.h
@@ -4,6 +4,7 @@
 
 #include <vector>
 #include <string>
+#include <map>
 #include <tuple>
 #include <cstdint>
 #include "boost/asio.hpp"
@@ -48,11 +49,12 @@ namespace daq {
             /**
              * \param[in] partition The IPC partition object.
              * \param[in] data_networks A list of networks in the format network/netmask. Both IP 4 and 6 are accepted.
-             * \param[in] is_server The IS server to publish the information to.
+             * \param[in] is_server The IS server to publish the information to. If the DF_CONFIG_IS_SERVER environment variable
+                                    is set, it takes precedence.
              */
             NameService(IPCPartition partition ,
                         const std::vector<std::string>& data_networks, 
-                        const std::string& is_server = "DF") noexcept;
+                        const std::string& is_server = "DFConfig") noexcept;
             ~NameService() noexcept;
 
             /** \brief Publish IS object with all valid local interfaces and port number.
@@ -74,6 +76,26 @@ namespace daq {
              */
             std::vector<boost::asio::ip::tcp::endpoint> lookup(const std::string& prefix) const;
 
+            /** \brief Look up all applications starting with the given 'prefix' and return a map of names and endpoints.
+             *
+             * \param[in] prefix The search criteria in IS will be 'prefix.*'.
+             *
+             * \returns A map of application names and boost ASIO TCP endpoints, exactly one for each remote application.
+             *
+             * \throws IS exceptions
+             */
+            std::map<std::string,boost::asio::ip::tcp::endpoint> lookup_names(const std::string& prefix) const;
+
+            /** \brief Look up all applications starting with the given 'prefix' and return a map of names and all endpoints.
+             *
+             * \param[in] prefix The search criteria in IS will be 'prefix.*'.
+             *
+             * \returns A map of application names and a list of all boost ASIO TCP endpoints that would be available.
+             *
+             * \throws IS exceptions
+             */            
+            std::map<std::string,std::vector<boost::asio::ip::tcp::endpoint>> lookup_all(const std::string& prefix) const;
+
             /** \brief Resolve a single specific application.
              *
              * \param[in] Resolves exactly one specific remote applications.
diff --git a/src/NameService.cxx b/src/NameService.cxx
index b2244ed3475dd3fdd52203a3ded12d51751bf19b..d1c9f6a97954dcd66f3cdca69439c99b5ed9d292 100644
--- a/src/NameService.cxx
+++ b/src/NameService.cxx
@@ -15,6 +15,12 @@ namespace daq {
             : m_partition(partition),
               m_is_server(is_server)
         {
+
+            if(const char *server = getenv("DF_CONFIG_IS_SERVER")) {
+                // override user argument
+                m_is_server = server;
+            }
+
             for(const auto & network : data_networks) {
                 m_data_networks.push_back(parse_address_network(network));
             }
@@ -173,6 +179,66 @@ namespace daq {
             return results;
         }
 
+        // Look up all applications of given 'type' and return a map of names and endpoints
+        std::map<std::string,boost::asio::ip::tcp::endpoint> 
+        NameService::lookup_names(const std::string& prefix) const
+        {
+
+            std::map<std::string,boost::asio::ip::tcp::endpoint> results;
+
+            ISInfoIterator it(m_partition, m_is_server, ISCriteria("MSG_" + prefix + ".*", MsgInfo::type()));
+
+            while(it++) {
+                std::string name(it.name());
+                MsgInfo     info;
+
+                it.value(info);
+
+                // match my local interfaces against the list
+                for(auto& addr_netmask : info.Addresses) {
+                    boost::asio::ip::address addr, mask;
+                    std::tie(addr, mask) = parse_address_network(addr_netmask);
+
+                    if(matches(addr, mask)) {
+                        results[name.substr(4)] = boost::asio::ip::tcp::endpoint(addr, info.Port);
+                        break;
+                    }
+                }
+            }
+
+            return results;
+        }
+
+        // Look up all applications of given 'type' and return a map of all names and endpoints that match
+        std::map<std::string, std::vector<boost::asio::ip::tcp::endpoint>>
+        NameService::lookup_all(const std::string& prefix) const
+        {
+
+            std::map<std::string,std::vector<boost::asio::ip::tcp::endpoint>> results;
+
+            ISInfoIterator it(m_partition, m_is_server, ISCriteria("MSG_" + prefix + ".*", MsgInfo::type()));
+
+            while(it++) {
+                std::string name(it.name());
+                MsgInfo     info;
+
+                it.value(info);
+
+                // match my local interfaces against the list
+                for(auto& addr_netmask : info.Addresses) {
+                    boost::asio::ip::address addr, mask;
+                    std::tie(addr, mask) = parse_address_network(addr_netmask);
+
+                    if(matches(addr, mask)) {
+                        results[name.substr(4)].push_back(boost::asio::ip::tcp::endpoint(addr, info.Port));
+                        break;
+                    }
+                }
+            }
+
+            return results;
+        }
+
 
         boost::asio::ip::tcp::endpoint 
         NameService::resolve(const std::string& name) const