Make bone roll match a face/vertex normal?
Construct the bone matrix

Here is a script that creates a  bone at each edge such that the bones y axis is aligned vert 0 to vert 1 and the z axis to the &quot;edge normal&quot; ie the average of the two linked face normals.
Select mesh object in object mode, run script creates an armature with bone on each edge.
import bpy
import bmesh
from mathutils import Vector, Matrix
context = bpy.context
vl = context.view_layer
coll = context.collection
ob = context.object # the mesh
me = ob.data
bm = bmesh.new()
bm.from_mesh(me)
arm = bpy.data.armatures.new(&quot;Foo&quot;)
arm_obj = bpy.data.objects.new(&quot;Foo&quot;, arm)
coll.objects.link(arm_obj)
vl.objects.active = arm_obj
bpy.ops.object.mode_set(mode='EDIT')

for e in bm.edges:
    eb = arm.edit_bones.new(f&quot;edge{e.index}&quot;)
    v = e.verts[1].co - e.verts[0].co
    
    y = v.normalized()
    z = sum((f.normal for f in e.link_faces), Vector()).normalized()
    x = y.cross(z)
    M = Matrix((x, y, z)).transposed().to_4x4()
    M.translation = e.verts[0].co
    eb.matrix = M
    eb.tail = e.verts[1].co

bpy.ops.object.mode_set()