diff --git a/.gitignore b/.gitignore
index e791976..107042d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@ __pycache__
 *.pyo
 *.pyc
 .env*
+site/
+docs/api/
+docs/src/
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..96b9a5b
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1 @@
+--8<-- "README.md"
diff --git a/mkapi_conf.py b/mkapi_conf.py
new file mode 100644
index 0000000..a8e6b70
--- /dev/null
+++ b/mkapi_conf.py
@@ -0,0 +1,17 @@
+"""Config functions."""
+
+from __future__ import annotations
+
+import sys
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from mkdocs.config.defaults import MkDocsConfig
+
+    from mkapi.plugins import MkAPIPlugin
+
+
+def before_on_config(config: MkDocsConfig, plugin: MkAPIPlugin) -> None:  # noqa: ARG001
+    """Called before `on_config` event of MkAPI plugin."""
+    if "." not in sys.path:
+        sys.path.insert(0, ".")
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..b53c805
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,14 @@
+site_name: pddnsc
+
+theme: material
+markdown_extensions:
+  - pymdownx.snippets
+
+plugins:
+  - search
+  - mkapi:
+      config: mkapi_conf.py
+
+nav:
+  - Home: index.md
+  - Reference: $api/pddnsc.***
diff --git a/pddnsc/__init__.py b/pddnsc/__init__.py
index e69de29..1a311ee 100644
--- a/pddnsc/__init__.py
+++ b/pddnsc/__init__.py
@@ -0,0 +1 @@
+""" Возможно клиент DDNS """
diff --git a/pddnsc/base.py b/pddnsc/base.py
index cd346a2..bf5af7a 100644
--- a/pddnsc/base.py
+++ b/pddnsc/base.py
@@ -5,12 +5,16 @@ from netaddr import valid_ipv4, valid_ipv6
 
 
 class IPAddreses(NamedTuple):
+    """набор из названия источника и IP адресов, результат одного из источников"""
+
     source_name: str
     ipv4: str
     ipv6: str
 
 
 class BaseSourceProvider(ABC):
+    """базовый класс для провайдеров источников"""
+
     _childs = {}
     registred = {}
 
@@ -23,7 +27,9 @@ class BaseSourceProvider(ABC):
         )
         self.post_init()
 
-    def post_init(self): ...
+    def post_init(self):
+        """метод для переопределения пост инициализации"""
+        ...
 
     def __str__(self):
         return f"{self.__class__.__name__}: {self.name}"
@@ -58,13 +64,19 @@ class BaseSourceProvider(ABC):
         cls.registred[name] = provider(name, config, ipv4t, ipv6t)
 
     @abstractmethod
-    async def fetch_v4(self) -> str: ...
+    async def fetch_v4(self) -> str:
+        """необходимый метод для реализации получения ipv4"""
+        ...
 
     @abstractmethod
-    async def fetch_v6(self) -> str: ...
+    async def fetch_v6(self) -> str:
+        """необходимый метод для реализации получения ipv6"""
+        ...
 
 
 class BaseOutputProvider(ABC):
+    """базовый класс для провайдеров вывода"""
+
     _childs = {}
     registred = {}
 
@@ -73,7 +85,9 @@ class BaseOutputProvider(ABC):
         self.ipv4t, self.ipv6t = ipv4t, ipv6t
         self.post_init()
 
-    def post_init(self): ...
+    def post_init(self):
+        """метод для переопределения пост инициализации"""
+        ...
 
     def __init_subclass__(cls) -> None:
         BaseOutputProvider._childs[cls.__name__] = cls
@@ -107,10 +121,14 @@ class BaseOutputProvider(ABC):
         return await self.set_addrs_imp(source_provider, addr_v4, addr_v6)
 
     @abstractmethod
-    async def set_addrs_imp(self, source_provider, addr_v4, addr_v6): ...
+    async def set_addrs_imp(self, source_provider, addr_v4, addr_v6):
+        """необходимый метод для реализации отправки/вывода IP аддресов"""
+        ...
 
 
 class BaseFilterProvider(ABC):
