diff --git a/services/capability/MANIFEST.in b/services/capability/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..5e84c8812c023a08f88d019026c11f34ebcde103
--- /dev/null
+++ b/services/capability/MANIFEST.in
@@ -0,0 +1,5 @@
+include *.txt *.ini *.cfg *.rst *.wsgi *.sh *.spec *.md *.py
+recursive-include services *.ico *.png *.svg *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.ttf *.woff *.woff2
+include MANIFEST.in
+include README.txt
+include workflow/*
diff --git a/services/capability/README.md b/services/capability/README.md
index fad90cd376db7b0709b134c6e0e55e84d9134a53..e0dc6f31b9f24903492a0c38a73e95f8b4d94082 100644
--- a/services/capability/README.md
+++ b/services/capability/README.md
@@ -1 +1,15 @@
-# Workspaces Capability Service
+# Capability: The Workspaces Capability Service
+
+To use, first run the Alembic migrations in /schema:
+
+    env CAPO_PROFILE=local alembic upgrade head
+Then run:
+    `python setup.py develop`
+    
+Then you should be able to run this with:
+
+    env CAPO_PROFILE=local pserve --reload development.ini
+
+Once there, try the following URLs:
+
+- http://0.0.0.0:3456/capabilities
diff --git a/services/capability/capability.wsgi b/services/capability/capability.wsgi
new file mode 100644
index 0000000000000000000000000000000000000000..480a8b8b37ead924c75df26f74ef11832bba44b3
--- /dev/null
+++ b/services/capability/capability.wsgi
@@ -0,0 +1,22 @@
+# workflow.wsgi
+from pyramid.paster import get_app, setup_logging
+import os
+
+import socket
+
+fqdn = socket.getfqdn()
+if "shipman" in fqdn:
+    os.environ['CAPO_PROFILE'] = 'dsoc-prod'
+elif "wirth" in fqdn:
+    os.environ['CAPO_PROFILE'] = 'dsoc-dev'
+elif "hamilton" in fqdn:
+    os.environ['CAPO_PROFILE'] = 'dsoc-test'
+else:
+    os.environ['CAPO_PROFILE'] = 'local'
+
+# os.environ['CAPO_PROFILE'] = 'products'
+
+ini_path = os.path.dirname(__file__) + '/production.ini'
+
+setup_logging(ini_path)
+application = get_app(ini_path, 'main')
diff --git a/services/capability/development.ini b/services/capability/development.ini
new file mode 100644
index 0000000000000000000000000000000000000000..41d5e207f30a8d008bec566559bd0b40cfa679e1
--- /dev/null
+++ b/services/capability/development.ini
@@ -0,0 +1,49 @@
+[app:main]
+use = egg:ssa-capability
+pyramid.includes =
+    pyramid_debugtoolbar
+    pyramid_tm
+pyramid.reload_all = true
+
+session.cookie_expires = true
+session.auto = true
+
+[server:main]
+use = egg:waitress#main
+listen = 0.0.0.0:3456
+
+
+[loggers]
+keys = root, workflow
+
+[handlers]
+keys = console, filelog
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_workflow]
+level = DEBUG
+handlers =
+qualname = workflow
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_filelog]
+class = logging.handlers.TimedRotatingFileHandler
+args = ('%(here)s/workflow.log','midnight',1,3)
+level = INFO
+formatter = generic
+# When using the TimedRotatingFileHandler, we probably should set up the rollover time
+# and other aspects of the log to strike the balance between disk usage and log history
+
+[formatter_generic]
+format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
diff --git a/services/capability/production.ini b/services/capability/production.ini
new file mode 100644
index 0000000000000000000000000000000000000000..aacbb031a1b079c39f5091f9f06ff51770ba64dc
--- /dev/null
+++ b/services/capability/production.ini
@@ -0,0 +1,22 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
+[app:main]
+use = egg:ssa-capability
+
+session.cookie_expires = true
+session.auto = true
+
+pyramid.reload_templates = false
+pyramid.debug_authorization = false
+pyramid.debug_notfound = false
+pyramid.debug_routematch = false
+pyramid.default_locale_name = en
+pyramid.includes = pyramid_tm
+
+
+[server:main]
+use = egg:waitress#main
+listen = 0.0.0.0:6543
diff --git a/services/capability/setup.py b/services/capability/setup.py
index ed5bf57ae0fff973c049846324aed4ecef631aeb..9576cb2ecc84ebe90e9a5675e5c46de7a67e1aaf 100644
--- a/services/capability/setup.py
+++ b/services/capability/setup.py
@@ -1,35 +1,104 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
+"""A setuptools based setup module.
 
-from pathlib import Path
-from setuptools import setup
+See:
+https://packaging.python.org/en/latest/distributing.html
+https://github.com/pypa/sampleproject
+"""
+# To use a consistent encoding
+from codecs import open
+from os import path
+
+# Always prefer setuptools over distutils
+from setuptools import setup, find_packages
+
+# For matching the version string.
+import re
+
+this_module = 'capability'
+here = path.abspath(path.dirname(__file__))
+
+# Get the long description from the README file
+with open(path.join(here, 'README.md'), encoding='utf-8') as f:
+    long_description = f.read()
+
+
+def read(*parts):
+    with open(path.join(here, *parts), 'r') as fp:
+        return fp.read()
+
+
+def find_version(*file_paths):
+    version_file = read(*file_paths)
+    version_match = re.search(r"^___version___ = ['\"]([^'\"]*)['\"]",
+                              version_file, re.M)
+    if version_match:
+        return version_match.group(1)
+    raise RuntimeError("Unable to find version string.")
 
-VERSION = open('src/capability/_version.py').readlines()[-1].split()[-1].strip("\"'")
-README = Path('README.md').read_text()
 
 requires = [
+    'pycapo',
+    'pyramid',
+    'pyramid_beaker',
+    'pyramid_debugtoolbar',
+    'pyramid_tm',
+    'requests',
+    'ssa-schema',
+    'sqlalchemy',
+    'waitress',
     'ssa-workspaces',
+    'zope.sqlalchemy'
 ]
-# tests_require = []
 
 setup(
-    name='ssa-' + Path().absolute().name,
-    version=VERSION,
-    description='The Workspaces capability service',
-    long_description=README,
-    author='NRAO SSA Team',
-    author_email='dms-ssa@nrao.edu',
-    url='TBD',
-    license="GPL",
-    install_requires=requires,
-    # tests_require=tests_require,
-    keywords=[],
-    packages=['capability'],
-    package_dir={'':'src'},
+    name='ssa-' + this_module,
+
+    # Versions should comply with PEP440.  For a discussion on single-sourcing
+    # the version across setup.py and the project code, see
+    # https://packaging.python.org/en/latest/single_source_version.html
+    version=find_version('src/' + this_module, '_version.py'),
+
+    description='Capability: the Workspaces Capability Service',
+    long_description=long_description,
+
+    # Author details
+    author='Science Support and Archive',
+    author_email='ssa-announcements@nrao.edu',
+
+    # Choose your license
+    license='GPL',
+
+    # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
     classifiers=[
-        'Programming Language :: Python :: 3.8'
+        # How mature is this project? Common values are
+        #   3 - Alpha
+        #   4 - Beta
+        #   5 - Production/Stable
+        'Development Status :: 4 - Beta',
+
+        # Indicate who your project is intended for
+        'Intended Audience :: Developers',
+        'Topic :: Software Development :: Build Tools',
+
+        # Pick your license as you wish (should match "license" above)
+        'License :: OSI Approved :: GPL License',
+
+        # Specify the Python versions you support here. In particular, ensure
+        # that you indicate whether you support Python 2, Python 3 or both.
+        'Programming Language :: Python :: 3.6',
     ],
+
+    install_requires=requires,
+    extras_require={
+        'dev': [
+            'pyramid_debugtoolbar',
+        ],
+    },
+    package_dir={'': 'src'},
+    packages=find_packages(),
     entry_points={
-        'console_scripts': ['cap_launcher = capability.capability_launcher:main']
+        'paste.app_factory': [
+            'main = capability.server:main'
+        ],
     },
 )
diff --git a/services/capability/src/capability/server.py b/services/capability/src/capability/server.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6cc204facb2df0642ec7d7a1578e6c4ead956cf
--- /dev/null
+++ b/services/capability/src/capability/server.py
@@ -0,0 +1,68 @@
+import zope.sqlalchemy
+from pyramid.config import Configurator
+from pyramid.renderers import JSONP
+from pyramid.view import view_config, view_defaults
+from pyramid_beaker import session_factory_from_settings
+from workspaces.services import WorkflowInfo, WorkflowService, get_session_factory, get_engine, CapabilityInfo, \
+    CapabilityService
+
+
+# ---------------------------------------------------------
+#
+#    F R A M E W O R K    S E T U P
+#
+# ---------------------------------------------------------
+
+
+def get_tm_session(session_factory, transaction_manager):
+    """
+    Enable Zope's transaction manager on our session
+    :param session_factory:
+    :param transaction_manager:
+    :return:
+    """
+    dbsession = session_factory()
+    zope.sqlalchemy.register(dbsession, transaction_manager=transaction_manager)
+    return dbsession
+
+
+# ---------------------------------------------------------
+#
+#    M A I N    E N T R Y P O I N T
+#
+# ---------------------------------------------------------
+
+
+def main(global_config, **settings):
+    with Configurator(settings=settings) as config:
+        session_factory = session_factory_from_settings(settings)
+        config.set_session_factory(session_factory)
+        config.add_renderer('jsonp', JSONP(param_name='callback'))
+
+        settings['tm.manager_hook'] = 'pyramid_tm.explicit_manager'
+
+        # use pyramid_tm to hook the transaction lifecycle to the request
+        config.include('pyramid_tm')
+
+        # use pyramid_retry to retry a request when transient exceptions occur
+        config.include('pyramid_retry')
+
+        session_factory = get_session_factory(get_engine())
+        config.registry['dbsession_factory'] = session_factory
+
+        # make workflow_info available for use in Pyramid
+        config.add_request_method(
+            # r.tm is the transaction manager used by pyramid_tm
+            lambda request: CapabilityInfo(get_tm_session(session_factory, request.tm)),
+            'info',
+            reify=True
+        )
+        # make workflow_service available for use in Pyramid
+        config.add_request_method(lambda r: CapabilityService(r.info), 'capabilities', reify=True)
+
+        # add some routes
+        # config.add_route('workflows', '/workflows')
+
+        config.include('pyramid_beaker')
+        config.scan('.')
+        return config.make_wsgi_app()
diff --git a/services/workflow/development.ini b/services/workflow/development.ini
index 005980125efd6aa0ffd4627d40140cf53e7c14cf..9f23a0f81745a0d687383178850abcca3e8d14ab 100644
--- a/services/workflow/development.ini
+++ b/services/workflow/development.ini
@@ -1,5 +1,5 @@
 [app:main]
-use = egg:workflow
+use = egg:ssa-workflow
 pyramid.includes =
     pyramid_debugtoolbar
     pyramid_tm
diff --git a/services/workflow/production.ini b/services/workflow/production.ini
index d1430a9b8c25dff1eeacadaebf6bd3869bb15e5d..1dc1e17b2fdb2a2b53c9614ac896fb588d7bd8b2 100644
--- a/services/workflow/production.ini
+++ b/services/workflow/production.ini
@@ -4,7 +4,7 @@
 ###
 
 [app:main]
-use = egg:workflow
+use = egg:ssa-workflow
 
 session.cookie_expires = true
 session.auto = true
diff --git a/services/workflow/setup.py b/services/workflow/setup.py
index 2d6903af4d7ae9b574a764a9da31193060abc997..90e6c715e908309fb9c5eb4593bba69684d44621 100644
--- a/services/workflow/setup.py
+++ b/services/workflow/setup.py
@@ -62,8 +62,8 @@ setup(
     long_description=long_description,
 
     # Author details
-    author='Daniel Lyons',
-    author_email='dlyons@nrao.edu',
+    author='Science Support and Archive',
+    author_email='ssa-announcements@nrao.edu',
 
     # Choose your license
     license='GPL',
diff --git a/services/workflow/workflow.wsgi b/services/workflow/workflow.wsgi
index d0452ee043312de9e5f3d2a1a85b1b5dced7392d..480a8b8b37ead924c75df26f74ef11832bba44b3 100644
--- a/services/workflow/workflow.wsgi
+++ b/services/workflow/workflow.wsgi
@@ -5,11 +5,10 @@ import os
 import socket
 
 fqdn = socket.getfqdn()
-if "mcilroy" in fqdn:
+if "shipman" in fqdn:
     os.environ['CAPO_PROFILE'] = 'dsoc-prod'
 elif "wirth" in fqdn:
-    os.environ['CAPO_PROFILE'] = 'nmtest'
-    #os.environ['CAPO_PROFILE'] = 'dsoc-dev'
+    os.environ['CAPO_PROFILE'] = 'dsoc-dev'
 elif "hamilton" in fqdn:
     os.environ['CAPO_PROFILE'] = 'dsoc-test'
 else: