diff --git a/deploy.sh b/deploy.sh
index 21c771bc7e64c4578653f68b40f583833c15518f..5b32174a5740fde435f71f82d0455cfc6b6cb6eb 100644
--- a/deploy.sh
+++ b/deploy.sh
@@ -1,5 +1,11 @@
 #!/bin/bash
 echo "TELEGRAM_BOT_TOKEN=${BOT_TOKEN}" >>.env.docker
+
+# Store some info in app.info file
+printf "Maintainer: \`win10@list.ru\`\n" >app.info
+printf "repo url: \`%s\`\n" "$CI_PROJECT_URL" >>app.info
+printf "last commit message: \`\`\`\n%s \`\`\`\n" "$(git log -1 --pretty=%B)" >>app.info
+
 rm -rf "${APP_DIR:?}/"*
 rsync -av --exclude=".git" . "${APP_DIR}"
 cd "${APP_DIR}" || exit 1
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index 71aa015cf001149280d751b3ace80dda5e562838..aec3e5057c0c12f6d4f24a5d0836b9896c72e485 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -17,6 +17,7 @@ services:
       POSTGRES_USER: 'telegram_sysadmin'
       POSTGRES_HOST: 'system_bot_postgres'
       POSTGRES_PORT: 5432
+      APP_MODE: 'prod'
     volumes:
       - ~/.ssh:/root/.ssh
       - ./:/app
diff --git a/docker-compose.yml b/docker-compose.yml
index 2b3e15ce8cb13932af9d68f81a0d6f2d6cca4136..55189d536165ab8b14e4ae9da3ab9314009e7c6d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,6 +17,7 @@ services:
       POSTGRES_USER: 'dev_telegram_sysadmin'
       POSTGRES_HOST: 'system_bot_postgres'
       POSTGRES_PORT: 5432
+      APP_MODE: 'dev'
       TELEGRAM_BOT_TOKEN: 'your dev token here'
     volumes:
       - ~/.ssh:/root/.ssh
diff --git a/src/__init__.py b/src/__init__.py
index 446d9fd1b2deff9fe24e817676ce484913b2c503..7b08a4fc09423a58799422b90869658c6cb7b985 100644
--- a/src/__init__.py
+++ b/src/__init__.py
@@ -1,2 +1,2 @@
-__version__ = '0.0.1'
+__version__ = '0.0.2'
 
diff --git a/src/actions/basic_actions.py b/src/actions/basic_actions.py
index 5e11b69adc7c0db5a749b43ac93e50eb66a264ed..fa6be86e8d8e213d2b549e29d1afc65d975e4edf 100644
--- a/src/actions/basic_actions.py
+++ b/src/actions/basic_actions.py
@@ -1,6 +1,8 @@
 from aiogram.types import Message, ParseMode
 
+from src import __version__ as bot_version
 from src.models.server import ServerPermissions