+    """базовый класс для провайдеров фильтров"""
+
     _childs = {}
     registred = {}
 
@@ -119,7 +137,9 @@ class BaseFilterProvider(ABC):
         self.ipv4t, self.ipv6t = ipv4t, ipv6t
         self.post_init()
 
-    def post_init(self): ...
+    def post_init(self):
+        """метод для переопределения пост инициализации"""
+        ...
 
     def __init_subclass__(cls) -> None:
         BaseFilterProvider._childs[cls.__name__] = cls
@@ -153,12 +173,16 @@ class BaseFilterProvider(ABC):
         return await self.check_imp(source_provider, addr_v4, addr_v6)
 
     @abstractmethod
-    async def check_imp(self, source_provider, addr_v4, addr_v6): ...
+    async def check_imp(self, source_provider, addr_v4, addr_v6):
+        """необходимый метод реализации проверки"""
+        ...
 
 
 def filter_ipv4(value: str) -> Optional[str]:
+    """функция для проверки валидности IPv4 адреса, возвращает None если адрес неправильный или пустой"""
     return value and valid_ipv4(value) and value or None
 
 
 def filter_ipv6(value: str) -> Optional[str]:
+    """функция для проверки валидности IPv6 адреса, возвращает None если адрес неправильный или пустой"""
     return value and valid_ipv6(value) and value or None
diff --git a/pddnsc/cli.py b/pddnsc/cli.py
index 6169899..e94274a 100644
--- a/pddnsc/cli.py
+++ b/pddnsc/cli.py
@@ -1,3 +1,5 @@
+""" модуль запуска """
+
 import httpx
 import asyncio
 import toml
diff --git a/pddnsc/filters/__init__.py b/pddnsc/filters/__init__.py
index 6be9257..1d672eb 100644
--- a/pddnsc/filters/__init__.py
+++ b/pddnsc/filters/__init__.py
@@ -1,3 +1,5 @@
+""" Фильтры для проверки адресов перед отправкой """
+
 from pddnsc.loaders import load_plugins
 
 load_plugins(__file__)
diff --git a/pddnsc/loaders.py b/pddnsc/loaders.py
index 00ee9f5..a0cc0e2 100644
--- a/pddnsc/loaders.py
+++ b/pddnsc/loaders.py
@@ -1,3 +1,5 @@
+""" функции загрузки файлов плагинов """
+
 import os
 import traceback
 from importlib import util
diff --git a/pddnsc/outputs/__init__.py b/pddnsc/outputs/__init__.py
index 6be9257..77d0726 100644
--- a/pddnsc/outputs/__init__.py
+++ b/pddnsc/outputs/__init__.py
@@ -1,3 +1,5 @@
+""" Модули вывода """
+
 from pddnsc.loaders import load_plugins
 
 load_plugins(__file__)
diff --git a/pddnsc/plugins.py b/pddnsc/plugins.py
index 8547462..2c26f85 100644
--- a/pddnsc/plugins.py
+++ b/pddnsc/plugins.py
@@ -1,3 +1,5 @@
+""" модуль взаимодействия и регистрации плагинов """
+
 from .base import BaseSourceProvider, BaseFilterProvider, BaseOutputProvider
 from . import sources
 from . import outputs
diff --git a/pddnsc/sources/__init__.py b/pddnsc/sources/__init__.py
index 6be9257..d28d825 100644
--- a/pddnsc/sources/__init__.py
+++ b/pddnsc/sources/__init__.py
@@ -1,3 +1,5 @@
+""" Модули источников IP адресов """
+
 from pddnsc.loaders import load_plugins
 
 load_plugins(__file__)
diff --git a/pddnsc/sources/fake.py b/pddnsc/sources/fake.py
index 3d6a2d9..5856dc5 100644
--- a/pddnsc/sources/fake.py
+++ b/pddnsc/sources/fake.py
@@ -1,9 +1,13 @@
+""" модуль имитации получения IP аддресов """
+
 import asyncio
 
 from pddnsc.base import BaseSourceProvider
 
 
 class DummySource(BaseSourceProvider):
