diff --git a/jc/lib.py b/jc/lib.py
index 8db37280..35a023c5 100644
--- a/jc/lib.py
+++ b/jc/lib.py
@@ -58,6 +58,7 @@ parsers: List[str] = [
     'hashsum',
     'hciconfig',
     'history',
+    'host',
     'hosts',
     'id',
     'ifconfig',
diff --git a/jc/parsers/host.py b/jc/parsers/host.py
new file mode 100644
index 00000000..c1a1a106
--- /dev/null
+++ b/jc/parsers/host.py
@@ -0,0 +1,248 @@
+"""jc - JSON Convert `host` command output parser
+
+Supports parsing of the most commonly used RR types (A, AAAA, MX, TXT)
+
+Usage (cli):
+
+    $ host google.com | jc --host
+
+or
+
+    $ jc host google.com
+
+Usage (module):
+
+    import jc
+    result = jc.parse('host', host_command_output)
+
+Schema:
+
+    [
+      {
+        "hostname":     string,
+        "address": [
+                        string
+        ],
+        "v6-address": [
+                        string
+        ],
+        "mail": [
+                        string
+        ]
+      }
+    ]
+
+    [
+      {
+        "nameserver":   string,
+        "zone":         string,
+        "mname":        string,
+        "rname":        string,
+        "serial":       integer,
+        "refresh":      integer,
+        "retry":        integer,
+        "expire":       integer,
+        "minimum":      integer
+      }
+    ]
+
+Examples:
+
+    $ host google.com | jc --host
+    [
+      {
+        "hostname": "google.com",
+        "address": [
+          "142.251.39.110"
+        ],
+        "v6-address": [
+          "2a00:1450:400e:811::200e"
+        ],
+        "mail": [
+          "smtp.google.com."
+        ]
+      }
+    ]
+
+    $ jc host -C sunet.se
+    [
+      {
+        "nameserver": "2001:6b0:7::2",
+        "zone": "sunet.se",
+        "mname": "sunic.sunet.se.",
+        "rname": "hostmaster.sunet.se.",
+        "serial": "2023090401",
+        "refresh": "28800",
+        "retry": "7200",
+        "expire": "604800",
+        "minimum": "300"
+      },
+      {
+        ...
+      }
+    ]
+"""
+from typing import Dict, List
+import jc.utils
+
+
+class info():
+    """Provides parser metadata (version, author, etc.)"""
+    version = '1.0'
+    description = '`host` command parser'
+    author = 'Pettai'
+    author_email = 'pettai@sunet.se'
+    # details = 'enter any other details here'
+
+    # compatible options: linux, darwin, cygwin, win32, aix, freebsd
+    compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
+
+    # tags options: generic, standard, file, string, binary, command
+    tags = ['command']
+    magic_commands = ['host']
+
+
+__version__ = info.version
+
+
+def _process(proc_data):
+    """
+    Final processing to conform to the schema.
+
+    Parameters:
+
+        proc_data:   (List of Dictionaries) raw structured data to process
+
+    Returns:
+
+        List of Dictionaries. Structured to conform to the schema.
+    """
+
+    int_list = {'serial', 'refresh', 'retry', 'expire', 'minimum'}
+
+    for entry in proc_data:
+        for key in entry:
+            if key in int_list:
+                entry[key] = jc.utils.convert_to_int(entry[key])
+
+    return proc_data
+
+
+def parse(data: str, raw: bool = False, quiet: bool = False):
+    """
+    Main text parsing function
+
+    Parameters:
+
+        data:        (string)  text data to parse
+        raw:         (boolean) unprocessed output if True
+        quiet:       (boolean) suppress warning messages if True
+
+    Returns:
+
+        List of Dictionaries. Raw or processed structured data.
+    """
+    jc.utils.compatibility(__name__, info.compatible, quiet)
+    jc.utils.input_type_check(data)
+
+    raw_output: List[Dict] = []
+ 
+    warned = False
+
+    if jc.utils.has_data(data):
+
+        addresses = []
+        v6addresses = []
+        mail = []
+        text = []
+        rrdata = {}
+        soaparse = False
+
+        for line in filter(None, data.splitlines()):
+            line = line.strip()
+
+            # default
+            if ' has address ' in line:
+                linedata = line.split(' ', maxsplit=3)
+                hostname = linedata[0]
+                address = linedata[3]
+                addresses.append(address)
+                rrdata.update({'hostname': hostname})
+                rrdata.update({'address': addresses})
+                continue
+
+            if ' has IPv6 address ' in line:
+                linedata = line.split(' ', maxsplit=4)
+                hostname = linedata[0]
+                v6address = linedata[4]
+                v6addresses.append(v6address)
+                rrdata.update({'hostname': hostname})
+                rrdata.update({'v6-address': v6addresses})
+                continue
+
+            if ' mail is handled by ' in line:
+                linedata = line.split(' ', maxsplit=6)
+                hostname = linedata[0]
+                mx = linedata[6]
+                mail.append(mx)
+                rrdata.update({'hostname': hostname})
+                rrdata.update({'mail': mail})
+                continue
+
+
+            # TXT parsing
+            if ' descriptive text ' in line:
+                linedata = line.split('descriptive text "', maxsplit=1)
+                hostname = linedata[0]
+                txt = linedata[1].strip('"')
+                text.append(txt)
+                rrdata.update({'hostname': hostname})
+                rrdata.update({'text': text})
+                continue
+
+
+            # -C / SOA parsing
+            if line.startswith('Nameserver '):
+                soaparse = True
+                rrdata = {}
+                linedata = line.split(' ', maxsplit=1)
+                nameserverip = linedata[1].rstrip(':')
+                rrdata.update({'nameserver': nameserverip})
+                continue
+
+            if ' has SOA record ' in line:
+                linedata = line.split(' ', maxsplit=10)
+
+                zone = linedata[0]
+                mname = linedata[4]
+                rname = linedata[5]
+                serial = linedata[6]
+                refresh = linedata[7]
+                retry = linedata[8]
+                expire = linedata[9]
+                minimum = linedata[10]
+            
+                try:
+                    rrdata.update(
+                        {
+                            'zone': zone,
+                            'mname': mname,
+                            'rname': rname,
+                            'serial': serial,
+                            'refresh': refresh,
+                            'retry': retry,
+                            'expire': expire,
+                            'minimum': minimum 
+                        },
+                    )
+                    raw_output.append(rrdata)
+
+                except IndexError:
+                    if not warned:
+                        jc.utils.warning_message(['Unknown format detected.'])
+                        warned = True
+
+        if not soaparse:
+            raw_output.append(rrdata)
+
+    return raw_output if raw else _process(raw_output)
diff --git a/tests/fixtures/generic/host-google.json b/tests/fixtures/generic/host-google.json
new file mode 100644
index 00000000..149bf4f9
--- /dev/null
+++ b/tests/fixtures/generic/host-google.json
@@ -0,0 +1 @@
+[{"hostname":"google.com","address":["142.250.179.206"],"v6-address":["2a00:1450:400e:811::200e"],"mail":["smtp.google.com."]}]
diff --git a/tests/fixtures/generic/host-google.out b/tests/fixtures/generic/host-google.out
new file mode 100644
index 00000000..009113f7
--- /dev/null
+++ b/tests/fixtures/generic/host-google.out
@@ -0,0 +1,3 @@
+google.com has address 142.250.179.206
+google.com has IPv6 address 2a00:1450:400e:811::200e
+google.com mail is handled by 10 smtp.google.com.
diff --git a/tests/fixtures/generic/host-sunet.json b/tests/fixtures/generic/host-sunet.json
new file mode 100644
index 00000000..49f14529
--- /dev/null
+++ b/tests/fixtures/generic/host-sunet.json
@@ -0,0 +1 @@
+[{"nameserver":"192.36.125.2","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"193.10.252.19","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"2001:6b0:1::250","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"2001:948:4:2::19","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"2001:6b0:5a:4020::384","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"130.237.72.250","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"2001:6b0:7::2","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300},{"nameserver":"89.47.185.240","zone":"sunet.se","mname":"hidden-master.sunet.se.","rname":"hostmaster.sunet.se.","serial":2023091102,"refresh":28800,"retry":7200,"expire":604800,"minimum":300}]
diff --git a/tests/fixtures/generic/host-sunet.out b/tests/fixtures/generic/host-sunet.out
new file mode 100644
index 00000000..e8f6e178
--- /dev/null
+++ b/tests/fixtures/generic/host-sunet.out
@@ -0,0 +1,16 @@
+Nameserver 192.36.125.2:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 193.10.252.19:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 2001:6b0:1::250:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 2001:948:4:2::19:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 2001:6b0:5a:4020::384:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 130.237.72.250:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 2001:6b0:7::2:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
+Nameserver 89.47.185.240:
+	sunet.se has SOA record hidden-master.sunet.se. hostmaster.sunet.se. 2023091102 28800 7200 604800 300
diff --git a/tests/test_host.py b/tests/test_host.py
new file mode 100644
index 00000000..272fb981
--- /dev/null
+++ b/tests/test_host.py
@@ -0,0 +1,58 @@
+import os
+import unittest
+import json
+from typing import Dict
+from jc.parsers.host import parse
+
+THIS_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+class MyTests(unittest.TestCase):
+    f_in: Dict = {}
+    f_json: Dict = {}
+
+    @classmethod
+    def setUpClass(cls):
+        fixtures = {
+            'google': (
+                'fixtures/generic/host-google.out',
+                'fixtures/generic/host-google.json'),
+            'sunet': (
+                'fixtures/generic/host-sunet.out',
+                'fixtures/generic/host-sunet.json')
+        }
+
+        for file, filepaths in fixtures.items():
+            with open(os.path.join(THIS_DIR, filepaths[0]), 'r', encoding='utf-8') as a, \
+                 open(os.path.join(THIS_DIR, filepaths[1]), 'r', encoding='utf-8') as b:
+                cls.f_in[file] = a.read()
+                cls.f_json[file] = json.loads(b.read())
+
+#    host cannot run without input (will only display help)
+#    def test_host_nodata(self):
+#        """
+#        Test 'host' with no data
+#        """
+#        self.assertEqual(parse('', quiet=True), {})
+
+
+    def test_host_google(self):
+        """
+        Test 'host google'
+        """
+        self.assertEqual(
+            parse(self.f_in['google'], quiet=True),
+            self.f_json['google']
+        )
+
+    def test_host_sunet(self):
+        """
+        Test 'host sunet'
+        """
+        self.assertEqual(
+            parse(self.f_in['sunet'], quiet=True),
+            self.f_json['sunet']
+        )
+
+if __name__ == '__main__':
+    unittest.main()