diff --git a/changelogs/unreleased/gh-7413-use-streams-in-binary-console.md b/changelogs/unreleased/gh-7413-use-streams-in-binary-console.md
new file mode 100644
index 0000000000000000000000000000000000000000..970affe40aaa66fe20471679bd40c072e4de43f6
--- /dev/null
+++ b/changelogs/unreleased/gh-7413-use-streams-in-binary-console.md
@@ -0,0 +1,3 @@
+## feature/core
+
+* Supported interactive transactions for remote binary console (gh-7413).
diff --git a/src/box/lua/console.lua b/src/box/lua/console.lua
index b306f321864a7c845267322345fb5e80bf3c06a7..ed168822deffc26090781a7515ab64c9e79ba422 100644
--- a/src/box/lua/console.lua
+++ b/src/box/lua/console.lua
@@ -578,7 +578,7 @@ end
 --
 local function remote_eval(self, line)
     if line and self.remote.state == 'active' then
-        local ok, res = pcall(self.remote.eval, self.remote, line)
+        local ok, res = pcall(self.remote.console_eval, line)
         if self.remote.state == 'active' then
             return ok and res or format(false, res)
         end
@@ -586,6 +586,7 @@ local function remote_eval(self, line)
     local err = self.remote.error
     self.remote:close()
     self.remote = nil
+    self.console_eval = nil
     self.eval = nil
     self.prompt = nil
     self.completion = nil
@@ -834,18 +835,26 @@ local function connect(uri, opts)
             log.verbose(err)
             box.error(box.error.NO_CONNECTION)
         end
+        remote.console_eval = function(line)
+            return remote:eval(line)
+        end
     else
         if not remote.host then
             remote.host = 'localhost'
         end
-        local old_eval = remote.eval
-        remote.eval = function(con, line)
-            return old_eval(con, 'return require("console").eval(...)', {line})
+        local eval_obj
+        if remote.peer_protocol_features.streams then
+            eval_obj = remote:new_stream()
+        else
+            eval_obj = remote
+        end
+        remote.console_eval = function(line)
+            return eval_obj:eval('return require("console").eval(...)', {line})
         end
     end
 
     -- check connection && permissions
-    local ok, res = pcall(remote.eval, remote, 'return true')
+    local ok, res = pcall(remote.console_eval, 'return true')
     if not ok then
         remote:close()
         pcall(self.on_client_disconnect, self)
@@ -860,7 +869,7 @@ local function connect(uri, opts)
         local c = string.format(
             'return require("console").completion_handler(%q, %d, %d)',
             str, pos1, pos2)
-        return yaml.decode(remote:eval(c))[1]
+        return yaml.decode(remote.console_eval(c))[1]
     end
     log.info("connected to %s:%s", self.remote.host, self.remote.port)
     return true
diff --git a/test/app-luatest/gh_7288_console_flavours_vs_txn_test.lua b/test/app-luatest/gh_7288_console_flavours_vs_txn_test.lua
index 2fb60e7d5c648b5c1b7efdd704afd69e4ab0f734..29c6b202475f4d8e37c7fda5a813241a3979c19b 100644
--- a/test/app-luatest/gh_7288_console_flavours_vs_txn_test.lua
+++ b/test/app-luatest/gh_7288_console_flavours_vs_txn_test.lua
@@ -3,6 +3,7 @@ local console = require('console')
 local fiber = require('fiber')
 local fio = require('fio')
 local string = require('string')
+local netbox = require('net.box')
 local t = require('luatest')
 
 local function configure_box()
@@ -158,7 +159,6 @@ local false_output = [[
 ]]
 
 g.test_begin_in_expr_without_error = function(cg)
-    t.xfail_if(cg.params.name == "remote_bin")
     local console = cg.console
     console:send('box.begin()')
     t.assert_equals(console:send('box.is_in_txn()'), true_output)
@@ -176,9 +176,52 @@ g.test_begin_in_expr_with_error = function(cg)
 end
 
 g.test_error_in_different_expr = function(cg)
-    t.xfail_if(cg.params.name == "remote_bin")
     local console = cg.console
     console:send('box.begin()')
     console:send('error("test error")')
     t.assert_equals(console:send('box.is_in_txn()'), true_output)
 end
+
+local gb = t.group('gh-7288-bin-backcompat')
+
+gb.before_all(function()
+    gb.save = netbox.connect
+    netbox.connect = function(...)
+        local remote = gb.save(...)
+        remote.peer_protocol_features.streams = false
+        return remote
+    end
+    gb.console = TestConsole:new(flavours.remote_bin)
+    gb.console:start()
+end)
+
+gb.after_all(function()
+    gb.console:stop()
+    gb.console = nil
+    netbox.connect = gb.save
+end)
+
+gb.before_each(function()
+    gb.console:connect()
+end)
+
+gb.after_each(function()
+    gb.console:disconnect()
+end)
+
+gb.test_remote_bin_no_streams_works = function(cg)
+    local console = cg.console
+    -- first check we have backcompat mode without streams
+    local expected = [[
+---
+- error: Transaction is active at return from function
+...
+]]
+    t.assert_equals(console:send('box.begin()'), expected)
+    local expected = [[
+---
+- 4
+...
+]]
+    t.assert_equals(console:send('2 + 2'), expected)
+end