diff --git a/calparrot/__main__.py b/calparrot/__main__.py
index 3669bce9391c7d7dcdba7c59811ad5f2dcce7b33..0a2c681cf46d4c081d1d73d5f514c7afd6aa03c5 100644
--- a/calparrot/__main__.py
+++ b/calparrot/__main__.py
@@ -13,11 +13,11 @@ try:
 except ImportError:
     restful_config = {}
 
-def main():
+async def amain():
     ap = argparse.ArgumentParser()
     ap.add_argument('--debug', action='store_true')
     ap.add_argument('--db', default='calparrot.sqlite')
-    ap.add_argument('--port-file', help="File to write port number into")
+    ap.add_argument('command', nargs='+')
     args = ap.parse_args()
     logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)
     # Suppress tornado's access logging when things are working correctly:
@@ -40,15 +40,17 @@ def main():
 
     app = ProxyApp(base_url, oauth_info, args.db)
     log.info("CalParrot will serve constant queries on http://127.0.0.1:%d", app.port)
-    if args.port_file:
-        with open(args.port_file, 'w') as f:
-            f.write(str(app.port))
 
-    if os.fork() == 0:
-        asyncio.run(app.serve())
-    else:
-        # Parent process - exit now
-        return 0
+    try:
+        env = os.environ.copy()
+        # Tell the child process (running the notebook) to talk to our proxy:
+        env['CAL_CAL_TOOLS_CALCAT'] = "{base-api-url='http://127.0.0.1:{app.port}/api', use-oauth2=false}"
+        proc = await asyncio.create_subprocess_exec(*args.command, env=env)
+        retcode = await proc.wait()
+    finally:
+        await app.shutdown()
+
+    return retcode
 
 if __name__ == '__main__':
-    sys.exit(main())
+    sys.exit(asyncio.run(amain()))
diff --git a/calparrot/proxy.py b/calparrot/proxy.py
index 663af2fdc47dcd7070af9cd4feb3bed8444c7fe8..6c63951318ac05af467b5e6d7b652829965b37f7 100644
--- a/calparrot/proxy.py
+++ b/calparrot/proxy.py
@@ -181,17 +181,7 @@ class ProxyHandler(RequestHandler):
         await self.finish(response.body)
 
 
-class ShutdownHandler(RequestHandler):
-    def initialize(self, proxy_app):
-        self.proxy_app = proxy_app
-
-    def post(self):
-        self.proxy_app.shutdown()
-
-
 class ProxyApp:
-    quit_event: asyncio.Event
-
     def __init__(self, base_url, oauth_info=None, db_path='calparrot.sqlite'):
         self.response_store = ResponsesDB(db_path)
         base_url = base_url.rstrip('/')  # e.g. https://in.xfel.eu/calibration
@@ -208,7 +198,6 @@ class ProxyApp:
             self.client = AsyncHTTPClient()
 
         self.tornado_app = Application([
-            ('/.calparrot/stop', ShutdownHandler, {'proxy_app': self}),
             ('(/.*)', ProxyHandler, {
                 'base_url': base_url,
                 'upstream_client': self.client,
@@ -218,25 +207,18 @@ class ProxyApp:
 
         # Bind a random port to listen on
         self.sockets = bind_sockets(0, '127.0.0.1')
+        self.server = HTTPServer(self.tornado_app)
+        # add_sockets hooks up the server to the event loop
+        self.server.add_sockets(self.sockets)
 
     @property
     def port(self):
         return self.sockets[0].getsockname()[1]
 
-    async def serve(self):
-        """Serve requests until asked to quit"""
-        self.quit_event = asyncio.Event()
-        server = HTTPServer(self.tornado_app)
-        # add_sockets hooks up the server to the event loop
-        server.add_sockets(self.sockets)
-
-        await self.quit_event.wait()
-
+    async def shutdown(self):
+        """Cleanly shut down the server"""
         log.info("CalParrot shutting down")
-        server.stop()  # Stop accepting new connections
-        await server.close_all_connections()  # Close existing connections
+        self.server.stop()  # Stop accepting new connections
+        await self.server.close_all_connections()  # Close existing connections
         self.response_store.close()
         log.info("Query stats: %s", self.response_store.stats)
-
-    def shutdown(self):
-        self.quit_event.set()