diff --git a/CMakeLists.txt b/CMakeLists.txt
index d6fa9ab8416cecabeca3412cd0ade69717b47f20..80e706f20b468cc6368e00e18cca747f69c7f737 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,7 +44,7 @@ link_directories(${PROJECT_BINARY_DIR}/s2client-api/bin)
 add_definitions(-DSC2API)
 
 # Create the executable.
-pybind11_add_module(library library.cpp ${BOT_SOURCES})
+pybind11_add_module(library library.cpp library.h ${BOT_SOURCES})
 target_link_libraries(library PRIVATE
     sc2api sc2lib sc2utils sc2protocol libprotobuf
 )
diff --git a/library.cpp b/library.cpp
index bd86eb69cdbc32725b6888865eb22d825629cfca..d4195c3eba6d9c3b8fa78bb6cf0a54df279e133c 100644
--- a/library.cpp
+++ b/library.cpp
@@ -1,14 +1,10 @@
-#include <pybind11/pybind11.h>
-#include <sc2api/sc2_api.h>
-#include "src/IDABot.h"
-#include <iostream>
+#include "library.h"
+
+namespace py = pybind11;
 
 void run()
 {
-    char *argv[] = { "executable", NULL};
-    int argc = sizeof(argv) / sizeof(char*) - 1;
-    sc2::Coordinator coordinator;
-    coordinator.LoadSettings(argc, argv);
+    Coordinator coordinator;
 
     IDABot bot;
     coordinator.SetParticipants({
@@ -23,14 +19,46 @@ void run()
     }
 }
 
-int add(int i, int j)
-{
-    return i + j + 1;
-}
-
 PYBIND11_MODULE(library, m)
 {
     m.doc() = "pybind11 example plugin";
-    m.def("add", &add, "A function which adds two numbers");
+
+    py::class_<Coordinator>(m, "Coordinator")
+        .def(py::init())
+        .def("SetParticipants", &sc2::Coordinator::SetParticipants)
+        .def("LaunchStarcraft", &sc2::Coordinator::LaunchStarcraft)
+        .def("StartGame", &sc2::Coordinator::StartGame)
+        .def("Update", &sc2::Coordinator::Update);
+
+    py::enum_<sc2::Race>(m, "Race")
+        .value("Terran", sc2::Race::Terran)
+        .value("Zerg", sc2::Race::Zerg)
+        .value("Protoss", sc2::Race::Protoss)
+        .value("Random", sc2::Race::Random);
+
+    py::class_<sc2::Agent>(m, "Agent")
+        .def(py::init());
+
+    // IDABot is a specialization of Agent
+    py::class_<IDABot, sc2::Agent>(m, "IDABot")
+        .def(py::init());
+
+    py::class_<sc2::PlayerSetup>(m, "PlayerSetup");
+
+    py::enum_<sc2::Difficulty>(m, "Difficulty")
+        .value("VeryEasy", sc2::Difficulty::VeryEasy)
+        .value("Easy", sc2::Difficulty::Easy)
+        .value("Medium", sc2::Difficulty::Medium)
+        .value("MediumHard", sc2::Difficulty::MediumHard)
+        .value("Hard", sc2::Difficulty::Hard)
+        .value("HardVeryHard", sc2::Difficulty::HardVeryHard)
+        .value("VeryHard", sc2::Difficulty::VeryHard)
+        .value("CheatVision", sc2::Difficulty::CheatVision)
+        .value("CheatMoney", sc2::Difficulty::CheatMoney)
+        .value("CheatInsane", sc2::Difficulty::CheatInsane);
+
+    m.def("CreateParticipant", &sc2::CreateParticipant, "Create participant from agent");
+    m.def("CreateComputer", &sc2::CreateComputer, "Create participant from built-in Starcraft computer");
+
     m.def("run", &run, "Start Starcraft 2");
 }
diff --git a/library.h b/library.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b3abdd660d001e00a58ac7909c0b50574ef917c
--- /dev/null
+++ b/library.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <pybind11/pybind11.h>
+#include <sc2api/sc2_api.h>
+#include "src/IDABot.h"
+#include <iostream>
+#include <pybind11/stl.h> /* Automatic conversion from std::vector to Python lists */
+
+class Coordinator : public sc2::Coordinator
+{
+public:
+    // TODO: We might not always want default value when we run on Linux
+    Coordinator() : sc2::Coordinator()
+    {
+        char *argv[] = { "executable", NULL};
+        int argc = sizeof(argv) / sizeof(char*) - 1;
+        LoadSettings(argc, argv);
+    }
+};
\ No newline at end of file