diff --git a/tools/nfdc/face-helpers.cpp b/tools/nfdc/face-helpers.cpp
new file mode 100644
index 0000000..93b896c
--- /dev/null
+++ b/tools/nfdc/face-helpers.cpp
@@ -0,0 +1,207 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2022,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "face-helpers.hpp"
+#include "format-helpers.hpp"
+
+#include <ndn-cxx/util/logger.hpp>
+
+namespace nfd::tools::nfdc {
+
+NDN_LOG_INIT(nfdc.FindFace);
+
+FindFace::FindFace(ExecuteContext& ctx)
+  : m_ctx(ctx)
+{
+}
+
+FindFace::Code
+FindFace::execute(const FaceUri& faceUri, bool allowMulti)
+{
+  FaceQueryFilter filter;
+  filter.setRemoteUri(faceUri.toString());
+  return this->execute(filter, allowMulti);
+}
+
+FindFace::Code
+FindFace::execute(uint64_t faceId)
+{
+  FaceQueryFilter filter;
+  filter.setFaceId(faceId);
+  return this->execute(filter);
+}
+
+FindFace::Code
+FindFace::execute(const std::any& faceIdOrUri, bool allowMulti)
+{
+  const uint64_t* faceId = std::any_cast<uint64_t>(&faceIdOrUri);
+  if (faceId != nullptr) {
+    return this->execute(*faceId);
+  }
+  else {
+    return this->execute(std::any_cast<FaceUri>(faceIdOrUri), allowMulti);
+  }
+}
+
+FindFace::Code
+FindFace::execute(const FaceQueryFilter& filter, bool allowMulti)
+{
+  BOOST_ASSERT(m_res == Code::NOT_STARTED);
+  m_res = Code::IN_PROGRESS;
+  m_filter = filter;
+
+  if (m_filter.hasRemoteUri()) {
+    auto remoteUri = canonize("remote FaceUri", FaceUri(m_filter.getRemoteUri()));
+    if (!remoteUri) {
+      return m_res;
+    }
+    m_filter.setRemoteUri(remoteUri->toString());
+  }
+
+  if (m_filter.hasLocalUri()) {
+    auto localUri = canonize("local FaceUri", FaceUri(m_filter.getLocalUri()));
+    if (!localUri) {
+      return m_res;
+    }
+    m_filter.setLocalUri(localUri->toString());
+  }
+
+  this->query();
+  if (m_res == Code::OK) {
+    if (m_results.size() == 0) {
+      m_res = Code::NOT_FOUND;
+      m_errorReason = "Face not found";
+    }
+    else if (m_results.size() > 1 && !allowMulti) {
+      m_res = Code::AMBIGUOUS;
+      m_errorReason = "Multiple faces match the query";
+    }
+  }
+  return m_res;
+}
+
+std::optional<FaceUri>
+FindFace::canonize(const std::string& fieldName, const FaceUri& uri)
+{
+  // We use a wrapper because we want to accept FaceUris that cannot be canonized
+  if (!FaceUri::canCanonize(uri.getScheme())) {
+    NDN_LOG_DEBUG("Using " << fieldName << "=" << uri << " without canonization");
+    return uri;
+  }
+
+  auto [result, error] = nfdc::canonize(m_ctx, uri);
+  if (result) {
+    // Canonization succeeded
+    return result;
+  }
+  else {
+    // Canonization failed
+    std::tie(m_res, m_errorReason) = canonizeErrorHelper(uri, error);
+    return std::nullopt;
+  }
+}
+
+void
+FindFace::query()
+{
+  auto datasetCb = [this] (const auto& result) {
+    m_res = Code::OK;
+    m_results = result;
+  };
+  auto failureCb = [this] (uint32_t code, const auto& reason) {
+    m_res = Code::ERROR;
+    m_errorReason = "Error " + to_string(code) + " when querying face: " + reason;
+  };
+
+  if (m_filter.empty()) {
+    m_ctx.controller.fetch<ndn::nfd::FaceDataset>(
+      datasetCb, failureCb, m_ctx.makeCommandOptions());
+  }
+  else {
+    m_ctx.controller.fetch<ndn::nfd::FaceQueryDataset>(
+      m_filter, datasetCb, failureCb, m_ctx.makeCommandOptions());
+  }
+  m_ctx.face.processEvents();
+}
+
+std::set<uint64_t>
+FindFace::getFaceIds() const
+{
+  std::set<uint64_t> faceIds;
+  for (const FaceStatus& faceStatus : m_results) {
+    faceIds.insert(faceStatus.getFaceId());
+  }
+  return faceIds;
+}
+
+const FaceStatus&
+FindFace::getFaceStatus() const
+{
+  BOOST_ASSERT(m_results.size() == 1);
+  return m_results.front();
+}
+
+void
+FindFace::printDisambiguation(std::ostream& os, DisambiguationStyle style) const
+{
+  text::Separator sep(" ", ", ");
+  for (const auto& item : m_results) {
+    os << sep;
+    switch (style) {
+      case DisambiguationStyle::LOCAL_URI:
+        os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
+        break;
+    }
+  }
+}
+
+std::pair<std::optional<FaceUri>, std::string>
+canonize(ExecuteContext& ctx, const FaceUri& uri)
+{
+  std::optional<FaceUri> result;
+  std::string error;
+  uri.canonize(
+    [&result] (const auto& canonicalUri) { result = canonicalUri; },
+    [&error] (const auto& errorReason) { error = errorReason; },
+    ctx.face.getIoService(), ctx.getTimeout());
+  ctx.face.processEvents();
+
+  return {result, error};
+}
+
+std::pair<FindFace::Code, std::string>
+canonizeErrorHelper(const FaceUri& uri,
+                    const std::string& error,
+                    const std::string& field)
+{
+  std::string msg = "Error during canonization of ";
+  if (!field.empty()) {
+    msg += field + " ";
+  }
+  msg += "'" + uri.toString() + "': " + error;
+  return {FindFace::Code::CANONIZE_ERROR, msg};
+}
+
+} // namespace nfd::tools::nfdc
