diff --git a/src/box/lua/func_adapter.c b/src/box/lua/func_adapter.c
index f42177da62e702315069d5e83c30510d9054f389..6bcf22291eb55a1a3983f83bdc25d68d3a3c7cc7 100644
--- a/src/box/lua/func_adapter.c
+++ b/src/box/lua/func_adapter.c
@@ -124,6 +124,13 @@ func_adapter_lua_push_tuple(struct func_adapter_ctx *base, struct tuple *tuple)
 	luaT_pushtuple(ctx->L, tuple);
 }
 
+static void
+func_adapter_lua_push_bool(struct func_adapter_ctx *base, bool val)
+{
+	struct func_adapter_lua_ctx *ctx = (struct func_adapter_lua_ctx *)base;
+	lua_pushboolean(ctx->L, val);
+}
+
 static void
 func_adapter_lua_push_null(struct func_adapter_ctx *base)
 {
@@ -194,6 +201,25 @@ func_adapter_lua_pop_tuple(struct func_adapter_ctx *base, struct tuple **out)
  * of an object. The function checks all the cases.
  */
 static bool
+func_adapter_lua_is_bool(struct func_adapter_ctx *base)
+{
+	struct func_adapter_lua_ctx *ctx = (struct func_adapter_lua_ctx *)base;
+	return lua_gettop(ctx->L) >= ctx->idx &&
+	       lua_isboolean(ctx->L, ctx->idx);
+}
+
+static void
+func_adapter_lua_pop_bool(struct func_adapter_ctx *base, bool *val)
+{
+	struct func_adapter_lua_ctx *ctx = (struct func_adapter_lua_ctx *)base;
+	*val = lua_toboolean(ctx->L, ctx->idx++);
+}
+
+/**
+ * Null in Lua can be represented in two ways: nil or box.NULL.
+ * The function checks both cases.
+ */
+static bool
 func_adapter_lua_is_null(struct func_adapter_ctx *base)
 {
 	struct func_adapter_lua_ctx *ctx = (struct func_adapter_lua_ctx *)base;
@@ -245,6 +271,7 @@ func_adapter_lua_create(lua_State *L, int idx)
 		.push_double = func_adapter_lua_push_double,
 		.push_str = func_adapter_lua_push_str,
 		.push_tuple = func_adapter_lua_push_tuple,
+		.push_bool = func_adapter_lua_push_bool,
 		.push_null = func_adapter_lua_push_null,
 
 		.is_double = func_adapter_lua_is_double,
@@ -253,6 +280,8 @@ func_adapter_lua_create(lua_State *L, int idx)
 		.pop_str = func_adapter_lua_pop_str,
 		.is_tuple = func_adapter_lua_is_tuple,
 		.pop_tuple = func_adapter_lua_pop_tuple,
+		.is_bool = func_adapter_lua_is_bool,
+		.pop_bool = func_adapter_lua_pop_bool,
 		.is_null = func_adapter_lua_is_null,
 		.pop_null = func_adapter_lua_pop_null,
 
diff --git a/src/lib/core/func_adapter.h b/src/lib/core/func_adapter.h
index 8ace5cefede16843651d8a1954872fab25b2b41d..e63326731963f6c28533dc3091c3626a6b5bea22 100644
--- a/src/lib/core/func_adapter.h
+++ b/src/lib/core/func_adapter.h
@@ -69,6 +69,10 @@ struct func_adapter_vtab {
 	 */
 	void (*push_str)(struct func_adapter_ctx *ctx, const char *str,
 			 size_t len);
+	/**
+	 * Pushes boolean argument.
+	 */
+	void (*push_bool)(struct func_adapter_ctx *ctx, bool val);
 	/**
 	 * Pushes null argument.
 	 */
@@ -101,6 +105,14 @@ struct func_adapter_vtab {
 	 */
 	void (*pop_str)(struct func_adapter_ctx *ctx, const char **str,
 			size_t *len);
+	/**
+	 * Checks if the next returned value is a boolean.
+	 */
+	bool (*is_bool)(struct func_adapter_ctx *ctx);
+	/**
+	 * Pops boolean value.
+	 */
+	void (*pop_bool)(struct func_adapter_ctx *ctx, bool *val);
 	/**
 	 * Checks if the next returned value is null or nothing.
 	 */
@@ -189,6 +201,13 @@ func_adapter_push_tuple(struct func_adapter *func,
 	func->vtab->push_tuple(ctx, tuple);
 }
 
+static inline void
+func_adapter_push_bool(struct func_adapter *func, struct func_adapter_ctx *ctx,
+		       bool val)
+{
+	func->vtab->push_bool(ctx, val);
+}
+
 static inline void
 func_adapter_push_null(struct func_adapter *func, struct func_adapter_ctx *ctx)
 {
@@ -237,6 +256,20 @@ func_adapter_pop_tuple(struct func_adapter *func,
 	func->vtab->pop_tuple(ctx, tuple);
 }
 
+static inline bool
+func_adapter_is_bool(struct func_adapter *func, struct func_adapter_ctx *ctx)
+{
+	return func->vtab->is_bool(ctx);
+}
+
+static inline void
+func_adapter_pop_bool(struct func_adapter *func, struct func_adapter_ctx *ctx,
+		      bool *val)
+{
+	assert(func_adapter_is_bool(func, ctx));
+	func->vtab->pop_bool(ctx, val);
+}
+
 static inline bool
 func_adapter_is_null(struct func_adapter *func, struct func_adapter_ctx *ctx)
 {
diff --git a/test/unit/lua_func_adapter.c b/test/unit/lua_func_adapter.c
index 6f30f8f4bd27fadad9ab63c321953d962e0b3043..985fa0eb94427f45d6f6dacd73be22098945c7e2 100644
--- a/test/unit/lua_func_adapter.c
+++ b/test/unit/lua_func_adapter.c
@@ -167,6 +167,45 @@ test_string(void)
 	check_plan();
 }
 
+static void
+test_bool(void)
+{
+	plan(10);
+	header();
+
+	int idx = generate_function(
+		"function(a, b, c, d) "
+		"return a, not b, c, not d end");
+	bool arguments[4];
+	for (size_t i = 0; i < lengthof(arguments); ++i)
+		arguments[i] = rand() % 2 == 0;
+	struct func_adapter *func = func_adapter_lua_create(tarantool_L, idx);
+	struct func_adapter_ctx ctx;
+	func_adapter_begin(func, &ctx);
+	for (size_t i = 0; i < lengthof(arguments); ++i)
+		func_adapter_push_bool(func, &ctx, arguments[i]);
+	int rc = func_adapter_call(func, &ctx);
+	fail_if(rc != 0);
+
+	for (size_t i = 0; i < lengthof(arguments); ++i) {
+		ok(func_adapter_is_bool(func, &ctx), "Expected double");
+		bool retval = false;
+		func_adapter_pop_bool(func, &ctx, &retval);
+		bool is_odd = i % 2 == 0;
+		bool equal = arguments[i] == retval;
+		is(is_odd, equal, "Only odd elements are equal");
+	}
+
+	ok(!func_adapter_is_bool(func, &ctx), "No values left - no bool");
+	ok(func_adapter_is_null(func, &ctx), "No values left");
+	func_adapter_end(func, &ctx);
+	func_adapter_destroy(func);
+	lua_settop(tarantool_L, 0);
+
+	footer();
+	check_plan();
+}
+
 static void
 test_null(void)
 {
@@ -293,12 +332,13 @@ test_callable(void)
 static int
 test_lua_func_adapter(void)
 {
-	plan(7);
+	plan(8);
 	header();
 
 	test_numeric();
 	test_tuple();
 	test_string();
+	test_bool();
 	test_null();
 	test_error();
 	test_get_func();