Essentially a Meta Object Protocol (or MOP for short) is a method for accessing the guts of an object system through a Meta Class. A Meta Class is the class for a class. That is, if a class is an object, then this class-object must have a class.
Meta Classes are responsible for the overall behaviour of an object system. (Assuming your object system is centered around classes. See object-oriented-programming). A meta class is in charge of things like handling delegation (due to inheritance), access, etc.
Generally there are 2 major aspects to a meta object protocol
The ability to read the attributes of an object or class such as: what is this classes subclass? What methods are available to this class?
The ability to modify the behaviour of an object or class such as: change this objects parent, bind this method to this class or object.)
Perl has a complete read/write implementation of a Meta Object Protocol with its Class::MOP, this is used to produce a more sugary version called Moose. The object system in PHP 5 has introspective abilities, and a very limited set of intercession abilities through the magical __get(), __set() and __call() methods. The object system in Java has a purely introspective system. But really, you cannot talk about a Meta Object Protocol without mentioning CLOS.
Any time you need to alter how an object (or class) handles its messages. For instance, instead of doing a method lookup on a local table, perform an RPC call. Other potential uses include:
See Also: The Art of the Metaobject Protocol by Gregor Kiczales
Chapters 5 and 6 of "The Art of the Metaobject Protocol"