Kelly joue deux saisons à Owens Community College, où il affiche des moyennes de 17,9 points, 10 rebonds, 1 passe décisive, 1,5 interception et 1,5 contre par match. Il devient le premier joueur de l’histoire du programme à atteindre 1 000 points, 600 rebonds, 100 interceptions et 100 contres en carrière.
Lors de sa troisième année, il évolue aux Hurricanes de Miami, après avoir hésité entre Michigan State, West Virginia et New Mexico. Il tourne à 6,0 points et 3,7 rebonds en 17,9 minutes par match, avec une adresse de 40,5% à trois points[1]. Le , il est transféré de Miami à Thundering Herd de Marshall, mais il reste inactif lors de sa première saison à Marshall conformément aux règles de transfert de la NCAA.
Lors de sa dernière année à Marshall, il mène l’équipe au scoring (20,1 points par match), aux rebonds (9,8), aux interceptions (1,3) et aux contres (1,1). Il devient l’un des deux seuls joueurs de l’histoire des Herd à enregistrer au moins 600 points et 300 rebonds sur une seule saison, et le premier à y parvenir à Marshall depuis plus de quarante ans. Il est nommé trois fois Joueur de la semaine de la Conference USA (, et ), Newcomer of the Year de la Conference USA et membre du premier cinq All-Conference USA.
Carrière professionnelle
Non drafté lors de la draft NBA 2016, il rejoint les Hornets de Charlotte pour la NBA Summer League 2016[2].
Le , il est sélectionné en 8e position de la Draft de la KBL par les Incheon ET Land Elephants[3]. En 34 matchs, il termine cinquième meilleur marqueur de la KBL avec 23,2 points, tout en ajoutant 10,1 rebonds, 1,6 passe, 1,5 interception et 1 contre par match.
Le , James Kelly signe un contrat d’un an avec les Changwon LG Sakers[4]. Le , il réalise un double-double avec un record en carrière de 46 points et 12 rebonds, en réussissant 21 tirs sur 30, lors d’une défaite 94–93 contre Anyang KGC[5]. En 45 matchs, il termine troisième meilleur rebondeur de la KBL avec 11 rebonds par match, et affiche également 21,3 points, 1,4 passe et 1 interception de moyenne.
Le , il signe avec l’équipe française Levallois Metropolitans[6], mais un mois plus tard, il se sépare du club avant de disputer le moindre match[7].
Le , il s’engage avec Hapoel Gilboa Galil pour la saison 2018–2019[8]. En 33 matchs, il compile 15,1 points, 7,9 rebonds, 1,7 passe et 1,1 interception par match, avec 57,8% de réussite au tir.
Le , il signe un contrat d’un mois avec Maccabi Rishon LeZion en tant que remplaçant médical de Darryl Monroe[9]. Le , il réalise 27 points, 12 rebonds, 4 passes et 4 interceptions pour une évaluation de 40, lors d’une victoire 96–92 après prolongation contre Ratiopharm Ulm. Il est nommé MVP de la 10e journée d’EuroCoupe[10].
Le , il s’engage avec l'Aris Salonique[11]. En 14 matchs, il affiche des moyennes de 14,9 points, 8,6 rebonds, 1,6 passe, 0,6 contre et 1,4 interception en 27 minutes par match.