When you index with image[y,x] you're getting a 3-element list [b,g,r]. If you want to add 100 to the red channel then you can index the color directly and add the number image[y,x,2].
However, when you add scalar values directly to the colors like this, there's nothing protecting you from overflowing the UInt8 value. If it goes over 255 it'll wrap back around to zero. You can either manually do the overflow check yourself or use OpenCV's cv2.add() function.
import cv2
import numpy as np
# load image
img = cv2.imread("test.jpg");
orig = np.copy(img);
# create blank image
red = np.zeros_like(img);
# fill with red
red[:,:] = [0,0,100]; # (b,g,r)
# add to image (has overflow protection, values are clamped between [0,255])
img = cv2.add(img, red);
# show
cv2.imshow("Original", orig);
cv2.imshow("OpenCV Add", img);
cv2.waitKey(0);
# do it with loops
img = np.copy(orig);
unprotected = np.copy(orig);
height, width = img.shape[:2];
# loop through and add 100 red to each pixel
# WARNING, this method has no automatic overflow protection
# if the red value goes over 255 then it'll wrap back around to 0 (i.e. 200 + 100 will give 45)
for y in range(height):
for x in range(width):
# overflow check
if 100 + img[y,x,2] > 255:
# saturate value
img[y,x,2] = 255;
else:
# add normally
img[y,x,2] += 100;
# always add to unprotected image
unprotected[y,x,2] += 100;
# show
cv2.imshow("Looping Add", img);
cv2.imshow("Unprotected", unprotected);
cv2.waitKey(0);
Overflow Protected

No Overflow Protection
