diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -91,8 +91,8 @@
   // Calls have signature void(const Params&, Callback<Response>).
   void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
   void onInitialized(const InitializedParams &);
-  void onShutdown(const ShutdownParams &, Callback<std::nullptr_t>);
-  void onSync(const NoParams &, Callback<std::nullptr_t>);
+  void onShutdown(Callback<std::nullptr_t>);
+  void onSync(Callback<std::nullptr_t>);
   void onDocumentDidOpen(const DidOpenTextDocumentParams &);
   void onDocumentDidChange(const DidChangeTextDocumentParams &);
   void onDocumentDidClose(const DidCloseTextDocumentParams &);
@@ -159,7 +159,7 @@
                              Callback<SemanticTokensOrDelta>);
   /// This is a clangd extension. Provides a json tree representing memory usage
   /// hierarchy.
-  void onMemoryUsage(const NoParams &, Callback<MemoryTree>);
+  void onMemoryUsage(Callback<MemoryTree>);
 
   std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
 
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -258,6 +258,25 @@
     };
   }
 
+  template <typename Result>
+  void bind(const char *Method,
+            void (ClangdLSPServer::*Handler)(const NoParams &,
+                                             Callback<Result>)) {
+    Calls[Method] = [Handler, this](llvm::json::Value RawParams,
+                                    ReplyOnce Reply) {
+      (Server.*Handler)(NoParams{}, std::move(Reply));
+    };
+  }
+
+  template <typename Result>
+  void bind(const char *Method,
+            void (ClangdLSPServer::*Handler)(Callback<Result>)) {
+    Calls[Method] = [Handler, this](llvm::json::Value RawParams,
+                                    ReplyOnce Reply) {
+      (Server.*Handler)(std::move(Reply));
+    };
+  }
+
   // Bind a reply callback to a request. The callback will be invoked when
   // clangd receives the reply from the LSP client.
   // Return a call id of the request.
@@ -301,6 +320,20 @@
     };
   }
 
+  void bind(const char *Method, void (ClangdLSPServer::*Handler)()) {
+    Notifications[Method] = [Handler, this](llvm::json::Value RawParams) {
+      (Server.*Handler)();
+    };
+  }
+
+  template <>
+  void bind<NoParams>(const char *Method,
+                      void (ClangdLSPServer::*Handler)(const NoParams &)) {
+    Notifications[Method] = [Handler, this](llvm::json::Value RawParams) {
+      (Server.*Handler)(NoParams{});
+    };
+  }
+
 private:
   // Function object to reply to an LSP call.
   // Each instance must be called exactly once, otherwise:
@@ -647,8 +680,7 @@
 
 void ClangdLSPServer::onInitialized(const InitializedParams &Params) {}
 
-void ClangdLSPServer::onShutdown(const ShutdownParams &Params,
-                                 Callback<std::nullptr_t> Reply) {
+void ClangdLSPServer::onShutdown(Callback<std::nullptr_t> Reply) {
   // Do essentially nothing, just say we're ready to exit.
   ShutdownRequestReceived = true;
   Reply(nullptr);
@@ -656,8 +688,7 @@
 
 // sync is a clangd extension: it blocks until all background work completes.
 // It blocks the calling thread, so no messages are processed until it returns!
-void ClangdLSPServer::onSync(const NoParams &Params,
-                             Callback<std::nullptr_t> Reply) {
+void ClangdLSPServer::onSync(Callback<std::nullptr_t> Reply) {
   if (Server->blockUntilIdleForTest(/*TimeoutSeconds=*/60))
     Reply(nullptr);
   else
@@ -1445,8 +1476,7 @@
       });
 }
 
-void ClangdLSPServer::onMemoryUsage(const NoParams &,
-                                    Callback<MemoryTree> Reply) {
+void ClangdLSPServer::onMemoryUsage(Callback<MemoryTree> Reply) {
   llvm::BumpPtrAllocator DetailAlloc;
   MemoryTree MT(&DetailAlloc);
   profile(MT);
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -265,8 +265,6 @@
   return true;
 }
 using InitializedParams = NoParams;
-using ShutdownParams = NoParams;
-using ExitParams = NoParams;
 
 /// Defines how the host (editor) should sync document changes to the language
 /// server.