diff --git a/doxygen/siphon_process.py b/doxygen/siphon_process.py
new file mode 100755
index 0000000..80add4b
--- /dev/null
+++ b/doxygen/siphon_process.py
@@ -0,0 +1,323 @@
+#!/usr/bin/env python
+# Copyright (c) 2016 Comcast Cable Communications Management, LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Filter for .siphon files that are generated by other filters.
+# The idea is to siphon off certain initializers so that we can better
+# auto-document the contents of that initializer.
+
+import os, sys, re, argparse, cgi, json
+import pyparsing as pp
+
+import pprint
+
+DEFAULT_SIPHON ="clicmd"
+DEFAULT_OUTPUT = None
+DEFAULT_PREFIX = os.getcwd()
+
+siphon_map = {
+    'clicmd': "VLIB_CLI_COMMAND",
+}
+
+ap = argparse.ArgumentParser()
+ap.add_argument("--type", '-t', metavar="siphon_type", default=DEFAULT_SIPHON,
+        choices=siphon_map.keys(),
+        help="Siphon type to process [%s]" % DEFAULT_SIPHON)
+ap.add_argument("--output", '-o', metavar="directory", default=DEFAULT_OUTPUT,
+        help="Output directory for .md files [%s]" % DEFAULT_OUTPUT)
+ap.add_argument("--input-prefix", metavar="path", default=DEFAULT_PREFIX,
+        help="Prefix to strip from input pathnames [%s]" % DEFAULT_PREFIX)
+ap.add_argument("input", nargs='+', metavar="input_file",
+        help="Input .siphon files")
+args = ap.parse_args()
+
+if args.output is None:
+    sys.stderr.write("Error: Siphon processor requires --output to be set.")
+    sys.exit(1)
+
+
+def clicmd_index_sort(cfg, group, dec):
+    if group in dec and 'group_label' in dec[group]:
+        return dec[group]['group_label']
+    return group
+
+def clicmd_index_header(cfg):
+    s = "# CLI command index\n"
+    s += "\n[TOC]\n"
+    return s
+
+def clicmd_index_section(cfg, group, md):
+    return "\n@subpage %s\n\n" % md
+
+def clicmd_index_entry(cfg, meta, item):
+    v = item["value"]
+    return "* [%s](@ref %s)\n" % (v["path"], meta["label"])
+
+def clicmd_sort(cfg, meta, item):
+    return item['value']['path']
+
+def clicmd_header(cfg, group, md, dec):
+    if group in dec and 'group_label' in dec[group]:
+        label = dec[group]['group_label']
+    else:
+        label = group
+    return "\n@page %s %s\n" % (md, label)
+
+def clicmd_format(cfg, meta, item):
+    v = item["value"]
+    s = "\n@section %s %s\n" % (meta['label'], v['path'])
+
+    # The text from '.short_help = '.
+    # Later we should split this into short_help and usage_help
+    # since the latter is how it is primarily used but the former
+    # is also needed.
+    if "short_help" in v:
+        tmp = v["short_help"].strip()
+
+        # Bit hacky. Add a trailing period if it doesn't have one.
+        if tmp[-1] != ".":
+            tmp += "."
+
+        s += "### Summary/usage\n    %s\n\n" % tmp
+
+    # This is seldom used and will likely be deprecated
+    if "long_help" in v:
+        tmp = v["long_help"]
+
+        s += "### Long help\n    %s\n\n" % tmp
+
+    # Extracted from the code in /*? ... ?*/ blocks
+    if "siphon_block" in item["meta"]:
+        sb = item["meta"]["siphon_block"]
+
+        if sb != "":
+            # hack. still needed?
+            sb = sb.replace("\n", "\\n")
+            try:
+                sb = json.loads('"'+sb+'"')
+                s += "### Description\n%s\n\n" % sb
+            except:
+                pass
+
+    # Gives some developer-useful linking
+    if "item" in meta or "function" in v:
+        s += "### Declaration and implementation\n\n"
+
+        if "item" in meta:
+            s += "Declaration: @ref %s (%s:%d)\n\n" % \
+                (meta['item'], meta["file"], int(item["meta"]["line_start"]))
+
+        if "function" in v:
+            s += "Implementation: @ref %s.\n\n" % v["function"]
+
+    return s
+
+
+siphons = {
+    "VLIB_CLI_COMMAND": {
+        "index_sort_key": clicmd_index_sort,
+        "index_header": clicmd_index_header,
+        "index_section": clicmd_index_section,
+        "index_entry": clicmd_index_entry,
+        'sort_key': clicmd_sort,
+        "header": clicmd_header,
+        "format": clicmd_format,
+    }
+}
+
+
+# PyParsing definition for our struct initializers which look like this:
+# VLIB_CLI_COMMAND (show_sr_tunnel_command, static) = {
+#    .path = "show sr tunnel",
+#    .short_help = "show sr tunnel [name <sr-tunnel-name>]",
+#    .function = show_sr_tunnel_fn,
+#};
+def getMacroInitializerBNF():
+    cs = pp.Forward()
+    ident = pp.Word(pp.alphas + "_", pp.alphas + pp.nums + "_")
+    intNum = pp.Word(pp.nums)
+    hexNum = pp.Literal("0x") + pp.Word(pp.hexnums)
+    octalNum = pp.Literal("0") + pp.Word("01234567")
+    integer = (hexNum | octalNum | intNum) + \
+        pp.Optional(pp.Literal("ULL") | pp.Literal("LL") | pp.Literal("L"))
+    floatNum = pp.Regex(r'\d+(\.\d*)?([eE]\d+)?') + pp.Optional(pp.Literal("f"))
+    char = pp.Literal("'") + pp.Word(pp.printables, exact=1) + pp.Literal("'")
+    arrayIndex = integer | ident
+
+    lbracket = pp.Literal("(").suppress()
+    rbracket = pp.Literal(")").suppress()
+    lbrace = pp.Literal("{").suppress()
+    rbrace = pp.Literal("}").suppress()
+    comma = pp.Literal(",").suppress()
+    equals = pp.Literal("=").suppress()
+    dot = pp.Literal(".").suppress()
+    semicolon = pp.Literal(";").suppress()
+
+    # initializer := { [member = ] (variable | expression | { initializer } ) }
+    typeName = ident
+    varName = ident
+
+    typeSpec = pp.Optional("unsigned") + \
+               pp.oneOf("int long short float double char u8 i8 void") + \
+               pp.Optional(pp.Word("*"), default="")
+    typeCast = pp.Combine( "(" + ( typeSpec | typeName ) + ")" ).suppress()
+
+    string = pp.Combine(pp.OneOrMore(pp.QuotedString(quoteChar='"',
+        escChar='\\', multiline=True)), adjacent=False)
+    literal = pp.Optional(typeCast) + (integer | floatNum | char | string)
+    var = pp.Combine(pp.Optional(typeCast) + varName + pp.Optional("[" + arrayIndex + "]"))
+
+    expr = (literal | var) # TODO
+
+
+    member = pp.Combine(dot + varName + pp.Optional("[" + arrayIndex + "]"))
+    value = (expr | cs)
+
+    entry = pp.Group(pp.Optional(member + equals, default="") + value)
+    entries = (pp.ZeroOrMore(entry + comma) + entry + pp.Optional(comma)) | \
+              (pp.ZeroOrMore(entry + comma))
+
+    cs << (lbrace + entries + rbrace)
+
+    macroName = ident
+    params = pp.Group(pp.ZeroOrMore(expr + comma) + expr)
+    macroParams = lbracket + params + rbracket
+
+    mi = macroName + pp.Optional(macroParams) + equals + pp.Group(cs) + semicolon
+    mi.ignore(pp.cppStyleComment)
+    return mi
+
+
+mi = getMacroInitializerBNF()
+
+# Parse the input file into a more usable dictionary structure
+cmds = {}
+line_num = 0
+line_start = 0
+for filename in args.input:
+    sys.stderr.write("Parsing items in file \"%s\"...\n" % filename)
+    data = None
+    with open(filename, "r") as fd:
+        data = json.load(fd)
+
+    cmds['_global'] = data['global']
+
+    # iterate the items loaded and regroup it
+    for item in data["items"]:
+        try:
+            o = mi.parseString(item['block']).asList()
+        except:
+            sys.stderr.write("Exception parsing item: %s\n%s\n" \
+                    % (json.dumps(item, separators=(',', ': '), indent=4),
+                        item['block']))
+            raise
+
+        group = item['group']
+        file = item['file']
+        macro = o[0]
+        param = o[1][0]
+
+        if group not in cmds:
+            cmds[group] = {}
+
+        if file not in cmds[group]:
+            cmds[group][file] = {}
+
+        if macro not in cmds[group][file]:
+            cmds[group][file][macro] = {}
+
+        c = {
+            'params': o[2],
+            'meta': {},
+            'value': {},
+        }
+
+        for key in item:
+            if key == 'block':
+                continue
+            c['meta'][key] = item[key]
+
+        for i in c['params']:
+            c['value'][i[0]] = cgi.escape(i[1])
+
+        cmds[group][file][macro][param] = c
+
+
+# Write the header for this siphon type
+cfg = siphons[siphon_map[args.type]]
+sys.stdout.write(cfg["index_header"](cfg))
+contents = ""
+
+def group_sort_key(item):
+    if "index_sort_key" in cfg:
+        return cfg["index_sort_key"](cfg, item, cmds['_global'])
+    return item
+
+# Iterate the dictionary and process it
+for group in sorted(cmds.keys(), key=group_sort_key):
+    if group.startswith('_'):
+        continue
+
+    sys.stderr.write("Processing items in group \"%s\"...\n" % group)
+
+    cfg = siphons[siphon_map[args.type]]
+    md = group.replace("/", "_").replace(".", "_")
+    sys.stdout.write(cfg["index_section"](cfg, group, md))
+
+    if "header" in cfg:
+        dec = cmds['_global']
+        contents += cfg["header"](cfg, group, md, dec)
+
+    for file in sorted(cmds[group].keys()):
+        if group.startswith('_'):
+            continue
+
+        sys.stderr.write("- Processing items in file \"%s\"...\n" % file)
+
+        for macro in sorted(cmds[group][file].keys()):
+            if macro != siphon_map[args.type]:
+                continue
+            sys.stderr.write("-- Processing items in macro \"%s\"...\n" % macro)
+            cfg = siphons[macro]
+
+            meta = {
+                "group": group,
+                "file": file,
+                "macro": macro,
+                "md": md,
+            }
+
+            def item_sort_key(item):
+                if "sort_key" in cfg:
+                    return cfg["sort_key"](cfg, meta, cmds[group][file][macro][item])
+                return item
+
+            for param in sorted(cmds[group][file][macro].keys(), key=item_sort_key):
+                sys.stderr.write("--- Processing item \"%s\"...\n" % param)
+
+                meta["item"] = param
+
+                # mangle "md" and the item to make a reference label
+                meta["label"] = "%s___%s" % (meta["md"], param)
+
+                if "index_entry" in cfg:
+                    s = cfg["index_entry"](cfg, meta, cmds[group][file][macro][param])
+                    sys.stdout.write(s)
+
+                if "format" in cfg:
+                    contents += cfg["format"](cfg, meta, cmds[group][file][macro][param])
+
+sys.stdout.write(contents)
+
+# All done
