diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,13 @@
 # Revision history for lsp
 
+## 2.1.0.0
+
+* Fix handling of optional methods.
+* `staticHandlers` now takes the client capabilities as an argument. 
+  These are static across the lifecycle of the server, so this allows
+  a server to decide at construction e.g. whether to provide handlers
+  for resolve methods depending on whether the client supports it.
+
 ## 2.0.0.0
 
 * Support `lsp-types-2.0.0.0`.
diff --git a/example/Reactor.hs b/example/Reactor.hs
--- a/example/Reactor.hs
+++ b/example/Reactor.hs
@@ -96,7 +96,7 @@
             J.Success cfg -> Right cfg
       , doInitialize = \env _ -> forkIO (reactor stderrLogger rin) >> pure (Right env)
       -- Handlers log to both the client and stderr
-      , staticHandlers = lspHandlers dualLogger rin
+      , staticHandlers = \_caps -> lspHandlers dualLogger rin
       , interpretHandler = \env -> Iso (runLspT env) liftIO
       , options = lspOptions
       }
diff --git a/example/Simple.hs b/example/Simple.hs
--- a/example/Simple.hs
+++ b/example/Simple.hs
@@ -41,7 +41,7 @@
   { onConfigurationChange = const $ const $ Right ()
   , defaultConfig = ()
   , doInitialize = \env _req -> pure $ Right env
-  , staticHandlers = handlers
+  , staticHandlers = \_caps -> handlers
   , interpretHandler = \env -> Iso (runLspT env) liftIO
   , options = defaultOptions
   }
diff --git a/lsp.cabal b/lsp.cabal
--- a/lsp.cabal
+++ b/lsp.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               lsp
-version:            2.0.0.0
+version:            2.1.0.0
 synopsis:           Haskell library for the Microsoft Language Server Protocol
 description:
   An implementation of the types, and basic message server to
@@ -63,7 +63,7 @@
     , filepath
     , hashable
     , lens                  >=4.15.2
-    , lsp-types             ^>=2.0
+    , lsp-types             ^>=2.0.1
     , mtl                   <2.4
     , prettyprinter
     , random
diff --git a/src/Language/LSP/Server/Core.hs b/src/Language/LSP/Server/Core.hs
--- a/src/Language/LSP/Server/Core.hs
+++ b/src/Language/LSP/Server/Core.hs
@@ -294,10 +294,12 @@
       -- language server implementation the chance to create any processes or
       -- start new threads that may be necessary for the server lifecycle. It can
       -- also return an error in the initialization if necessary.
-    , staticHandlers :: Handlers m
+    , staticHandlers :: ClientCapabilities -> Handlers m
       -- ^ Handlers for any methods you want to statically support.
       -- The handlers here cannot be unregistered during the server's lifetime
       -- and will be registered statically in the initialize request.
+      -- The handlers provided can depend on the client capabilities, which
+      -- are static across the lifetime of the server.
     , interpretHandler :: a -> (m <~> IO)
       -- ^ How to run the handlers in your own monad of choice, @m@.
       -- It is passed the result of 'doInitialize', so typically you will want
diff --git a/src/Language/LSP/Server/Processing.hs b/src/Language/LSP/Server/Processing.hs
--- a/src/Language/LSP/Server/Processing.hs
+++ b/src/Language/LSP/Server/Processing.hs
@@ -126,6 +126,7 @@
     let p = req ^. L.params
         rootDir = getFirst $ foldMap First [ p ^? L.rootUri . _L >>= uriToFilePath
                                            , p ^? L.rootPath . _Just . _L <&> T.unpack ]
+        clientCaps = (p ^. L.capabilities)
 
     let initialWfs = case p ^. L.workspaceFolders of
           Just (InL xs) -> xs
@@ -152,11 +153,11 @@
 
     -- Call the 'duringInitialization' callback to let the server kick stuff up
     let env = LanguageContextEnv handlers onConfigurationChange sendFunc stateVars (p ^. L.capabilities) rootDir
-        handlers = transmuteHandlers interpreter staticHandlers
+        handlers = transmuteHandlers interpreter (staticHandlers clientCaps)
         interpreter = interpretHandler initializationResult
     initializationResult <- ExceptT $ doInitialize env req
 
-    let serverCaps = inferServerCapabilities (p ^. L.capabilities) options handlers
+    let serverCaps = inferServerCapabilities clientCaps options handlers
     liftIO $ sendResp $ makeResponseMessage (req ^. L.id) (InitializeResult serverCaps (optServerInfo options))
     pure env
   where
@@ -404,11 +405,8 @@
     -- See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#-notifications-and-requests.
     reportMissingHandler :: m ()
     reportMissingHandler =
-      let optional = isOptionalNotification m
+      let optional = isOptionalMethod (SomeMethod m)
       in logger <& MissingHandler optional m `WithSeverity` if optional then Warning else Error
-    isOptionalNotification (SMethod_CustomMethod p)
-      | "$/" `T.isPrefixOf` T.pack (symbolVal p) = True
-    isOptionalNotification _  = False
 
 progressCancelHandler :: (m ~ LspM config) => LogAction m (WithSeverity LspProcessingLog) -> TMessage Method_WindowWorkDoneProgressCancel -> m ()
 progressCancelHandler logger (TNotificationMessage _ _ (WorkDoneProgressCancelParams tid)) = do