+    """имитация получения пустых адресов"""
+
     async def fetch_v4(self) -> str:
         result = await asyncio.sleep(self.config.get("delay", 1), result=None)
         return result
@@ -14,6 +18,8 @@ class DummySource(BaseSourceProvider):
 
 
 class FakeSource(BaseSourceProvider):
+    """имитация получения заданных в конфигурации адресов"""
+
     async def fetch_v4(self) -> str:
         result = await asyncio.sleep(
             self.config.get("delay", 1), result=self.config.get("ipv4", "127.0.0.1")
diff --git a/pddnsc/sources/http.py b/pddnsc/sources/http.py
index ec65934..8207c6a 100644
--- a/pddnsc/sources/http.py
+++ b/pddnsc/sources/http.py
@@ -4,6 +4,8 @@ from pddnsc.base import BaseSourceProvider, filter_ipv4, filter_ipv6
 
 
 class GenericHttpSource(BaseSourceProvider):
+    """базовый провайдер получения IP адресов по http/https ссылкам в виде текста"""
+
     def post_init(self):
         self.url_v4 = self.config.get("url_v4")
         self.url_v6 = self.config.get("url_v6")
@@ -37,6 +39,8 @@ class GenericHttpSource(BaseSourceProvider):
 
 
 class GenericHttpJsonSource(BaseSourceProvider):
+    """базовый провайдер получения IP адресов по http/https ссылкам в виде json"""
+
     def post_init(self):
         self.url_v4 = self.config.get("url_v4")
         self.url_v6 = self.config.get("url_v6")
diff --git a/pddnsc/sources/ipfy.py b/pddnsc/sources/ipfy.py
index c340761..034bc49 100644
--- a/pddnsc/sources/ipfy.py
+++ b/pddnsc/sources/ipfy.py
@@ -1,8 +1,9 @@
 from pddnsc.sources.http import GenericHttpSource
 
 
-# https://www.ipify.org/
 class IPIFYSource(GenericHttpSource):
+    """https://www.ipify.org/"""
+
     def post_init(self):
         super().post_init()
         self.url_v4 = "https://api4.ipify.org"
diff --git a/pddnsc/sources/ipsb.py b/pddnsc/sources/ipsb.py
index cc78bbe..8cfe862 100644
--- a/pddnsc/sources/ipsb.py
+++ b/pddnsc/sources/ipsb.py
@@ -1,8 +1,9 @@
 from pddnsc.sources.http import GenericHttpSource
 
 
-# https://ip.sb/api
 class IPSB(GenericHttpSource):
+    """https://ip.sb/api"""
+
     def post_init(self):
         super().post_init()
         self.url_v4 = "https://api-ipv4.ip.sb/ip"
diff --git a/pddnsc/sources/wtfismyip.py b/pddnsc/sources/wtfismyip.py
index 9b00765..fa36874 100644
--- a/pddnsc/sources/wtfismyip.py
+++ b/pddnsc/sources/wtfismyip.py
@@ -1,9 +1,12 @@
 from pddnsc.sources.http import GenericHttpSource
 
 
-# https://wtfismyip.com/
-# https://gitlab.com/wtfismyip/wtfismyip
 class WTFIsMyIP(GenericHttpSource):
+    """
+    https://wtfismyip.com/
+    https://gitlab.com/wtfismyip/wtfismyip
+    """
+
     def post_init(self):
         super().post_init()
         self.url_v4 = "https://text.ipv4.myip.wtf"
diff --git a/requirements.docs.txt b/requirements.docs.txt
new file mode 100644
index 0000000..0b32163
--- /dev/null
+++ b/requirements.docs.txt
@@ -0,0 +1,4 @@
+mkdocs>=1.5,<2
+pymdown-extensions>=10.7,<11
+mkapi>=2.1,<3
+mkdocs-material>=9.5.10,<10