diff --git a/src/info.rs b/src/info.rs
index f63201ff786aa318de728b62a6f97b10283d0b97..c5b057c4614b9d7eca85cb6a95ba55b0513672b2 100644
--- a/src/info.rs
+++ b/src/info.rs
@@ -140,3 +140,43 @@ impl crate::rpc::RequestArgs for InstanceInfoRequest {
     const PROC_NAME: &'static str = crate::stringify_cfunc!(proc_instance_info);
     type Response = InstanceInfo;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// RaftInfo
+////////////////////////////////////////////////////////////////////////////////
+
+#[derive(Clone, Debug, ::serde::Serialize, ::serde::Deserialize)]
+pub struct RaftInfo {
+    pub id: RaftId,
+    pub term: RaftTerm,
+    pub applied: RaftIndex,
+    pub leader_id: RaftId,
+    pub state: node::RaftState,
+}
+
+impl tarantool::tuple::Encode for RaftInfo {}
+
+impl RaftInfo {
+    #[inline]
+    pub fn get(node: &node::Node) -> Self {
+        let raft_status = node.status();
+        RaftInfo {
+            id: raft_status.id,
+            term: raft_status.term,
+            applied: node.get_index(),
+            leader_id: raft_status.leader_id.unwrap_or(0),
+            state: raft_status.raft_state,
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// .proc_raft_info
+////////////////////////////////////////////////////////////////////////////////
+
+#[proc]
+pub fn proc_raft_info() -> Result<RaftInfo, Error> {
+    let node = node::global()?;
+
+    Ok(RaftInfo::get(node))
+}
diff --git a/test/int/test_basics.py b/test/int/test_basics.py
index afcf32eba274f9fd0242e18317845e07de436d5a..5dd78ad2682f7edc572e60b3e8b9421e67a1ff86 100644
--- a/test/int/test_basics.py
+++ b/test/int/test_basics.py
@@ -373,3 +373,20 @@ def test_proc_instance_info(cluster: Cluster):
     with pytest.raises(TarantoolError) as e:
         i1.call(".proc_instance_info", "i3")
     assert 'instance with id "i3" not found' in str(e)
+
+
+def test_proc_raft_info(instance: Instance):
+    info = instance.call(".proc_raft_info")
+
+    assert isinstance(info["applied"], int)
+    # This field is super volatile, don't want to be updating it every time we
+    # add a bootstrap entry.
+    info["applied"] = 69
+
+    assert info == dict(
+        id=1,
+        term=2,
+        applied=69,
+        leader_id=1,
+        state="Leader",
+    )
diff --git a/test/int/test_uninitialized.py b/test/int/test_uninitialized.py
index 3b996649faae0f1522f689658697688dc6e0e7a7..a59eaa64ee13c1c46902778c77c0b44751ea67a2 100644
--- a/test/int/test_uninitialized.py
+++ b/test/int/test_uninitialized.py
@@ -31,6 +31,7 @@ def uninitialized_instance(cluster: Cluster) -> Generator[Instance, None, None]:
 def test_raft_api(uninitialized_instance: Instance):
     functions: list[Callable[[Instance], Any]] = [
         lambda i: i._raft_status(),
+        lambda i: i.call(".proc_raft_info"),
         lambda i: i.raft_get_index(),
         lambda i: i.raft_read_index(),
         lambda i: i.raft_wait_index(0),