diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000000000000000000000000000000000..19ff63cb42294f1ce5aa49d78a74d82e6141927b
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,149 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveMacros: false
+AlignConsecutiveAssignments: false
+AlignConsecutiveBitFields: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   Align
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  AfterExternBlock: false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 2
+ContinuationIndentWidth: 2
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeBlocks:   Preserve
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+    SortPriority:    0
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+    SortPriority:    0
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentCaseLabels: false
+IndentCaseBlocks: false
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentExternBlock: AfterExternBlock
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+InsertTrailingCommas: None
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments:  true
+SortIncludes:    false
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpaceBeforeSquareBrackets: false
+Standard:        Latest
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth:        8
+UseCRLF:         false
+UseTab:          Never
+WhitespaceSensitiveMacros:
+  - STRINGIZE
+  - PP_STRINGIZE
+  - BOOST_PP_STRINGIZE
+...
+
diff --git a/.docker/Dockerfile b/.docker/Dockerfile
index 20b74967ffd7f163a4b3d5598540c134c2b586cd..712d497293d0bc93ac31cc42419e3af5e9df092a 100644
--- a/.docker/Dockerfile
+++ b/.docker/Dockerfile
@@ -13,6 +13,13 @@ RUN wget --output-document generate_doc_unreleased.zip \
     https://github.com/gnu-octave/generate_doc/archive/refs/heads/main.zip
 RUN octave --eval "pkg install generate_doc_unreleased.zip"
 
+# Unit test framework (MOxUnit)
+RUN wget --output-document MOxUnit-master.zip \
+    https://github.com/MOxUnit/MOxUnit/archive/master.zip
+RUN unzip MOxUnit-master.zip
+WORKDIR /MOCov-master/
+RUN make install
+
 COPY doc/requirements.txt doc-requirements.txt
 RUN pip3 install -r doc-requirements.txt
 
diff --git a/.gitignore b/.gitignore
index eed30a636ab5153b90b95deee423c7aebe6a0a06..c9fc1e4296d3fbcb8de8a61e73a1a14657a2a833 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 # General
 build/
+inst/
 *.tar.gz
 *.zip
 doc/_build_octave/
@@ -83,6 +84,7 @@ dkms.conf
 [._]s[a-rt-v][a-z]
 [._]ss[a-gi-z]
 [._]sw[a-p]
+.vimrc
 
 ## Session
 Session.vim
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b00540c076d081359e383b3b95924d16420edd7c..db5b76e9c8df16443c660d370c74c58c7b991160 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -54,7 +54,7 @@ code_style:
   stage: test
   script:
     - mh_style -v
-    - mh_style --octave ./
+    - mh_style --octave ./src ./doc
   allow_failure: true
 
 # Unit tests
