diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index fdb0975ac0fa760388df0c44b42e8cfaef8238d3..ed9895ac8133e7594b1ef9ded8d50369e4dac0d6 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -5,6 +5,7 @@
 #include "archive.hh"
 #include "affinity.hh"
 #include "globals.hh"
+#include "derivations.hh"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -458,7 +459,14 @@ void RemoteStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
 BuildResult RemoteStore::buildDerivation(const Path & drvPath, const BasicDerivation & drv,
     BuildMode buildMode)
 {
-    throw Error("not implemented");
+    openConnection();
+    to << wopBuildDerivation << drvPath << drv << buildMode;
+    processStderr();
+    BuildResult res;
+    unsigned int status;
+    from >> status >> res.errorMsg;
+    res.status = (BuildResult::Status) status;
+    return res;
 }
 
 
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index d037d7402ede4210da7db3bdc319018692dc6efa..5a0ef5117aa66257b42fccf013d81c020ea9f2e5 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -43,7 +43,8 @@ typedef enum {
     wopQuerySubstitutablePaths = 32,
     wopQueryValidDerivers = 33,
     wopOptimiseStore = 34,
-    wopVerifyStore = 35
+    wopVerifyStore = 35,
+    wopBuildDerivation = 36,
 } WorkerOp;
 
 
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
index f8e9d00c12b8b24fda0ba7817e690a42ec43c524..f136a13248ba1f852b44aa59adbaedab42f7006a 100644
--- a/src/libutil/serialise.cc
+++ b/src/libutil/serialise.cc
@@ -248,6 +248,13 @@ Source & operator >> (Source & in, string & s)
 }
 
 
+Source & operator >> (Source & in, unsigned int & n)
+{
+    n = readInt(in);
+    return in;
+}
+
+
 template<class T> T readStrings(Source & source)
 {
     unsigned int count = readInt(source);
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index 97ac3e912f858ce5df85ddddbccdfac0e39ac513..979ff849fcafa91bb709154da7b7472f8a2b37da 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -143,6 +143,7 @@ string readString(Source & source);
 template<class T> T readStrings(Source & source);
 
 Source & operator >> (Source & in, string & s);
+Source & operator >> (Source & in, unsigned int & n);
 
 
 MakeError(SerialisationError, Error)
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 199d3288f4d68c432e03261394bb4aa679f08cb5..aaae691e9ee86227018aa9382e9a9fe679bcce96 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -7,6 +7,7 @@
 #include "affinity.hh"
 #include "globals.hh"
 #include "monitor-fd.hh"
+#include "derivations.hh"
 
 #include <algorithm>
 
@@ -325,6 +326,20 @@ static void performOp(bool trusted, unsigned int clientVersion,
         break;
     }
 
+    case wopBuildDerivation: {
+        Path drvPath = readStorePath(from);
+        BasicDerivation drv;
+        from >> drv;
+        BuildMode buildMode = (BuildMode) readInt(from);
+        startWork();
+        if (!trusted)
+            throw Error("you are not privileged to build derivations");
+        auto res = store->buildDerivation(drvPath, drv, buildMode);
+        stopWork();
+        to << res.status << res.errorMsg;
+        break;
+    }
+
     case wopEnsurePath: {
         Path path = readStorePath(from);
         startWork();