diff --git a/test/agent/Makefile.am b/test/agent/Makefile.am
index c2e7672ce2ec9aa7b7d1e1d686f7c6fe82a83e41..bd92e88da0d799d209e07734c359f03b6b653000 100644
--- a/test/agent/Makefile.am
+++ b/test/agent/Makefile.am
@@ -16,6 +16,7 @@ lib_LTLIBRARIES = libguile-jami.la
 libguile_jami_la_SOURCES =          \
 	src/main.cpp                \
 	src/utils.h                 \
+	src/bindings/jami.h         \
 	src/bindings/bindings.cpp   \
 	src/bindings/bindings.h     \
 	src/bindings/account.h      \
diff --git a/test/agent/jami.scm b/test/agent/jami.scm
index 9fbb34b6ea532a672ea88ade81718152896af854..d34822144f1acf1401cf19c8001fe839f8709cd1 100644
--- a/test/agent/jami.scm
+++ b/test/agent/jami.scm
@@ -1,12 +1,37 @@
 (define-module (jami)
-  #:use-module (system foreign-library))
+  #:use-module (system foreign-library)
+  #:export (init
+            initialized
+            fini
+            logging
+            platform
+            start
+            version
+            JAMI_FLAG_DEBUG
+            JAMI_FLAG_CONSOLE_LOG
+            JAMI_FLAG_AUTOANSWER
+            JAMI_FLAG_IOS_EXTENSION)
+  #:export-syntax (with-jami))
 