diff --git a/pkg/CITATION b/CITATION
similarity index 100%
rename from pkg/CITATION
rename to CITATION
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..88e537875424b4f6d990984e95a89269035190fe
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,60 @@
+#
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+# Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+
+cmake_minimum_required(VERSION 3.15)
+
+project(OctaveCaosDB
+    DESCRIPTION "GNU/Octave wrapper for libcaosdb, the C++ client library of the CaosDB project."
+    LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+
+# dependency management with conan
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup()
+
+# fix grpc - remove unsecure (no-op ssl implementations)
+string(REGEX REPLACE ";grpc\\+?\\+?_unsecure" "" CONAN_LIBS_GRPC
+    "${CONAN_LIBS_GRPC}")
+string(REGEX REPLACE ";grpc\\+?\\+?_unsecure" "" CONAN_PKG_LIBS_GRPC
+    "${CONAN_PKG_LIBS_GRPC}")
+string(REGEX REPLACE ";grpc\\+?\\+?_unsecure" "" CONAN_LIBS
+    "${CONAN_LIBS}")
+string(REGEX REPLACE ";grpc\\+?\\+?_unsecure" "" CONAN_PKG_LIBS
+    "${CONAN_PKG_LIBS}")
+
+add_subdirectory(src)
+
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/inst)
+string(REGEX REPLACE ";" ";-I" MKOCTFILE_INCLUDES "-I${CONAN_INCLUDE_DIRS}")
+string(REGEX REPLACE ";" ";-L" MKOCTFILE_LIB_DIRS "-L${CONAN_LIB_DIRS}")
+string(REGEX REPLACE ";" ";-l" MKOCTFILE_LIBS "-l${CONAN_LIBS}")
+string(REGEX REPLACE ";" ":" MKOCTFILE_RPATH "${CONAN_LIB_DIRS}")
+set(MKOCTFILE_OPTIONS "-o" "inst/caosdb.mex" "-Wl,-rpath,${MKOCTFILE_RPATH}" "--mex" "-std=gnu++17"
+    "-L/usr/local/lib" ${MKOCTFILE_INCLUDES} ${MKOCTFILE_LIB_DIRS} ${MKOCTFILE_LIBS})
+add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/inst/caosdb.mex
+    COMMAND mkoctfile
+    ARGS ${MKOCTFILE_OPTIONS} ${OCTAVE_CAOSDB_SRC}
+    DEPENDS ${OCTAVE_CAOSDB_SRC}
+    )
+add_custom_target(caosdb.mex ALL
+    SOURCES ${CMAKE_BINARY_DIR}/inst/caosdb.mex)
diff --git a/pkg/COPYING b/COPYING
similarity index 100%
rename from pkg/COPYING
rename to COPYING
diff --git a/CHANGELOG.md b/ChangeLog
similarity index 100%
rename from CHANGELOG.md
rename to ChangeLog
diff --git a/pkg/DESCRIPTION b/DESCRIPTION
similarity index 100%
rename from pkg/DESCRIPTION
rename to DESCRIPTION
diff --git a/Makefile b/Makefile
index 0274fb935dcaa7b820944b52eb4b0347a541891c..c76ce93b1ae3bd435f1fa7b86645cc46675434a4 100644
--- a/Makefile
+++ b/Makefile
@@ -29,25 +29,28 @@ help:
 	@echo "    test - run unit tests."
 	@echo "    doc - create the documentation."
 
-dist:
-
-
 .PHONY: doc
 doc:
 	cd doc && $(MAKE) html
 
 .PHONY: style
 style:
-	mh_style --fix --octave src pkg doc
+	mh_style --fix --octave src doc
 
 .PHONY: test
 test:
-	cd src && octave Run_Test.m
+	cd test && octave Run_Test.m
 
 .PHONY: pkg
-pkg: caosdb.tar.gz
+pkg: dist/caosdb.tar.gz
 
 
 .PHONY: caosdb.tar.gz
-caosdb.tar.gz:
-	tar -czf caosdb.tar.gz --exclude-from=.gitignore pkg
+dist/caosdb.tar.gz: dist/
+	tar -czf dist/caosdb.tar.gz \
+	--exclude=.git* --exclude=env* --exclude=doc/_build_octave* --exclude=build* --exclude=.docker* --exclude=dist* --exclude-ignore-recursive=.gitignore \
+	--transform 's,^\.,caosdb,' .
+
+.PHONY: dist/
+dist/:
+	mkdir -p dist
diff --git a/conanfile.txt b/conanfile.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e89a593b5f6388ac539975c6ae0ed808a900ecc3
--- /dev/null
+++ b/conanfile.txt
@@ -0,0 +1,5 @@
+[requires]
+caosdb/0.0.5
+
+[generators]
+cmake
diff --git a/dev-requirements.txt b/dev-requirements.txt
index f12580b74c2c03734f98d9eac4deadcb6d6f0225..fdb3579450258709d22d7df462dee7cfe698d7b7 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,2 +1,41 @@
+alabaster==0.7.12
+Babel==2.9.1
+bottle==0.12.19
+certifi==2021.5.30
+charset-normalizer==2.0.1
+colorama==0.4.4
+conan==1.38.0
+deprecation==2.0.7
+distro==1.5.0
+docutils==0.16
+fasteners==0.16.3
+future==0.18.2
+idna==3.2
+imagesize==1.2.0
+Jinja2==2.11.3
+MarkupSafe==2.0.1
 miss-hit==0.9.23
 miss-hit-core==0.9.23