+from src.settings import settings
 from src.utils import chunks
 from src.utils.decorators import (
     bot_action
@@ -39,3 +41,31 @@ async def bot_run_code(message: Message, alias: str, command: str, state=None):
     results = chunks(await run_ssh_command(server, command), 4095)
     for res in results:
         await message.reply(f'```\n{res}```', parse_mode=ParseMode.MARKDOWN)
+
+
+@bot_action(trigger_str='meme admin toggle debug')
+async def debug_mode_toggle(message: Message, state=None):
+    if settings.app_mode != 'dev':
+        await message.reply('Debug mode is unavailable in production.')
+        return
+    if settings.debug_mode:
+        settings.debug_mode = False
+        await message.reply('Leaving debug mode')
+    else:
+        settings.debug_mode = True
+        await message.reply('Entering debug mode')
+
+
+@bot_action(trigger_str='meme admin info')
+async def bot_info(message: Message, state):
+    if settings.app_mode == 'prod':
+        with open('app.info') as f:
+            app_info = f.read()
+    else:
+        app_info = f'App mode: `{settings.app_mode}`'
+    await message.reply(
+        '* Le-memese system administrator info *\n\n'
+        f'version: `{bot_version}`\n'
+        f'{app_info}'
+        , parse_mode=ParseMode.MARKDOWN
+    )
diff --git a/src/actions/interactive_session.py b/src/actions/interactive_session.py
index a213be1644f29f1943036bfe179fafb5cfcfccff..c731370449df2eebeaff8947952c2ccb459881e6 100644
--- a/src/actions/interactive_session.py
+++ b/src/actions/interactive_session.py
@@ -16,9 +16,10 @@ from aiogram.types import (
 from src.models.crud.server_crud import fn_get_server
 from src.models.server import ServerPermissions
 from src.settings import settings
+from src.utils.debug_mode import debug_message
 from src.utils.decorators import bot_action
 from src.utils.server_utils import get_server_by_alias
-from src.utils.ssh import session_manager
+from src.utils.ssh import session_manager, run_ssh_command
 
 logger = logging.getLogger()
 
@@ -42,6 +43,12 @@ async def start_interactive_mode(message: Message, state=None):
     if not user_available_servers:
         raise Exception(
             'Cannot start interactive session.\n\nNo server with remote command execution is available for you.')
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Available rce servers: {list(map(lambda x: x.server_alias, user_available_servers))}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        )
+
     await UserStates.initial.set()
     markup = ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
     for server in user_available_servers:
@@ -51,15 +58,22 @@ async def start_interactive_mode(message: Message, state=None):
 
 @bot_action(filter_state=UserStates.initial)
 async def choose_server(message: Message, state: FSMContext):
-    async with state.proxy() as data:
-        logger.debug(data)
     server_alias = message.text
     chosen_server = await get_server_by_alias(message, server_alias)
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Server permissions: {chosen_server.server_permissions.name} \n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        )
+
     if chosen_server.server_permissions.value < ServerPermissions.RCE.value \
             and str(message.from_user.id) != chosen_server.server_admin:
         raise Exception('You do not have permission for remote code execution.'
                         ' Please ask user who added this server to change permission level.')
 
+    # Dummy command to check that server is online
+    await run_ssh_command(chosen_server, 'uname')
+
     async with state.proxy() as current_state:
         current_state['server_alias'] = chosen_server.server_alias
         current_state['session_id'] = await session_manager.add_connection(chosen_server)
@@ -91,5 +105,10 @@ async def exit_session(message: Message, state: FSMContext):
 @bot_action(filter_state=UserStates.interactive)
 async def run_interactive_command(message: Message, state: FSMContext):
     async with state.proxy() as current_state:
+        await debug_message(message,
+                            f'Chat id: {message.chat.id}\n'
+                            f'Current user: {str(message.from_user.id)}\n'
+                            f'Session id: {current_state["session_id"]}\n'
+                            )
         result = await session_manager.run_command(current_state['session_id'], message.text)
         await message.reply(f'```\n{result if result else "Nothing to show"}```', parse_mode=ParseMode.MARKDOWN)
diff --git a/src/actions/permissions.py b/src/actions/permissions.py
index 57cb1bbcd85b391318e8c24f0422b1628e39d2e8..5405adb9fcb0b21284446fbbf42858523a2d0e49 100644
--- a/src/actions/permissions.py
+++ b/src/actions/permissions.py
@@ -5,6 +5,7 @@ from aiogram.types import Message, ParseMode
 from src.models.crud.server_crud import fn_update_server
 from src.models.server import ServerPermissions
 from src.settings import settings
+from src.utils.debug_mode import debug_message
 from src.utils.decorators import bot_action
 from src.utils.server_utils import get_server_by_alias
 
@@ -36,6 +37,14 @@ async def list_permissions(message: Message, state=None):
             ])
 async def change_permissions(message: Message, server_alias, permission, state=None):
     server = await get_server_by_alias(message, server_alias)
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Server alias: {server_alias}\n'
+                        f'Requested permission: {permission}\n'
+                        f'Server admin: {server.server_admin}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        )
+
     if not (str(message.from_user.id) == server.server_admin):
         raise Exception('You have no permissions to change server permissions.\nOnly admins can do this.')
     if permission.upper() not in ServerPermissions.__members__:
diff --git a/src/actions/server_management.py b/src/actions/server_management.py
index 6ba1e534fc7d7c70c684161eafab4b9994719877..aaf38eee91956c1ee6053787437256c9b785a730 100644
--- a/src/actions/server_management.py
+++ b/src/actions/server_management.py
@@ -10,6 +10,7 @@ from src.models.crud.server_crud import (
 )
 from src.models.server import ServerPermissions, Server
 from src.settings import settings
