diff --git a/.gitignore b/.gitignore
index 30f0e05e896f8273ad7e982e67bbbace82ca86d9..6b99e4e745b949ea523a78580ce80111859315e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,5 +8,5 @@ meta.key
 hsm.crt
 hsm.der
 *.xml
-mdserver.yaml
+mdsigner.yaml
 mdproxy.yaml
diff --git a/README.md b/README.md
index a9c0b0a452ec259db36977605dfd59a9fdea10ef..90105aee2fba9bfb2643c3ffe0547f0d67e1f498 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,10 @@ Alternate MDX research project
 - Download metadata file(s)
 - Run one or more of the tools below
 
-## ```mdsigner.py [mdfile] [mdfile] [mdfile] ...```
+## ```mdwriter.py [mdfile] [mdfile] [mdfile] ...```
 Reads source metadata file(s) and outputs them signed to filesystem
 
-## ```mdserver.py```
+## ```mdsigner.py```
 Starts a metadata signer server.
 Reads source metadata files(s) from mdsigner.yaml configuration, see example.
 Reloads metadata on inotify CLOSE_WRITE of metadata file.
@@ -23,12 +23,12 @@ Serves and caches signed by realm signer from memory, on request
 
 ## ```mdproxy.py```
 Reads config from mdproxy.yaml configuration, see example.
-Caches signed and cached ```mdserver.py``` metadata requests
+Caches signed and cached ```mdsigner.py``` metadata requests
 
 ## Queries
 MDQ Queries can then be pointed at
 
-- ```http://mdserver:5001/<realm>/entities/<entityid>```
+- ```http://mdsigner:5001/<realm>/entities/<entityid>```
 - ```http://mdproxy:5002/<realm>/entities/<entityid>```
 
 ## Bootstrap softHSM2
diff --git a/mdserver.py b/mdserver.py
deleted file mode 100755
index f76b9d845a1c9e377c18a0e4cff4c2bb2574bd5a..0000000000000000000000000000000000000000
--- a/mdserver.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-from utils import read_config, Realm, Server
-from flask import Flask, Response
-from datetime import datetime
-from dateutil import tz
-from email.utils import formatdate
-from time import mktime
-
-import logging
-log = logging.getLogger('werkzeug')
-log.setLevel(logging.ERROR)
-
-config = read_config('mdserver.yaml')
-app = Flask(__name__)
-server = Server()
-
-
-@app.route('/<realm>/entities',
-           strict_slashes=False,
-           methods=['GET'])
-def serve_all(realm):
-    print(f"all in {realm}")
-    response = Response()
-    response.headers['Content-Type'] = "application/samlmetadata+xml"
-    response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
-
-    data = server[realm].all_entities()
-    response.data = data.md
-    max_age = int((data.valid_until -
-                   datetime.now(tz.tzutc())).total_seconds())
-
-    response.headers['Cache-Control'] = f"max-age={max_age}"
-    response.headers['Last-Modified'] = formatdate(
-        timeval=mktime(data.last_modified.timetuple()),
-        localtime=False,
-        usegmt=True)
-    return response
-
-
-@app.route('/<realm>/entities/<path:entity_id>',
-           strict_slashes=False,
-           methods=['GET'])
-def serve_one(realm, entity_id):
-    print(f"entity_id: {entity_id}")
-    response = Response()
-    response.headers['Content-Type'] = "application/samlmetadata+xml"
-    response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
-
-    try:
-        data = server[realm][entity_id]
-        response.data = data.md
-        max_age = data.max_age
-        last_modified = data.last_modified
-    except Exception:
-        response.data = "No valid metadata\n"
-        response.headers['Content-type'] = "text/html"
-        response.status = 404
-        max_age = 60
-        last_modified = datetime.now(tz.tzutc())
-
-    response.headers['Cache-Control'] = f"max-age={max_age}"
-    response.headers['Last-Modified'] = formatdate(
-        timeval=mktime(last_modified.timetuple()),
-        localtime=False,
-        usegmt=True)
-    return response
-
-
-for realm, values in config.items():
-    print(f"realm: {realm}")
-    location = values['metadir']
-    signer = values['signer']
-    server[realm] = Realm(location, signer)
-
-if __name__ == "__main__":
-    app.run(host='127.0.0.1', port=5001, debug=False)
diff --git a/mdsigner.py b/mdsigner.py
index 7c3e160e9dca64a96264c88b4a42b3afbc785bf2..11b06149738ca91d25eb8c8c8472f6addcec2811 100755
--- a/mdsigner.py
+++ b/mdsigner.py
@@ -1,52 +1,76 @@
 #!/usr/bin/env python
-import sys
-import copy
-from concurrent.futures import ThreadPoolExecutor
+from utils import read_config, Realm, Server
+from flask import Flask, Response
+from datetime import datetime
+from dateutil import tz
+from email.utils import formatdate
+from time import mktime
 
-from lxml import etree as ET
-# import traceback
+import logging
+log = logging.getLogger('werkzeug')
+log.setLevel(logging.ERROR)
 
-from utils import hasher
-from signers import Signers
+config = read_config('mdsigner.yaml')
+app = Flask(__name__)
+server = Server()
 
-# Find all IdP's in edugain metadata
-idps = []
-success = 0
-failed = 0
-maxthreads = 8
-signer = Signers('normal_signer')
 
