Too low accuracy on MNIST dataset using a neural network
What am I missing?



Incorrect architecture for the classification task. You have a single binary output, trained using binary_crossentropy, so the NN can only classify something as in a class (label 1) or not (label 0). Instead, you most likely want 10 outputs using softmax activation instead of sigmoid, and categorical_crossentropy as the loss, so that you can classify which digit is most likely given an input.
Incomplete processing of MNIST raw data. The input pixel values in X_train range from 0 to 255, and this will cause numeric problems for a NN. The target labels in y_train are the digit value (0,1,2,3,4,5,6,7,8,9), whilst for classification you will need to turn that into binary classes - usually a one-hot coding e.g. the label 3 becomes a vector [0,0,0,1,0,0,0,0,0,0].


Scale the inputs - a quick fix might be X_train = X_train/ 255 and X_test = X_test/ 255
One-hot code the labels. A quick fix might be y_train = keras.utils.to_categorical(y_train)



I made those changes to your code and got this after 10 epochs:

val_loss: 0.1194 - val_acc: 0.9678