You have it right.
It is literally a container that allows you to pipeline functions on its contents. The only technical catch is that you aren't allowed to change the type of the contents in the function. That means if you start with something of type A in the container, you have to get a container containing something of type A at each stage of the pipeline.
There are probably 3 popular uses for monads. First to defer error handling. You allow type A to include some kind of error state. The you run your entire pipeline of functions, but at every stage if the container contains an error, you just return a container with the same error as output. That way, none of your pipeline stages need to check for valid input -- they just assume there were no errors before their stage.
The second main case is to defer processing until a later time. You have a pipeline of functions and a container. As long as you don't look at the result of running that pipeline, even if the container doesn't contain anything yet you can pretend that it represents your result. You can pass that along in your program, gradually appending more functions on your pipeline as you go. When you finally put something in the container, you can see what the result is. This is useful when you don't know what your result is right now, but you know what processing you want to do when you get the input (for example, if you are going to query some external system and when it returns you want to do some processing. You can go ahead and pretend to process that result and when the data finally arrives, then you can actually get the result of the computation).
The third main case is when you have a big list and you want to narrow it. For instance, you might have a list of food. You want to narrow that to a list of fruit. Then you want to narrow that to a list of red fruit. Then you want to narrow that to a list of red fruits that are berries. Instead of writing a function to do your whole query, you can separate it: A query for fruit. A query for red. A query for berries. This can make your code a lot easier to read.
There are other things you can do with monads, but that's the basics IMHO. They really are simple, but suprisingly enlightening. You might think, "This constraint that I return the same type each time is kind of annoying", but if you spend a fair amount of time with monads you will see that this allows you to make pretty amazing assumptions in your code -- which, in turn, let you do very powerful things.