diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua
index 18c359e2c..3c1ac9d34 100644
--- a/mods/ITEMS/mcl_anvils/init.lua
+++ b/mods/ITEMS/mcl_anvils/init.lua
@@ -1,7 +1,12 @@
 local MAX_NAME_LENGTH = 30
 local MAX_WEAR = 65535
 local SAME_TOOL_REPAIR_BOOST = math.ceil(MAX_WEAR * 0.12) -- 12%
-local MATERIAL_TOOL_REPAIR_BOOST = math.ceil(MAX_WEAR * 0.25) -- 25%
+local MATERIAL_TOOL_REPAIR_BOOST = {
+	math.ceil(MAX_WEAR * 0.25), -- 25%
+	math.ceil(MAX_WEAR * 0.5), -- 50%
+	math.ceil(MAX_WEAR * 0.75), -- 75%
+	MAX_WEAR, -- 100%
+}
 local NAME_COLOR = "#FFFF4C"
 
 local function get_anvil_formspec(set_name)
@@ -25,6 +30,41 @@ local function get_anvil_formspec(set_name)
 	"listring[current_player;main]"
 end
 
+-- Given a tool and material stack, returns how many items of the material stack
+-- needs to be used up to repair the tool.
+local function get_consumed_materials(tool, material)
+	local wear = tool:get_wear()
+	if wear == 0 then
+		return 0
+	end
+	local health = (MAX_WEAR - wear)
+	local matsize = material:get_count()
+	local materials_used = 0
+	for m=1, math.min(4, matsize) do
+		materials_used = materials_used + 1
+		if (wear - MATERIAL_TOOL_REPAIR_BOOST[m]) <= 0 then
+			break
+		end
+	end
+	return materials_used
+end
+
+-- Given 2 input stacks, tells you which is the tool and which is the material.
+-- Returns ("tool", input1, input2) if input1 is tool and input2 is material.
+-- Returns ("material", input2, input1) if input1 is material and input2 is tool.
+-- Returns nil otherwise.
+local function distinguish_tool_and_material(input1, input2)
+	local def1 = input1:get_definition()
+	local def2 = input2:get_definition()
+	if def1.type == "tool" and def1._repair_material then
+		return "tool", input1, input2
+	elseif def2.type == "tool" and def2._repair_material then
+		return "material", input2, input1
+	else
+		return nil
+	end
+end
+
 -- Update the inventory slots of an anvil node.
 -- meta: Metadata of anvil node
 local function update_anvil_slots(meta)
@@ -72,17 +112,9 @@ local function update_anvil_slots(meta)
 
 			-- Big repair bonus
 			-- TODO: Combine tool enchantments
-			local tool, tooldef, material
-			if def1.type == "tool" and def1._repair_material then
-				tool = input1
-				tooldef = def1
-				material = input2
-			elseif def2.type == "tool" and def2._repair_material then
-				tool = input2
-				tooldef = def2
-				material = input1
-			end
-			if tool and material then
+			local distinguished, tool, material = distinguish_tool_and_material(input1, input2)
+			if distinguished then
+				local tooldef = tool:get_definition()
 				local has_correct_material = false
 				if string.sub(tooldef._repair_material, 1, 6) == "group:" then
 					has_correct_material = minetest.get_item_group(material:get_name(), string.sub(tooldef._repair_material, 7)) ~= 0
@@ -90,7 +122,8 @@ local function update_anvil_slots(meta)
 					has_correct_material = true
 				end
 				if has_correct_material and tool:get_wear() > 0 then
-					local new_wear = calculate_repair(tool:get_wear(), MAX_WEAR, MATERIAL_TOOL_REPAIR_BOOST)
+					local materials_used = get_consumed_materials(tool, material)
+					local new_wear = calculate_repair(tool:get_wear(), MAX_WEAR, MATERIAL_TOOL_REPAIR_BOOST[materials_used])
 					tool:set_wear(new_wear)
 					name_item = tool
 					new_output = name_item
@@ -285,12 +318,29 @@ local anvildef = {
 			local inv = meta:get_inventory()
 			local input1 = inv:get_stack("input", 1)
 			local input2 = inv:get_stack("input", 2)
+			-- Both slots occupied?
 			if not input1:is_empty() and not input2:is_empty() then
-				-- Both slots occupied: Repair mode. Only take 1 item from each stack
-				input1:take_item()
-				input2:take_item()
-				inv:set_stack("input", 1, input1)
-				inv:set_stack("input", 2, input2)
+				-- Take as many items as needed
+				local distinguished, tool, material = distinguish_tool_and_material(input1, input2)
+				if distinguished then
+					-- Tool + material: Take tool and as many materials as needed
+					local materials_used = get_consumed_materials(tool, material)
+					material:set_count(material:get_count() - materials_used)
+					tool:take_item()
+					if distinguished == "tool" then
+						input1, input2 = tool, material
+					else
+						input1, input2 = material, tool
+					end
+					inv:set_stack("input", 1, input1)
+					inv:set_stack("input", 2, input2)
+				else
+					-- Else take 1 item from each stack
+					input1:take_item()
+					input2:take_item()
+					inv:set_stack("input", 1, input1)
+					inv:set_stack("input", 2, input2)
+				end
 			else
 				-- Otherwise: Rename mode: Clear all input slots as the whole stack is renamed.
 				inv:set_list("input", {"", ""})