+from src.utils.debug_mode import debug_message
 from src.utils.decorators import bot_action
 from src.utils.server_utils import get_server_by_alias
 
@@ -35,6 +36,14 @@ async def servers_help(message: Message, state=None):
                 ('alias', r'[\w\d]+')
             ])
 async def add_server(message: Message, address, alias, port, state=None):
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Address: {address}\n'
+                        f'Port: {port}\n'
+                        f'Alias: {alias}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        )
+
     await fn_create_server(settings.engine,
                            chat_id=str(message.chat.id),
                            server_address=address,
@@ -57,6 +66,13 @@ async def add_server(message: Message, address, alias, port, state=None):
             ])
 async def rename_server(message: Message, old_alias, new_alias, state=None):
     server = await get_server_by_alias(message, old_alias)
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Old alias: {old_alias}\n'
+                        f'New alias: {new_alias}\n'
+                        f'Server admin: {server.server_admin}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        )
     if server.server_admin != str(message.from_user.id):
         raise Exception(f'You do not have enough permissions to rename this server. \nOnly server admins can do this.')
     await fn_update_server(settings.engine,
@@ -72,7 +88,14 @@ async def rename_server(message: Message, old_alias, new_alias, state=None):
             ])
 async def delete_server(message: Message, server_alias, state=None):
     server = await get_server_by_alias(message, server_alias)
-    if (server.server_admin != str(message.from_user.id) or
+    await debug_message(message,
+                        f'Requested server: {server_alias}\n'
+                        f'Server permission value: {server.server_permissions.value}'
+                        f' ({server.server_permissions.name})\n'
+                        f'Server admin: {server.server_admin}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        )
+    if (server.server_admin != str(message.from_user.id) and
             server.server_permissions.value < ServerPermissions.DELETE.value):
         raise Exception(f'You do not have enough permissions to delete this server. \nOnly server admins can do this.')
 
@@ -100,6 +123,10 @@ async def list_servers(message: Message, state=None):
         servers_list.append(await server_repr(server))
     total_number = len(servers_list)
     servers_list = "\n".join(servers_list)
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Total length: {total_number}\n'
+                        f'Current user: {str(message.from_user.id)}\n')
     await message.reply(
         f'All available servers: \nTotal: {total_number} \n\n{servers_list if servers_list else "No servers available"}'
         , parse_mode=ParseMode.MARKDOWN)
diff --git a/src/actions/stats.py b/src/actions/stats.py
index 0b894864312f2e0799dba2d04b5ffdb3edf13e47..0f9226ccf62db218fd95b65f4543eb43002b0bb4 100644
--- a/src/actions/stats.py
+++ b/src/actions/stats.py
@@ -2,6 +2,7 @@ import logging
 
 from aiogram.types import Message, ParseMode
 
+from src.utils.debug_mode import debug_message
 from src.utils.decorators import bot_action
 from src.utils.server_utils import get_server_by_alias
 from src.utils.ssh import run_ssh_command
@@ -29,6 +30,12 @@ async def cpu_usage(message: Message, alias: str, state=None):
     server = await get_server_by_alias(message, alias)
     cpu_stats = await run_ssh_command(server, "grep 'cpu' /proc/stat")
     cores = cpu_stats.splitlines()
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        f'Server cpu info: \n'
+                        f'{cpu_stats}'
+                        )
 
     def calculate_load(core_stats: str):
         logger.warning(core_stats)
@@ -61,6 +68,12 @@ async def ram_usage(message: Message, alias: str, state=None):
     server = await get_server_by_alias(message, alias)
     ram_stats = await run_ssh_command(server, "free -m")
     table_head, *memories = ram_stats.splitlines()
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        f'Server RAM info: \n'
+                        f'{ram_stats}'
+                        )
 
     def parse_stats(memory_stat: str):
         m_split = memory_stat.split()
@@ -88,6 +101,13 @@ async def mem(message: Message, alias: str, state=None):
     ram_stats = await run_ssh_command(server, "df -hl /")
     table_head, info = ram_stats.splitlines()
     info = info.split()
