LSP is a protocol while tree-sitter is a parsing tool and library. LSP is a protocol developed by Microsoft for IDEs to communicate with a separate process to provide annotations and insight into source code. Practically, tree-sitter is usually used for syntax highlighting, while servers implementing LSP are used for compilation errors, warnings, jump to definition, linter warnings, symbol highlighting, etc etc etc.
Tree-sitter works like a syntax highlighting plugin, and doesn’t require communication with an external process. It’s like syntax highlighting but with a deeper understanding of the programming language, not based just on regular expressions. So not only is the highlighting better, but you can do more things, such as selecting blocks or jumping among them. One of my favorite goodies is being able to ask the editor what function my cursor is inside.
They don't overlap in functionality at all. LSP is a protocol for communicating with IDE plugins. Tree-Sitter is a parser.
They're often used together. I've written a couple of language servers that use Tree-Sitter to parse documents.
For example when you hover something in VSCode it uses the LSP to communicate with the language server and say "oi, what's on line 5 column 10" and then the language server uses Tree Sitter to parse the document and figure out the answer (or some other parser).