+node-semver==0.6.1
+packaging==21.0
+patch-ng==1.17.4
+pluginbase==1.0.1
+Pygments==2.9.0
+PyJWT==1.7.1
+pyparsing==2.4.7
+python-dateutil==2.8.2
+pytz==2021.1
+PyYAML==5.4.1
+requests==2.26.0
+six==1.15.0
+snowballstemmer==2.1.0
+Sphinx==4.1.0
+sphinx-rtd-theme==0.5.2
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==2.0.0
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.5
+tqdm==4.61.2
+urllib3==1.25.11
diff --git a/doc/Generate_Octave_Doc.m b/doc/Generate_Octave_Doc.m
index 8cdf33411d9596b9dbf0e0de919237d855ae28d2..f8093dc03f0fb2af550b8445cbb7c3d27fb76959 100644
--- a/doc/Generate_Octave_Doc.m
+++ b/doc/Generate_Octave_Doc.m
@@ -46,6 +46,6 @@ pkg load generate_doc;
 of_options = get_html_options("octave-forge");
 setfield(of_options, '__header__', header);
 % (Re)loading caosdb package
-pkg install ../pkg;
+pkg install ..;
 pkg load caosdb;
 generate_package_html('caosdb', '_build_octave/', of_options);
diff --git a/doc/api/function/some_function.rst b/doc/api/function/caosdb.rst
similarity index 89%
rename from doc/api/function/some_function.rst
rename to doc/api/function/caosdb.rst
index 9ab4bcca865b0a6d8f490c0ee75e46866fc9bc3a..d3bbbe134126b86438b43192bc94c8695894fd81 100644
--- a/doc/api/function/some_function.rst
+++ b/doc/api/function/caosdb.rst
@@ -19,13 +19,13 @@
     # along with this program. If not, see <https://www.gnu.org/licenses/>.
     #
 
-.. _some_function:
+.. _caosdb_main:
 
-some_function
-=============
+caosdb
+======
 
 .. toctree::
     :hidden:
 
 .. raw:: html
