You can edit everything about a mesh with the ArrayMesh API and the RenderingServer API.
Every primitive mesh in Godot is basically an “ArrayMesh” internally. They all have functions to get the mesh arrays. The more simpler and specialised looking Mesh resource classes limit the API and user input options hiding away the complexity from users. Internally they build the same arrays required for the RenderingServer as you would with a manual ArrayMesh.
For a lot of the mesh primitives their usefulness is therefor limited to prototyping. They can not support many of the more sophisticated mesh features like skeletons or updating small array regions instead of the entire mesh.
So if you want to work with more complex procedual meshes you can basically ignore all Mesh resource classes except for the ArrayMesh.
MeshDataTools is just a slow convenience class, it is required for nothing. You can do the same more efficiently with just plain arrays or SurfaceTool. SurfaceTool on the other hand is a more useful helper class for mesh surface creation. It has functionality like recalculating normals and tangents or doing the mesh indexing and cache optimizations.
Note that as soon as you commit to a mesh all the mesh data is stored on the GPU. This means calling getters to receive mesh data will stall the rendering. So keep a copy of your mesh arrays so you have it on the CPU to update your mesh.
Since you are working with just pure data arrays most of the time you can throw as many threads at the mesh problem as you need. Just make sure that you commit your arrays on the main thread and don’t call getters that require GPU data.