Convention is for each module to prevent itself from being interpreted multiple times using a guard at the top of the module. User code and other modules load external modules as required.
A guard can be implemented by declaring a variable or macro and then testing for its existence using the known operator. If it exists before it has been declared, the module has already been read and code interpretation is stopped via endinput. Here's an example guard:
if known my_module:
message "module my_module loaded twice";
expandafter endinput
fi
string my_module;
my_module := "";
message "module my_module loaded once";
<module code>
endinput
Within the if clause, expandafter postpones the effect of endinput just a little to give MetaPost a chance to see the closing fi statement. Otherwise, MetaPost would complain about an open if clause whenever the module is read more than once.
Regarding version management, there's not much support for that in MetaPost. Providing means to retrieve the version number in each module is all you can do, so users can check module version after inputting a module.
For external modules that don't provide version information, you can check for the existence of a particular feature (a variable or macro) using the known operator as shown above. But that won't help with identifying a particular patch level of a module (with certain bugs fixed). If fine grained version information is needed, one option is to contact the module author and make a feature request.