-   :file: ../../_build_octave/caosdb/function/some_function.html
+   :file: ../../_build_octave/caosdb/function/caosdb.html
diff --git a/pkg/ChangeLog b/pkg/ChangeLog
deleted file mode 120000
index 04c99a55caae5d51f17666f554c2c8cea0aadfc0..0000000000000000000000000000000000000000
--- a/pkg/ChangeLog
+++ /dev/null
@@ -1 +0,0 @@
-../CHANGELOG.md
\ No newline at end of file
diff --git a/pkg/LICENSE.md b/pkg/LICENSE.md
deleted file mode 120000
index f0608a63ae16053f55e32ab4abf40e7a61f2dccb..0000000000000000000000000000000000000000
--- a/pkg/LICENSE.md
+++ /dev/null
@@ -1 +0,0 @@
-../../LICENSE.md
\ No newline at end of file
diff --git a/pkg/inst/some_function.m b/pkg/inst/some_function.m
deleted file mode 100644
index 682f582cfe09b150a9e7ebd110e7dbede0c4a197..0000000000000000000000000000000000000000
--- a/pkg/inst/some_function.m
+++ /dev/null
@@ -1,49 +0,0 @@
-% Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
-% Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
-%
-% This file is a part of the CaosDB Project.
-%
-% This program is free software: you can redistribute it and/or modify
-% it under the terms of the GNU Affero 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 Affero General Public License for more details.
-%
-% You should have received a copy of the GNU Affero General Public License
-% along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-% -*- texinfo -*-
-% @deftypefn {Function File} {@var{result} =} some_function (@var{arg_a}, @var{arg_b})
-% This is some function.
-%
-% For example, this function could be called like this:
-% @example
-% some_function (1, 2);
-% @end example
-%
-% @seealso{some_function}
-% @end deftypefn
-
-function result = some_function(arg_a, arg_b)
-  if arg_a >= arg_b
-    error("arg_a must be smaller than arg_b!");
-  end
-  x = arg_a:0.1:arg_b;
-  result = sin(x);
-end
-
-%%%%%%%%%%
-% See https://wiki.octave.org/Tests and
-% https://octave.org/doc/interpreter/Test-Functions.html for unit tests.
-
-%!assert (some_function(1, 2))
-%!assert (some_function(-0.1, 0.1)(2) == 0)
-%!error <arg_a must be smaller than arg_b!> (some_function(3, 2))
-
-%!demo
-%! ## Try out some_function(arg_a, arg_b):
-%! some_function(-1,1)
diff --git a/pkg/src/configure b/pkg/src/configure
deleted file mode 100755
index 0a272ab170de3241d32886ad662423cb54affc80..0000000000000000000000000000000000000000
--- a/pkg/src/configure
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-echo "Nothing is implemented yet."
-
-# See https://octave.org/doc/interpreter/Creating-Packages.html
diff --git a/src/.miss_hit b/src/.miss_hit
deleted file mode 100644
index f15ccfe29ff4a2e193fb4ae51ca5a7bd1cc3a88d..0000000000000000000000000000000000000000
--- a/src/.miss_hit
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- mode:conf; -*-
-# See https://florianschanda.github.io/miss_hit/style_checker.html
-
-line_length: 100
-regex_function_name: "[a-z]+(_[a-z]+)*"
-suppress_rule: "whitespace_comments"
-tab_width: 2
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..58fd2e981f71f986f4138b94e26fa7fa93670edb
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,26 @@
+#
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+# Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+
+set(OCTAVE_CAOSDB_SRC
+    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb.cpp
+    )
+
+# pass variable to parent scope
+set(OCTAVE_CAOSDB_SRC ${OCTAVE_CAOSDB_SRC}  PARENT_SCOPE)
diff --git a/src/Caosdb.m b/src/Caosdb.m
new file mode 100644
index 0000000000000000000000000000000000000000..7345ca240266d0d738377d564a35dda6c4ce6434
--- /dev/null
+++ b/src/Caosdb.m
@@ -0,0 +1,42 @@
+% (C) Copyright 2021 IndiScale GmbH <info@indiscale.com>
+% (C) Copyright 2021 Timm FItschen <t.fitschen@indiscale.com>
+%
+% This file is a part of the CaosDB Project.
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU Affero 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 Affero General Public License for more details.
+%
+% You should have received a copy of the GNU Affero General Public License
+% along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+% -*- texinfo -*-
+% @deftypefn {Loadable Function} {} caosdb ([@var{OPTIONS}])
+% This is the main function of the CaosDB client for Octave.
+%
+% Print usage help and return:
+% @example
+% caosdb --help;
+% @end example
+%
+% Print the version and return:
+% @example
+% caosdb --version;
+% @end example
+%
+% Test the default connection, print the server's version and return.
+% @example
+% caosdb --test-connection;
+% @end example
+%
+% @end deftypefn
+
+%!demo
+%! ## Print Help:
+%! caosdb --help;
diff --git a/src/FILES.in b/src/FILES.in
new file mode 100644
index 0000000000000000000000000000000000000000..92701f0929431293984c7c86f21cf8607f0829c5
--- /dev/null
+++ b/src/FILES.in
@@ -0,0 +1,2 @@
+${BUILD_DIR}/inst/caosdb.mex
+caosdb.m
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..274c59a9ce161085fadd26e073ab22988dd5f6c6
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,5 @@
+BUILD_DIR ?= ../build
+
+.PHONY: compile
+compile:
+	$(MAKE) --directory=$(BUILD_DIR) --file=$(BUILD_DIR)/Makefile
diff --git a/src/caosdb.cpp b/src/caosdb.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b9845caf6daf6c5d9439311240de199bb42cd60
--- /dev/null
+++ b/src/caosdb.cpp
@@ -0,0 +1,58 @@
+#include <string>
+#include "mex.h"
+#include "caosdb/connection.h"  // for Connection, ConnectionManager
+#include "caosdb/constants.h"   // for LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_V...
+
+const char* print_version();
+void print_usage();
+void test_connection();
+
+void print_usage() {
+  print_version();
+  mexPrintf("\nUsage: caosdb [OPTIONS]\n\n");
+  mexPrintf("Options:\n");
+  mexPrintf("    --help              Print this help and return.\n");
+  mexPrintf("    --version           Print the version of OcataveCaosDB and libcaosdb and return.\n");
+  mexPrintf("    --test-connection   Test the default connection and return.\n");
+};
+
+const std::string FULL_VERSION = std::string("v0.1 (libcaosdb v"
+    + std::to_string(caosdb::LIBCAOSDB_VERSION_MAJOR) +
+    "." + std::to_string(caosdb::LIBCAOSDB_VERSION_MINOR) +
+    "." + std::to_string(caosdb::LIBCAOSDB_VERSION_PATCH) +
+    ")").c_str();
+
+const char* print_version() {
+  mexPrintf("Octave caosdb client %s\n\n", FULL_VERSION.c_str());
+  mexPrintf("We don't miss the H of caos.\n");
+  return FULL_VERSION.c_str();
+};
+
+void test_connection() {
+  const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection();
+  const auto &version_info = connection->GetVersionInfo();
+  mexPrintf("Server Version: v%d.%d.%d-%s-%s\n",
+      version_info->GetMajor(),
+      version_info->GetMinor(),
+      version_info->GetPatch(),
+      version_info->GetPreRelease().c_str(),
+      version_info->GetBuild().c_str());
+}
+
+void mexFunction (int nlhs, mxArray *plhs[],
+                  int nrhs, const mxArray *prhs[]) {
+
+  if (nrhs == 1) {
+    auto const *first_arg = mxGetChars(prhs[0]);
+    if(strcmp(first_arg,"--version") == 0) {
+      const auto *version = print_version();
+      plhs[0] = mxCreateString(version);
+      return;
+    } else if (strcmp(first_arg, "--test-connection") == 0) {
+      test_connection();
+      return;
+    }
+  }
+  print_usage();
+
+}
diff --git a/src/configure b/src/configure
new file mode 100755
index 0000000000000000000000000000000000000000..09f99a98e7bfe449c8dbe6668521fc93946d4a91
--- /dev/null
+++ b/src/configure
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# See https://octave.org/doc/interpreter/Creating-Packages.html
+
+# clean-up
+INST_DIR="$(realpath ../inst)"
+rm -r "${INST_DIR}" || true
+mkdir -p "${INST_DIR}"
+
+BUILD_DIR="$(realpath ../build)"
+
+# expand $BUILD_DIR in FILES.in
+#sed -e "s|\${BUILD_DIR}|${BUILD_DIR}|g" FILES.in > FILES
+
+ln -s "${BUILD_DIR}/inst/caosdb.mex" ${INST_DIR}/caosdb.mex
+
+mkdir -p $BUILD_DIR
+pushd $BUILD_DIR
+
+conan install ..
+cmake ..
+
+popd
diff --git a/src/Run_Test.m b/test/Run_Test.m
similarity index 65%
rename from src/Run_Test.m
rename to test/Run_Test.m
index b70b918652718418faf7ffe5044b45994d6bd22f..964dfe6d02f157dd6cbe61d0687ecd745aa4fd05 100644
--- a/src/Run_Test.m
+++ b/test/Run_Test.m
@@ -1,5 +1,5 @@
 % (C) Copyright 2021 IndiScale GmbH <info@indiscale.com>