+    await debug_message(message,
+                        f'Chat id: {message.chat.id}\n'
+                        f'Current user: {str(message.from_user.id)}\n'
+                        f'Server disk info: \n'
+                        f'{ram_stats}'
+                        )
+
     await message.reply(
         '* Current memory usage: *\n\n'
         '```\n'
diff --git a/src/settings.py b/src/settings.py
index d5634def929ec0ffde0e85ebf3364be2396aec5b..aecab7b18e578f2f530d0d4935644d54ca555b8b 100644
--- a/src/settings.py
+++ b/src/settings.py
@@ -45,10 +45,16 @@ class Settings(BaseSettings):
                                default=5432,
                                env='POSTGRES_PORT')
 
+    app_mode: str = Field(name='app_mode',
+                          default='dev',
+                          env='APP_MODE')
+
     engine: Engine = None
 
     dispatcher: Dispatcher = None
 
+    debug_mode: bool = False
+
     @property
     def public_key(self) -> str:
         with open(expanduser('~/.ssh/id_rsa.pub'), 'r') as key:
diff --git a/src/utils/debug_mode.py b/src/utils/debug_mode.py
new file mode 100644
index 0000000000000000000000000000000000000000..6422a73bb01074d6f6b67f75a23f7bc01785d7d9
--- /dev/null
+++ b/src/utils/debug_mode.py
@@ -0,0 +1,28 @@
+import logging
+
+from aiogram.types import Message, ParseMode
+
+from src.settings import settings
+
+logger = logging.getLogger()
+
+
+async def debug_message(message: Message, text: str):
+    """
+    Show to users in chat some useful debug info
+    if debug mode is on.
+    To toggle debug mode just call `meme admin toggle debug`
+
+    :param message:
+    :param text:
+    :return:
+    """
+    logger.debug(text)
+    if settings.debug_mode:
+        await message.reply(
+            "* Debug message: * \n"
+            f"```\n"
+            f"{text}"
+            "```",
+            parse_mode=ParseMode.MARKDOWN
+        )
diff --git a/src/utils/decorators.py b/src/utils/decorators.py
index 023dad8b57cd70d7d6df618901beb71d055b207a..c106b1129aefbd0c2191aade62f2280f747f270e 100644
--- a/src/utils/decorators.py
+++ b/src/utils/decorators.py
@@ -4,7 +4,7 @@ from functools import wraps
 from typing import Callable, List, Tuple
 
 from aiogram.dispatcher.filters.state import State
-from aiogram.types import Message, ParseMode
+from aiogram.types import Message, ParseMode, ReplyKeyboardRemove
 
 from src.settings import settings
 
@@ -12,6 +12,14 @@ logger = logging.getLogger()
 
 
 def cool_response_exception(f: Callable):
+    """
+    Wraps message handler to reply to user with
+    user-friendly message instead of ignoring.
+
+    :param f: wrapped function
+    :return: Any
+    """
+
     @wraps(f)
     async def decorated_func(message: Message, state=None):
         try:
@@ -19,13 +27,26 @@ def cool_response_exception(f: Callable):
             return result
         except Exception as e:
             await message.reply(f"Command cannot be executed, because of the following error: \n```\n{str(e)}```",
-                                parse_mode=ParseMode.MARKDOWN)
+                                parse_mode=ParseMode.MARKDOWN,
+                                reply_markup=ReplyKeyboardRemove())
             logger.exception(e)
 
     return decorated_func
 
 
-def bot_action(trigger_str: str = None, params: List[Tuple] = None, filter_state: State = None):
+def bot_action(trigger_str: str = None, params: List[Tuple] = None, filter_state: State = None) -> Callable:
+    """
+    Mark function as bot message handler.
+    params -> is just an array of tuples.
+    Each value have regex string and name
+
+
+    :param trigger_str: message that triggers bot
+    :param params: parameters in message
+    :param filter_state: trigger state if you use Finite State Machine mechanism
+    :return: decorator
+    """
+
     def decor(f: Callable):
         regexp_params = ' '.join([f'(?P<{name}>{pattern})' for name, pattern in params]) if params else ''
         filter_regexp = f'^{trigger_str} {regexp_params}'.strip()