-;;; Call DRing::init so that every other bindings work.
-;;;
-;;; Since Dring::fini is not safe in atexit callback, we also register a exit
-;;; hook for finalizing Jami with DRing::fini.
 (let* ((libjami (load-foreign-library "libguile-jami"))
-       (init (foreign-library-function libjami "init"))
-       (fini (foreign-library-function libjami "fini")))
-  (init)
-  (add-hook! exit-hook fini))
+       (bootstrap (foreign-library-function libjami "bootstrap")))
+  (bootstrap))
+
+(define-syntax with-jami
+  (syntax-rules ()
+    ((_ config-file (init-flags ...) thunk)
+     (dynamic-wind
+       (lambda ()
+         (init (logior init-flags ...))
+         (start config-file))
+       thunk
+       fini))
+    ((_ (init-flags ...) thunk)
+     (with-jami "" (init-flags ...) thunk))
+    ((_ thunk)
+     (with-jami "" (0) thunk))))
+
+(define JAMI_FLAG_DEBUG (ash 1 0))
+(define JAMI_FLAG_CONSOLE_LOG (ash 1 1))
+(define JAMI_FLAG_AUTOANSWER (ash 1 2))
+(define JAMI_FLAG_IOS_EXTENSION (ash 1 3))
diff --git a/test/agent/scenarios/bulk-calls/scenario.scm b/test/agent/scenarios/bulk-calls/scenario.scm
index 8bd62e29e0c27e2d185edc474a7ac1f0d798db8d..e0e24572c86426023d45662d91a561f0063aad1e 100644
--- a/test/agent/scenarios/bulk-calls/scenario.scm
+++ b/test/agent/scenarios/bulk-calls/scenario.scm
@@ -26,6 +26,7 @@
  (ice-9 match)
  (ice-9 threads)
  ((agent) #:prefix agent:)
+ ((jami) #:select (with-jami JAMI_FLAG_DEBUG))
  ((jami account) #:prefix account:)
  ((jami call) #:prefix call:)
  ((jami signal) #:prefix jami:)
@@ -119,14 +120,19 @@
 
 (define (main args)
 
-  (match (cdr args)
-    (("alice" bob-id) (alice bob-id))
-    (("bob") (bob))
-    (_
-     (jami:error "Invalid arguments: ~a" args)
-     (jami:error "Usage: ~a alice|bob (ARG)\n" (car args))
-     (exit EXIT_FAILURE)))
-
-  (jami:info "bye bye")
+  (with-jami (JAMI_FLAG_DEBUG)
+             (match (cdr args)
+               (("alice" bob-id)
+                (lambda ()
+                  (alice bob-id)
+                  (jami:info "bye bye")))
+               (("bob")
+                (lambda ()
+                  (bob)
+                  (jami:info "bye bye")))
+               (_
+                (jami:error "Invalid arguments: ~a" args)
+                (jami:error "Usage: ~a alice|bob (ARG)\n" (car args))
+                (exit EXIT_FAILURE))))
 
   (exit EXIT_SUCCESS))
diff --git a/test/agent/src/bindings/bindings.cpp b/test/agent/src/bindings/bindings.cpp
index 6ba1e926fae682b5272047d4074f87e941fda1d6..becb4addbc1c1b7cffc35e296042238d4cf0a520 100644
--- a/test/agent/src/bindings/bindings.cpp
+++ b/test/agent/src/bindings/bindings.cpp
@@ -25,6 +25,7 @@
 #include "bindings/account.h"
 #include "bindings/call.h"
 #include "bindings/conversation.h"
+#include "bindings/jami.h"
 #include "bindings/logger.h"
 #include "bindings/signal.h"
 
@@ -36,6 +37,7 @@ install_scheme_primitives()
         scm_c_define_module(name, init, NULL);
     };
 
+    load_module("jami", install_jami_primitives);
     load_module("jami account", install_account_primitives);
     load_module("jami call", install_call_primitives);
     load_module("jami conversation", install_conversation_primitives);
diff --git a/test/agent/src/bindings/jami.h b/test/agent/src/bindings/jami.h
new file mode 100644
index 0000000000000000000000000000000000000000..89e28f1d327c464308079238fc42b23594f36bc9
--- /dev/null
+++ b/test/agent/src/bindings/jami.h
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (C) 2022 Savoir-faire Linux Inc.
+ *
+ *  Author: Olivier Dion <olivier.dion@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#pragma once
+
+#include "jami/jami.h"
+
+#include "utils.h"
+
+static SCM init_binding(SCM flags)
+{
+        LOG_BINDING();
+
+        unsigned int flags_cast = from_guile(flags);
+
+        return to_guile(DRing::init(static_cast<DRing::InitFlag>(flags_cast)));
+}
+
+static SCM fini_binding()
+{
+        LOG_BINDING();
+
+        DRing::fini();
+
+        return SCM_UNDEFINED;
+}
+
+static SCM initialized_binding()
+{
+        LOG_BINDING();
+
+        return to_guile(DRing::initialized());
+}
+
+static SCM logging_binding(SCM whom, SCM action)
+{
+        LOG_BINDING();
+
+        DRing::logging(from_guile(whom), from_guile(action));
+
+        return SCM_UNDEFINED;
+}
+
+static SCM platform_binding()
+{
+        LOG_BINDING();
+
+        return to_guile(DRing::platform());
+}
+
+static SCM start_binding(SCM config_file)
+{
+        LOG_BINDING();
+
+        return to_guile(DRing::start(from_guile(config_file)));
+}
+
+static SCM version_binding()
+{
+        LOG_BINDING();
+
+        return to_guile(DRing::version());
+}
+
+static void
+install_jami_primitives(void *)
+{
+    define_primitive("init", 1, 0, 0, (void*) init_binding);
+    define_primitive("initialized", 0, 0, 0, (void*) initialized_binding);
+    define_primitive("fini", 0, 0, 0, (void*) fini_binding);
+    define_primitive("logging", 2, 0, 0, (void*) logging_binding);
+    define_primitive("platform", 0, 0, 0, (void*) platform_binding);
+    define_primitive("start", 1, 0, 0, (void*) start_binding);
+    define_primitive("version", 0, 0, 0, (void*) version_binding);
+}
diff --git a/test/agent/src/main.cpp b/test/agent/src/main.cpp
index f4e47102acbd3c7393b0a87434f1c5fdf68399fe..bfa74e0f58b22e190af49ce17d3b62ca49a4a76b 100644
--- a/test/agent/src/main.cpp
+++ b/test/agent/src/main.cpp
@@ -25,24 +25,11 @@
 #include <libguile.h>
 
 extern "C" {
-DRING_PUBLIC void init();
-DRING_PUBLIC void fini();
+DRING_PUBLIC void bootstrap();
 }
 
 void
-init()
+bootstrap()
 {
-    DRing::init(DRing::InitFlag(DRing::DRING_FLAG_DEBUG));
-
-    if (not DRing::start("")) {
-        scm_misc_error("Dring::start", NULL, 0);
-    }
-
     install_scheme_primitives();
 }
-
-void
-fini()
-{
-    DRing::fini();
-}