+@app.route('/<realm>/entities',
+           strict_slashes=False,
+           methods=['GET'])
+def serve_all(realm):
+    print(f"all in {realm}")
+    response = Response()
+    response.headers['Content-Type'] = "application/samlmetadata+xml"
+    response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
+
+    data = server[realm].all_entities()
+    response.data = data.md
+    max_age = int((data.valid_until -
+                   datetime.now(tz.tzutc())).total_seconds())
+
+    response.headers['Cache-Control'] = f"max-age={max_age}"
+    response.headers['Last-Modified'] = formatdate(
+        timeval=mktime(data.last_modified.timetuple()),
+        localtime=False,
+        usegmt=True)
+    return response
+
+
+@app.route('/<realm>/entities/<path:entity_id>',
+           strict_slashes=False,
+           methods=['GET'])
+def serve_one(realm, entity_id):
+    print(f"entity_id: {entity_id}")
+    response = Response()
+    response.headers['Content-Type'] = "application/samlmetadata+xml"
+    response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
 
-def sign(xml, name):
-    global success, failed, cert, key
-    # print("Signer")
     try:
-        sha1 = hasher(name)
-        signed = signer(xml)
-        out = ET.tostring(signed, pretty_print=True).decode()
-        # XMLVerifier().verify(out, x509_cert=cert)
-        with open(f'output/{sha1}.xml', 'w') as f:
-            f.write(out)
-        success += 1
-    except Exception as e:
-        print(name)
-        print(f"  {e}")
-        # traceback.print_exc()
-        failed += 1
-
-
-with ThreadPoolExecutor(max_workers=maxthreads) as executor:
-    for mdfile in sys.argv[1:]:
-        tree = ET.ElementTree(file=mdfile)
-        root = tree.getroot()
-        ns = copy.deepcopy(root.nsmap)
-        ns['xml'] = 'http://www.w3.org/XML/1998/namespace'
-
-        for idp in root.findall('md:EntityDescriptor', ns):
-            entityID = idp.attrib.get('entityID', 'none')
-            if entityID not in idps:
-                idps.append(entityID)
-                executor.submit(sign, idp, entityID)
-
-print(f"Succeeded: {success}")
-print(f"Failed: {failed}")
+        data = server[realm][entity_id]
+        response.data = data.md
+        max_age = data.max_age
+        last_modified = data.last_modified
+    except Exception:
+        response.data = "No valid metadata\n"
+        response.headers['Content-type'] = "text/html"
+        response.status = 404
+        max_age = 60
+        last_modified = datetime.now(tz.tzutc())
+
+    response.headers['Cache-Control'] = f"max-age={max_age}"
+    response.headers['Last-Modified'] = formatdate(
+        timeval=mktime(last_modified.timetuple()),
+        localtime=False,
+        usegmt=True)
+    return response
+
+
+for realm, values in config.items():
+    print(f"realm: {realm}")
+    location = values['metadir']
+    signer = values['signer']
+    server[realm] = Realm(location, signer)
+
+if __name__ == "__main__":
+    app.run(host='127.0.0.1', port=5001, debug=False)
diff --git a/mdserver.service b/mdsigner.service
similarity index 66%
rename from mdserver.service
rename to mdsigner.service
index affb8ef4837eb6a3fe8bc8a4291da032276e064c..8de380e4fd581f246d94e1ffe6598bd99f065128 100644
--- a/mdserver.service
+++ b/mdsigner.service
@@ -1,15 +1,15 @@
 [Unit]
-Description=MDServer
+Description=MDSigner
 After=syslog.target network.target
 
 [Service]
 Type=simple
 WorkingDirectory=/opt/alternate-mdx
-ExecStart=/opt/alternate-mdx/bin/python -u mdserver.py
+ExecStart=/opt/alternate-mdx/bin/python -u mdsigner.py
 ExecReload=/bin/kill -HUP $MAINPID
 Restart=on-failure
 RestartSec=10
-SyslogIdentifier=mdserver
+SyslogIdentifier=mdsigner
 
 [Install]
 WantedBy=multi-user.target
diff --git a/mdwriter.py b/mdwriter.py
new file mode 100755
index 0000000000000000000000000000000000000000..7c3e160e9dca64a96264c88b4a42b3afbc785bf2
--- /dev/null
+++ b/mdwriter.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+import sys
+import copy
+from concurrent.futures import ThreadPoolExecutor
+
+from lxml import etree as ET
+# import traceback
+
+from utils import hasher
+from signers import Signers
+
+# Find all IdP's in edugain metadata
+idps = []
+success = 0
+failed = 0
+maxthreads = 8
+signer = Signers('normal_signer')
+
+
+def sign(xml, name):
+    global success, failed, cert, key
+    # print("Signer")
+    try:
+        sha1 = hasher(name)
+        signed = signer(xml)
+        out = ET.tostring(signed, pretty_print=True).decode()
+        # XMLVerifier().verify(out, x509_cert=cert)
+        with open(f'output/{sha1}.xml', 'w') as f:
+            f.write(out)
+        success += 1
+    except Exception as e:
+        print(name)
+        print(f"  {e}")
+        # traceback.print_exc()
+        failed += 1
+
+
+with ThreadPoolExecutor(max_workers=maxthreads) as executor:
+    for mdfile in sys.argv[1:]:
+        tree = ET.ElementTree(file=mdfile)
+        root = tree.getroot()
+        ns = copy.deepcopy(root.nsmap)
+        ns['xml'] = 'http://www.w3.org/XML/1998/namespace'
+
+        for idp in root.findall('md:EntityDescriptor', ns):
+            entityID = idp.attrib.get('entityID', 'none')
+            if entityID not in idps:
+                idps.append(entityID)
+                executor.submit(sign, idp, entityID)
+
+print(f"Succeeded: {success}")
+print(f"Failed: {failed}")