Protobuf is gRPC agnostic. gRPC is protobuf agnostic. Neither of them know about each other, and this allows you to avoid either one if you don't want them. We actually have examples that don't use Protobuf in gRPC, particularly in our benchmarks.
The reason metadata is harder to get to is because it would complicate the stub API. gRPC Java opts for extremely simple stubs at the cost of some functionality. Using the Interceptor (or the ClientCall / ServerCall api) allows you access to them, presumably so you can modify the call.
Using them is more advanced, but we have helper classes to avoid errors. Take a look at SimpleForwardingClientCall to help you stub our most of the functionality in your interceptor. It is expected to *not* use thread local variables, but the Context, which is propagated correctly across thread boundaries.