diff --git a/CHANGELOG.md b/CHANGELOG.md
index 083381ba..6d29efd8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 ## master (unreleased)
 
+### New features
+
+* [#698](https://github.com/clojure-emacs/cider-nrepl/pull/698): Add `undef-all` op to undefine all symbols and aliases in namespace
+
 ## 0.26.0 (2021-04-22)
 
 ### New features
diff --git a/doc/modules/ROOT/pages/nrepl-api/ops.adoc b/doc/modules/ROOT/pages/nrepl-api/ops.adoc
index c815cb06..8a8f38e7 100644
--- a/doc/modules/ROOT/pages/nrepl-api/ops.adoc
+++ b/doc/modules/ROOT/pages/nrepl-api/ops.adoc
@@ -969,7 +969,7 @@ Required parameters::
 {blank}
 
 Optional parameters::
-* `:filter-regex` Only the specs that matches filter prefix regex will be returned
+* `:filter-regex` Only the specs that matches filter prefix regex will be returned 
 
 
 Returns::
@@ -1179,3 +1179,20 @@ Optional parameters::
 
 Returns::
 * `:status` done
+
+
+
+=== `undef-all`
+
+Undefine all aliases and symbols in a namespace
+
+Required parameters::
+* `:ns` The namespace to operate on
+
+
+Optional parameters::
+{blank}
+
+Returns::
+* `:status` done
+
diff --git a/src/cider/nrepl.clj b/src/cider/nrepl.clj
index b266ee9b..c982bb99 100644
--- a/src/cider/nrepl.clj
+++ b/src/cider/nrepl.clj
@@ -473,7 +473,7 @@
 (def ops-that-can-eval
   "Set of nREPL ops that can lead to code being evaluated."
   #{"eval" "load-file" "refresh" "refresh-all" "refresh-clear"
-    "toggle-trace-var" "toggle-trace-ns" "undef"})
+    "toggle-trace-var" "toggle-trace-ns" "undef" "undef-all"})
 
 (def-wrapper wrap-tracker cider.nrepl.middleware.track-state/handle-tracker
   ops-that-can-eval
@@ -492,7 +492,10 @@
    {"undef" {:doc "Undefine a symbol"
              :requires {"sym" "The symbol to undefine"
                         "ns" "The namespace is which to resolve sym (falls back to *ns* if not specified)"}
-             :returns {"status" "done"}}}})
+             :returns {"status" "done"}}
+    "undef-all" {:doc "Undefine all aliases and symbols in a namespace"
+                 :requires {"ns" "The namespace to operate on"}
+                 :returns {"status" "done"}}}})
 
 (def-wrapper wrap-version cider.nrepl.middleware.version/handle-version
   {:doc "Provides CIDER-nREPL version information."
diff --git a/src/cider/nrepl/middleware/undef.clj b/src/cider/nrepl/middleware/undef.clj
index 03747861..c6232fb7 100644
--- a/src/cider/nrepl/middleware/undef.clj
+++ b/src/cider/nrepl/middleware/undef.clj
@@ -27,10 +27,25 @@
           (ns-unmap ns sym-name)))
     sym))
 
+(defn undef-all
+  "Undefines all symbol mappings and aliases in the namespace."
+  [{:keys [ns]}]
+  (let [ns (misc/as-sym ns)]
+    (doseq [[sym _] (ns-map ns)]
+      (ns-unmap ns sym))
+    (doseq [[sym _] (ns-aliases ns)]
+      (ns-unalias ns sym))
+    ns))
+
 (defn undef-reply
   [msg]
   {:undef (undef msg)})
 
+(defn undef-all-reply
+  [msg]
+  {:undef-all (undef-all msg)})
+
 (defn handle-undef [handler msg]
   (with-safe-transport handler msg
-    "undef" undef-reply))
+    "undef" undef-reply
+    "undef-all" undef-all-reply))
diff --git a/test/clj/cider/nrepl/middleware/undef_test.clj b/test/clj/cider/nrepl/middleware/undef_test.clj
index 0b942aff..a879c5d9 100644
--- a/test/clj/cider/nrepl/middleware/undef_test.clj
+++ b/test/clj/cider/nrepl/middleware/undef_test.clj
@@ -101,3 +101,27 @@
       (is (:pp-stacktrace response))
       (is (:err response))
       (is (:ex response)))))
+
+(deftest undef-all-test
+  (testing "undef-all undefines all vars in namespace"
+    (is (= #{"done"}
+           (:status (session/message {:op "eval"
+                                      :code "(do (ns other.ns (:require [clojure.walk :as walk :refer [postwalk]])))"}))))
+    (is (= ["#'clojure.core/assoc"]
+           (:value (session/message {:op "eval"
+                                     :code "(do (in-ns 'user) (ns-resolve 'other.ns 'assoc))"}))))
+    (is (= ["#'clojure.walk/postwalk"]
+           (:value (session/message {:op "eval"
+                                     :code "(ns-resolve 'other.ns 'postwalk)"}))))
+    (is (= #{"done"}
+           (:status (session/message {:op "undef-all"
+                                      :ns "other.ns"}))))
+    (is (= ["nil"]
+           (:value (session/message {:op "eval"
+                                     :code "(ns-resolve 'other.ns 'assoc)"}))))
+    (is (= ["nil"]
+           (:value (session/message {:op "eval"
+                                     :code "(ns-resolve 'other.ns 'postwalk)"}))))
+    (is (= ["{}"]
+           (:value (session/message {:op "eval"
+                                     :code "(ns-aliases 'other.ns)"}))))))