-% (C) Copyright 2021 Daniel Hornung <d.hornung@indiscale.com>
+% (C) Copyright 2021 Timm FItschen <t.fitschen@indiscale.com>
 %
 % This file is a part of the CaosDB Project.
 %
@@ -16,16 +16,5 @@
 % You should have received a copy of the GNU Affero General Public License
 % along with this program. If not, see <https://www.gnu.org/licenses/>.
 
-% ------------------------------------------------------------------------
-% Run the tests, exit with their value.
-
-addpath('../pkg/inst/');
-
-[n, nmax, nxfail, nbug, nskip, nrtskip, nregression] = ...
-  test('some_function.m', 'verbose');
-
-disp(['Passed ' num2str(n) ' out of ' num2str(nmax) ' tests.']);
-if n == nmax
-  exit(0);
-end
-exit(1);
+pkg load caosdb;
+moxunit_runtests -verbose test_caosdb.m
diff --git a/test/test_caosdb.m b/test/test_caosdb.m
new file mode 100644
index 0000000000000000000000000000000000000000..6ce8788081c534b8efc72bae0ff76aae8cce3cee
--- /dev/null
+++ b/test/test_caosdb.m
@@ -0,0 +1,10 @@
+function test_suite=test_caosdb
+    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
+        test_functions=localfunctions();
+    catch % no problem; early Matlab versions can use initTestSuite fine
+    end
+    initTestSuite;
+
+function test_print_version
+    v = caosdb("--version")
+    assertEqual(v, "v0.1 (libcaosdb v0.0.5)")