How does tampermonkey overrides CSP to run user-defined dynamic code?

Tampermonkey injects dynamic code into the browser’s content script. However, in my understanding, this is not possible in manifest v3. Creating a script tag in the document is blocked by CSP, and APIs like executeScript don’t allow user-defined script. Then, how is tampermonkey implemented?