diff --git a/src/cli/admin.rs b/src/cli/admin.rs
index 01491bf9b279f88fea4ac728923579f7e912863a..929be1e82c17112e25498257e0735e0a6cc720be 100644
--- a/src/cli/admin.rs
+++ b/src/cli/admin.rs
@@ -82,7 +82,7 @@ impl UnixClient {
 
     /// Creates struct object using `path` for raw unix socket.
     ///
-    /// Setup delimiter and ignore tarantool prompt.
+    /// Setup delimiter, default language and ignore tarantool prompt.
     fn new(path: &str) -> Result<Self> {
         let socket = UnixStream::connect(path)?;
         let mut client = Self::from_stream(socket)?;
@@ -99,6 +99,11 @@ impl UnixClient {
         debug_assert!(prompt.contains("Tarantool"));
         debug_assert!(prompt.contains("Lua console"));
 
+        // set default language SQL
+        client.write("\\set language sql")?;
+        let response = client.read()?;
+        debug_assert!(response.contains("true"));
+
         Ok(client)
     }
 
@@ -176,7 +181,7 @@ impl UnixClient {
         let res = completions
             .unwrap_or_default()
             .first()
-            .map(|v| v[1..].to_owned())
+            .map(|v| v[1..].into())
             .unwrap_or_default();
 
         Ok(res)
@@ -202,7 +207,12 @@ fn admin_repl(args: args::Admin) -> core::result::Result<(), ReplError> {
         },
     };
 
-    let mut console = Console::with_completer("picoadmin :) ", helper)?;
+    let mut console = Console::with_completer(helper)?;
+
+    console.greet(&format!(
+        "Connected to admin console by socket path \"{}\"",
+        args.socket_path
+    ));
 
     while let Some(line) = console.read()? {
         let mut temp_client = client.borrow_mut();
diff --git a/src/cli/connect.rs b/src/cli/connect.rs
index d7365decb1711b4c37f1e426baa93692b42ae23f..7383a15e0d35b65a917403dd1452cc91714eec4a 100644
--- a/src/cli/connect.rs
+++ b/src/cli/connect.rs
@@ -120,7 +120,7 @@ fn sql_repl(args: args::Connect) -> Result<(), ReplError> {
     };
 
     let mut config = Config::default();
-    config.creds = Some((user, password));
+    config.creds = Some((user.clone(), password));
     config.auth_method = args.auth_method;
 
     let client = ::tarantool::fiber::block_on(Client::connect_with_config(
@@ -133,7 +133,12 @@ fn sql_repl(args: args::Connect) -> Result<(), ReplError> {
     // and we want to check whether authentication have succeeded or not
     ::tarantool::fiber::block_on(client.call("box.schema.user.info", &()))?;
 
-    let mut console = Console::new("picosql :) ")?;
+    let mut console = Console::new()?;
+
+    console.greet(&format!(
+        "Connected to interactive console by address \"{}:{}\" under \"{}\" user",
+        address.host, address.port, user
+    ));
 
     while let Some(line) = console.read()? {
         let response = ::tarantool::fiber::block_on(client.call("pico.sql", &(line,)))?;
diff --git a/src/cli/console.rs b/src/cli/console.rs
index 3cd308dbb4ccf0ad8280ff15886f5e21b80533f2..8e3efd55c690382091f64cbe7c43ba73291591b2 100644
--- a/src/cli/console.rs
+++ b/src/cli/console.rs
@@ -34,15 +34,22 @@ pub enum ReplError {
 
 pub type Result<T> = std::result::Result<T, ReplError>;
 
+/// Shows user of console
+pub enum ConsoleType {
+    Admin,
+    User,
+}
+
 /// Input/output handler
 pub struct Console<H: Helper> {
     editor: Editor<H, FileHistory>,
     history_file_path: PathBuf,
-    prompt: String,
+    console_type: ConsoleType,
 }
 
 impl<T: Helper> Console<T> {
-    const HISTORY_FILE_NAME: &'static str = ".picodata_history";
+    const HISTORY_FILE_NAME: &str = ".picodata_history";
+    const PROMPT: &str = "picodata> ";
 
     // Ideally we should have an enum for all commands. For now we have only two options, usual line
     // and only one special command. To not overengineer things at this point just handle this as ifs.
@@ -77,13 +84,34 @@ impl<T: Helper> Console<T> {
                 return Ok(ControlFlow::Continue(()));
             }
 
+            // we don't check content intentionally
             let line = read_to_string(temp.path()).map_err(ReplError::Io)?;
 
             return Ok(ControlFlow::Break(line));
-        } else if line == "\\lua" {
-            return Ok(ControlFlow::Break("\\set language lua".to_owned()));
-        } else if line == "\\sql" {
-            return Ok(ControlFlow::Break("\\set language sql".to_owned()));
+        } else if line == "\\help" {
+            self.print_help();
+            return Ok(ControlFlow::Continue(()));
+        }
+
+        // all language switching is availiable only for admin console
+        match self.console_type {
+            ConsoleType::User => (),
+            ConsoleType::Admin => {
+                if line == "\\lua" {
+                    return Ok(ControlFlow::Break("\\set language lua".into()));
+                } else if line == "\\sql" {
+                    return Ok(ControlFlow::Break("\\set language sql".into()));
+                }
+
+                let splitted = line.split_whitespace().collect::<Vec<_>>();
+                if splitted.len() > 2
+                    && (splitted[0] == "\\s" || splitted[0] == "\\set")
+                    && (splitted[1] == "language" || splitted[1] == "l" || splitted[1] == "lang")
+                    && (splitted[2] == "lua" || splitted[2] == "sql")
+                {
+                    return Ok(ControlFlow::Break(line));
+                }
+            }
         }
 
         self.write("Unknown special sequence");
@@ -98,7 +126,7 @@ impl<T: Helper> Console<T> {
     /// Reads from stdin. Takes into account treating special symbols.
     pub fn read(&mut self) -> Result<Option<String>> {
         loop {
-            let readline = self.editor.readline(&self.prompt);
+            let readline = self.editor.readline(Self::PROMPT);
             match readline {
                 Ok(line) => {
                     let line = match self.process_line(line)? {
@@ -151,10 +179,40 @@ impl<T: Helper> Console<T> {
 
         Ok((editor, history_file_path))
     }
+
+    fn print_help(&self) {
+        let switch_language_info: &'static str = "
+        \\lua          -- switch current language to Lua
+        \\sql          -- switch current language to SQL";
+
+        let lang_info = match self.console_type {
+            ConsoleType::Admin => switch_language_info,
+            ConsoleType::User => "",
+        };
+
+        let help = format!("
+    Available backslash commands:
+        \\e            -- open text editor. Path to editor should be set via EDITOR environment variable
+        \\help         -- show this screen{lang_info}
+
+    Available special commands:
+        Alt  + Enter  -- move the carriage to newline
+        Ctrl + C      -- discard current input
+        Ctrl + D      -- quit interactive console
+        ");
+
+        self.write(&help);
+    }
+
+    /// Prints information about connection and help hint
+    pub fn greet(&self, connection_info: &str) {
+        self.write(connection_info);
+        self.write("type '\\help' for interactive help");
+    }
 }
 
 impl Console<LuaHelper> {
-    pub fn with_completer(prompt: &str, helper: LuaHelper) -> Result<Self> {
+    pub fn with_completer(helper: LuaHelper) -> Result<Self> {
         let (mut editor, history_file_path) = Self::editor_with_history()?;
 
         editor.set_helper(Some(helper));
@@ -164,19 +222,19 @@ impl Console<LuaHelper> {
         Ok(Console {
             editor,
             history_file_path,
-            prompt: prompt.to_string(),
+            console_type: ConsoleType::Admin,
         })
     }
 }
 
 impl Console<()> {
-    pub fn new(prompt: &str) -> Result<Self> {
+    pub fn new() -> Result<Self> {
         let (editor, history_file_path) = Self::editor_with_history()?;
 
         Ok(Console {
             editor,
             history_file_path,
-            prompt: prompt.to_string(),
+            console_type: ConsoleType::User,
         })
     }
 }
diff --git a/test/int/test_cli_connect.py b/test/int/test_cli_connect.py
index cf27807026d967eedb3d8de054d5c1fda102a962..f5d0ebc589a50b789534bdf65b67406e6051c872 100644
--- a/test/int/test_cli_connect.py
+++ b/test/int/test_cli_connect.py
@@ -34,7 +34,7 @@ def test_connect_testuser(i1: Instance):
     cli.expect_exact("Enter password for testuser: ")
     cli.sendline("testpass")
 
-    cli.expect_exact("picosql :)")
+    cli.expect_exact("picodata> ")
 
     eprint("^D")
     cli.sendcontrol("d")
@@ -53,7 +53,7 @@ def test_connect_user_host_port(i1: Instance):
     cli.expect_exact("Enter password for testuser: ")
     cli.sendline("testpass")
 
-    cli.expect_exact("picosql :)")
+    cli.expect_exact("picodata> ")
 
     eprint("^D")
     cli.sendcontrol("d")
@@ -69,7 +69,7 @@ def test_connect_guest(i1: Instance):
     )
     cli.logfile = sys.stdout
 
-    cli.expect_exact("picosql :)")
+    cli.expect_exact("picodata> ")
 
     eprint("^D")
     cli.sendcontrol("d")
@@ -140,7 +140,7 @@ def test_connect_auth_type_ok(i1: Instance):
     cli.expect_exact("Enter password for testuser: ")
     cli.sendline("testpass")
 
-    cli.expect_exact("picosql :)")
+    cli.expect_exact("picodata> ")
 
     eprint("^D")
     cli.sendcontrol("d")
@@ -242,6 +242,10 @@ def configure_ldap_server(username, password, data_dir) -> LDAPServerState:
     )
 
 
+@pytest.mark.xfail(
+    run=False,
+    reason=("need installed glauth"),
+)
 def test_connect_auth_type_ldap(cluster: Cluster):
     username = "ldapuser"
     password = "ldappass"
@@ -384,7 +388,7 @@ def test_connect_unix_ok_via_default_sock(cluster: Cluster):
     )
     cli.logfile = sys.stdout
 
-    cli.expect_exact("picoadmin :) ")
+    cli.expect_exact("picodata> ")
 
     # Change language to SQL works
     cli.sendline("\\sql")
@@ -469,7 +473,7 @@ def test_connect_with_password_from_file(i1: Instance, binary_path: str):
     )
     cli.logfile = sys.stdout
 
-    cli.expect_exact("picosql :)")
+    cli.expect_exact("picodata> ")
 
     eprint("^D")
     cli.sendcontrol("d")
@@ -497,28 +501,84 @@ def test_lua_completion(cluster: Cluster):
     )
     cli.logfile = sys.stdout
 
-    cli.expect_exact("picoadmin :) ")
+    cli.expect_exact("picodata> ")
+    cli.sendline("\\lua")
 
     # With several possible variants they are shown as list
-    cli.sendline("to\t\t")
+    cli.send("to")
+    cli.send("\t\t")
     cli.expect_exact("tostring(    tonumber(    tonumber64(")
+    cli.sendcontrol("c")
 
-    cli.sendline("box.c\t\t")
+    cli.send("box.c")
+    cli.send("\t\t")
     cli.expect_exact("box.ctl      box.cfg      box.commit(")
+    cli.sendcontrol("c")
 
-    cli.sendline("tonumber(to\t\t")
+    cli.send("tonumber(to")
+    cli.send("\t\t")
     cli.expect_exact("tostring(    tonumber(    tonumber64(")
+    cli.sendcontrol("c")
 
     # With one possible variant it automaticaly completes current word
     # so we can check that is completed by result of completing this command
-    cli.sendline("hel\t\t")
+    cli.send("hel")
+    cli.send("\t")
+    cli.expect_exact("help")
+    cli.sendcontrol("c")
+
+    cli.send("bred bo")
+    cli.send("\t")
+    cli.expect_exact("bred box")
+
+
+def test_connect_connection_info_and_help(i1: Instance):
+    cli = pexpect.spawn(
+        command=i1.binary_path,
+        args=["connect", f"{i1.host}:{i1.port}", "-u", "testuser", "-a", "chap-sha1"],
+        encoding="utf-8",
+        timeout=1,
+    )
+    cli.logfile = sys.stdout
+
+    cli.expect_exact("Enter password for testuser: ")
+    cli.sendline("testpass")
+
     cli.expect_exact(
-        "To get help, see the Tarantool manual at https://tarantool.io/en/doc/"
+        f'Connected to interactive console by address "{i1.host}:{i1.port}" under "testuser" user'
     )
+    cli.expect_exact("type '\\help' for interactive help")
+    cli.expect_exact("picodata> ")
 
-    cli.sendline("bred bo\t\t")
-    cli.expect_exact("bred box")
-    cli.sendline(" ")
+    eprint("^D")
+    cli.sendcontrol("d")
+    cli.expect_exact(pexpect.EOF)
+
+
+def test_admin_connection_info_and_help(cluster: Cluster):
+    i1 = cluster.add_instance(wait_online=False)
+    i1.start()
+    i1.wait_online()
+
+    cli = pexpect.spawn(
+        # For some uninvestigated reason, readline trims the propmt in CI
+        # Instead of
+        #   unix/:/some/path/to/admin.sock>
+        # it prints
+        #   </path/to/admin.sock>
+        #
+        # We were unable to debug it quickly and used cwd as a workaround
+        cwd=i1.data_dir,
+        command=i1.binary_path,
+        args=["admin", "./admin.sock"],
+        encoding="utf-8",
+        timeout=1,
+    )
+    cli.logfile = sys.stdout
+
+    cli.expect_exact('Connected to admin console by socket path "./admin.sock"')
+    cli.expect_exact("type '\\help' for interactive help")
+    cli.expect_exact("picodata> ")
 
     eprint("^D")
     cli.sendcontrol("d")