diff --git a/src/SciSharp.MySQL.Replication/Protocol/CommandPacket.cs b/src/SciSharp.MySQL.Replication/Protocol/CommandPacket.cs
new file mode 100644
index 0000000..5c3b6ca
--- /dev/null
+++ b/src/SciSharp.MySQL.Replication/Protocol/CommandPacket.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SciSharp.MySQL.Replication.Protocol
+{
+    /// 
+    /// Represents a MySQL command packet.
+    /// Reference: https://dev.mysql.com/doc/internals/en/text-protocol.html
+    /// 
+    internal class CommandPacket : MySQLPacket
+    {
+        public MySQLCommand Command { get; set; }
+        public string Query { get; set; }
+        public byte[] Parameters { get; set; }
+
+        public CommandPacket(MySQLCommand command, string query = null, byte[] parameters = null)
+        {
+            Command = command;
+            Query = query;
+            Parameters = parameters;
+        }
+
+        protected override byte[] GetPayload()
+        {
+            var payload = new List();
+
+            // Command byte
+            payload.Add((byte)Command);
+
+            // Query string for COM_QUERY
+            if (Command == MySQLCommand.COM_QUERY && !string.IsNullOrEmpty(Query))
+            {
+                payload.AddRange(Encoding.UTF8.GetBytes(Query));
+            }
+
+            // Parameters for other commands
+            if (Parameters != null)
+            {
+                payload.AddRange(Parameters);
+            }
+
+            return payload.ToArray();
+        }
+    }
+
+    /// 
+    /// MySQL command types.
+    /// Reference: https://dev.mysql.com/doc/internals/en/command-phase.html
+    /// 
+    internal enum MySQLCommand : byte
+    {
+        COM_SLEEP = 0x00,
+        COM_QUIT = 0x01,
+        COM_INIT_DB = 0x02,
+        COM_QUERY = 0x03,
+        COM_FIELD_LIST = 0x04,
+        COM_CREATE_DB = 0x05,
+        COM_DROP_DB = 0x06,
+        COM_REFRESH = 0x07,
+        COM_SHUTDOWN = 0x08,
+        COM_STATISTICS = 0x09,
+        COM_PROCESS_INFO = 0x0A,
+        COM_CONNECT = 0x0B,
+        COM_PROCESS_KILL = 0x0C,
+        COM_DEBUG = 0x0D,
+        COM_PING = 0x0E,
+        COM_TIME = 0x0F,
+        COM_DELAYED_INSERT = 0x10,
+        COM_CHANGE_USER = 0x11,
+        COM_BINLOG_DUMP = 0x12,
+        COM_TABLE_DUMP = 0x13,
+        COM_CONNECT_OUT = 0x14,
+        COM_REGISTER_SLAVE = 0x15,
+        COM_STMT_PREPARE = 0x16,
+        COM_STMT_EXECUTE = 0x17,
+        COM_STMT_SEND_LONG_DATA = 0x18,
+        COM_STMT_CLOSE = 0x19,
+        COM_STMT_RESET = 0x1A,
+        COM_SET_OPTION = 0x1B,
+        COM_STMT_FETCH = 0x1C,
+        COM_DAEMON = 0x1D,
+        COM_BINLOG_DUMP_GTID = 0x1E,
+        COM_RESET_CONNECTION = 0x1F
+    }
+}
\ No newline at end of file
diff --git a/src/SciSharp.MySQL.Replication/Protocol/DirectMySQLConnection.cs b/src/SciSharp.MySQL.Replication/Protocol/DirectMySQLConnection.cs
new file mode 100644
index 0000000..3d30fb2
--- /dev/null
+++ b/src/SciSharp.MySQL.Replication/Protocol/DirectMySQLConnection.cs
@@ -0,0 +1,334 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SciSharp.MySQL.Replication.Protocol
+{
+    /// 
+    /// Direct MySQL connection implementation that handles the protocol without MySql.Data dependency.
+    /// 
+    internal class DirectMySQLConnection : IDisposable
+    {
+        private TcpClient _tcpClient;
+        private NetworkStream _stream;
+        private byte _sequenceId;
+        private bool _isConnected;
+        private string _serverVersion;
+        private uint _connectionId;
+
+        public bool IsConnected => _isConnected;
+        public string ServerVersion => _serverVersion;
+        public uint ConnectionId => _connectionId;
+        public Stream Stream => _stream;
+
+        /// 
+        /// Connects to the MySQL server and performs handshake authentication.
+        /// 
+        public async Task ConnectAsync(string host, int port, string username, string password, string database = null)
+        {
+            if (_isConnected)
+                throw new InvalidOperationException("Connection is already established");
+
+            try
+            {
+                // Parse host and port
+                var parts = host.Split(':');
+                var hostName = parts[0];
+                var portNumber = parts.Length > 1 ? int.Parse(parts[1]) : port;
+
+                // Establish TCP connection
+                _tcpClient = new TcpClient();
+                await _tcpClient.ConnectAsync(hostName, portNumber).ConfigureAwait(false);
+                _stream = _tcpClient.GetStream();
+
+                // Perform handshake
+                await PerformHandshakeAsync(username, password, database).ConfigureAwait(false);
+
+                _isConnected = true;
+            }
+            catch
+            {
+                Dispose();
+                throw;
+            }
+        }
+
+        /// 
+        /// Performs the MySQL handshake protocol.
+        /// 
+        private async Task PerformHandshakeAsync(string username, string password, string database)
+        {
+            // Read initial handshake packet from server
+            var (handshakePayload, sequenceId) = await MySQLPacket.ReadFromStreamAsync(_stream).ConfigureAwait(false);
+            _sequenceId = (byte)(sequenceId + 1);
+
+            // Check for error packet
+            if (handshakePayload[0] == 0xFF)
+            {
+                throw new Exception($"Server error during handshake: {ParseErrorPacket(handshakePayload)}");
+            }
+
+            // Parse handshake packet
+            var handshake = HandshakePacket.Parse(handshakePayload);
+            _serverVersion = handshake.ServerVersion;
+            _connectionId = handshake.ConnectionId;
+
+            // Generate auth response
+            var authResponse = MySQLAuth.MySqlNativePassword(password, handshake.AuthPluginData);
+
+            // Create handshake response
+            var handshakeResponse = new HandshakeResponsePacket(username, authResponse, database, MySQLAuth.MySqlNativePasswordPlugin)
+            {
+                SequenceId = _sequenceId
+            };
+
+            // Send handshake response
+            await handshakeResponse.WriteToStreamAsync(_stream).ConfigureAwait(false);
+            _sequenceId++;
+
+            // Read server response
+            var (responsePayload, responseSequenceId) = await MySQLPacket.ReadFromStreamAsync(_stream).ConfigureAwait(false);
+            _sequenceId = (byte)(responseSequenceId + 1);
+
+            // Check response
+            if (responsePayload[0] == 0xFF)
+            {
+                throw new Exception($"Authentication failed: {ParseErrorPacket(responsePayload)}");
+            }
+            else if (responsePayload[0] == 0x00)
+            {
+                // Success - OK packet
+                return;
+            }
+            else
+            {
+                throw new Exception("Unexpected response during authentication");
+            }
+        }
+
+        /// 
+        /// Executes a SQL query and returns the result set.
+        /// 
+        public async Task ExecuteQueryAsync(string query)
+        {
+            if (!_isConnected)
+                throw new InvalidOperationException("Connection is not established");
+
+            // Reset sequence ID for new command
+            _sequenceId = 0;
+
+            // Send command packet
+            var commandPacket = new CommandPacket(MySQLCommand.COM_QUERY, query)
+            {
+                SequenceId = _sequenceId
+            };
+
+            await commandPacket.WriteToStreamAsync(_stream).ConfigureAwait(false);
+            _sequenceId++;
+
+            // Read response packets
+            var (responsePayload, responseSequenceId) = await MySQLPacket.ReadFromStreamAsync(_stream).ConfigureAwait(false);
+            _sequenceId = (byte)(responseSequenceId + 1);
+
+            // Check for error
+            if (responsePayload[0] == 0xFF)
+            {
+                throw new Exception($"Query failed: {ParseErrorPacket(responsePayload)}");
+            }
+
+            // Check for OK packet (for non-SELECT queries)
+            if (responsePayload[0] == 0x00)
+            {
+                return new MySQLQueryResult { IsSuccess = true };
+            }
+
+            // Parse result set
+            return await ParseResultSetAsync(responsePayload).ConfigureAwait(false);
+        }
+
+        /// 
+        /// Parses a result set from query response.
+        /// 
+        private async Task ParseResultSetAsync(byte[] firstPacket)
+        {
+            var result = new MySQLQueryResult { IsSuccess = true };
+
+            // First packet contains column count
+            var columnCount = firstPacket[0];
+            result.ColumnCount = columnCount;
+
+            // Read column definition packets
+            var columns = new List();
+            for (int i = 0; i < columnCount; i++)
+            {
+                var (columnPayload, sequenceId) = await MySQLPacket.ReadFromStreamAsync(_stream).ConfigureAwait(false);
+                _sequenceId = (byte)(sequenceId + 1);
+
+                var column = ParseColumnDefinition(columnPayload);
+                columns.Add(column);
+            }
+            result.Columns = columns;
+
+            // Read EOF packet after column definitions
+            var (eofPayload, eofSequenceId) = await MySQLPacket.ReadFromStreamAsync(_stream).ConfigureAwait(false);
+            _sequenceId = (byte)(eofSequenceId + 1);
+
+            // Read data rows
+            var rows = new List();
+            while (true)
+            {
+                var (rowPayload, rowSequenceId) = await MySQLPacket.ReadFromStreamAsync(_stream).ConfigureAwait(false);
+                _sequenceId = (byte)(rowSequenceId + 1);
+
+                // Check for EOF packet
+                if (rowPayload[0] == 0xFE && rowPayload.Length < 9)
+                {
+                    break;
+                }
+
+                var row = ParseRow(rowPayload, columnCount);
+                rows.Add(row);
+            }
+            result.Rows = rows;
+
+            return result;
+        }
+
+        /// 
+        /// Parses a column definition packet.
+        /// 
+        private MySQLColumn ParseColumnDefinition(byte[] payload)
+        {
+            var column = new MySQLColumn();
+            int offset = 0;
+
+            // Skip catalog (length-encoded string)
+            offset += ReadLengthEncodedString(payload, offset, out _);
+
+            // Skip schema (length-encoded string)
+            offset += ReadLengthEncodedString(payload, offset, out _);
+
+            // Skip table (length-encoded string)
+            offset += ReadLengthEncodedString(payload, offset, out _);
+
+            // Skip org_table (length-encoded string)
+            offset += ReadLengthEncodedString(payload, offset, out _);
+
+            // Column name (length-encoded string)
+            string columnName;
+            offset += ReadLengthEncodedString(payload, offset, out columnName);
+            column.Name = columnName;
+
+            // Skip org_name (length-encoded string)
+            offset += ReadLengthEncodedString(payload, offset, out _);
+
+            // Skip length of fixed-length fields
+            offset++;
+
+            // Character set (2 bytes)
+            offset += 2;
+
+            // Column length (4 bytes)
+            offset += 4;
+
+            // Column type (1 byte)
+            column.Type = payload[offset];
+
+            return column;
+        }
+
+        /// 
+        /// Parses a data row packet.
+        /// 
+        private MySQLRow ParseRow(byte[] payload, int columnCount)
+        {
+            var row = new MySQLRow();
+            var values = new string[columnCount];
+            int offset = 0;
+
+            for (int i = 0; i < columnCount; i++)
+            {
+                offset += ReadLengthEncodedString(payload, offset, out values[i]);
+            }
+
+            row.Values = values;
+            return row;
+        }
+
+        /// 
+        /// Reads a length-encoded string from the payload.
+        /// 
+        private int ReadLengthEncodedString(byte[] payload, int offset, out string value)
+        {
+            if (payload[offset] == 0xFB)
+            {
+                // NULL value
+                value = null;
+                return 1;
+            }
+
+            var length = payload[offset];
+            if (length < 0xFB)
+            {
+                // Single byte length
+                value = Encoding.UTF8.GetString(payload, offset + 1, length);
+                return 1 + length;
+            }
+
+            // Multi-byte length (not implemented for simplicity)
+            throw new NotImplementedException("Multi-byte length-encoded strings not implemented");
+        }
+
+        /// 
+        /// Parses an error packet.
+        /// 
+        private string ParseErrorPacket(byte[] payload)
+        {
+            if (payload.Length < 3)
+                return "Unknown error";
+
+            var errorCode = BitConverter.ToUInt16(payload, 1);
+            var message = Encoding.UTF8.GetString(payload, 3, payload.Length - 3);
+            return $"Error {errorCode}: {message}";
+        }
+
+        public void Dispose()
+        {
+            _isConnected = false;
+            _stream?.Dispose();
+            _tcpClient?.Dispose();
+        }
+    }
+
+    /// 
+    /// Represents the result of a MySQL query.
+    /// 
+    internal class MySQLQueryResult
+    {
+        public bool IsSuccess { get; set; }
+        public int ColumnCount { get; set; }
+        public List Columns { get; set; }
+        public List Rows { get; set; }
+    }
+
+    /// 
+    /// Represents a MySQL column definition.
+    /// 
+    internal class MySQLColumn
+    {
+        public string Name { get; set; }
+        public byte Type { get; set; }
+    }
+
+    /// 
+    /// Represents a MySQL data row.
+    /// 
+    internal class MySQLRow
+    {
+        public string[] Values { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/src/SciSharp.MySQL.Replication/Protocol/HandshakePacket.cs b/src/SciSharp.MySQL.Replication/Protocol/HandshakePacket.cs
new file mode 100644
index 0000000..f541d38
--- /dev/null
+++ b/src/SciSharp.MySQL.Replication/Protocol/HandshakePacket.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Text;
+
+namespace SciSharp.MySQL.Replication.Protocol
+{
+    /// 
+    /// Represents the initial handshake packet sent by the MySQL server.
+    /// Reference: https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
+    /// 
+    internal class HandshakePacket
+    {
+        public byte ProtocolVersion { get; set; }
+        public string ServerVersion { get; set; }
+        public uint ConnectionId { get; set; }
+        public byte[] AuthPluginDataPart1 { get; set; } // 8 bytes
+        public uint CapabilityFlagsLower { get; set; } // lower 16 bits
+        public byte CharacterSet { get; set; }
+        public ushort StatusFlags { get; set; }
+        public uint CapabilityFlagsUpper { get; set; } // upper 16 bits
+        public byte AuthPluginDataLength { get; set; }
+        public byte[] AuthPluginDataPart2 { get; set; } // max 13 bytes (total auth_plugin_data is 21 bytes)
+        public string AuthPluginName { get; set; }
+
+        /// 
+        /// Gets the combined capability flags (lower 16 bits + upper 16 bits).
+        /// 
+        public uint CapabilityFlags => CapabilityFlagsLower | (CapabilityFlagsUpper << 16);
+
+        /// 
+        /// Gets the complete authentication plugin data (part1 + part2).
+        /// 
+        public byte[] AuthPluginData
+        {
+            get
+            {
+                var result = new byte[20]; // MySQL uses 20 bytes for auth data
+                Array.Copy(AuthPluginDataPart1, 0, result, 0, 8);
+                if (AuthPluginDataPart2 != null)
+                {
+                    var copyLength = Math.Min(AuthPluginDataPart2.Length, 12);
+                    Array.Copy(AuthPluginDataPart2, 0, result, 8, copyLength);
+                }
+                return result;
+            }
+        }
+
+        /// 
+        /// Parses a handshake packet from raw bytes.
+        /// 
+        public static HandshakePacket Parse(byte[] payload)
+        {
+            var packet = new HandshakePacket();
+            int offset = 0;
+
+            // Protocol version (1 byte)
+            packet.ProtocolVersion = payload[offset++];
+
+            // Server version (null-terminated string)
+            var serverVersionEnd = Array.IndexOf(payload, (byte)0, offset);
+            packet.ServerVersion = Encoding.UTF8.GetString(payload, offset, serverVersionEnd - offset);
+            offset = serverVersionEnd + 1;
+
+            // Connection ID (4 bytes)
+            packet.ConnectionId = BitConverter.ToUInt32(payload, offset);
+            offset += 4;
+
+            // Auth plugin data part 1 (8 bytes)
+            packet.AuthPluginDataPart1 = new byte[8];
+            Array.Copy(payload, offset, packet.AuthPluginDataPart1, 0, 8);
+            offset += 8;
+
+            // Filter (1 byte) - always 0x00
+            offset++;
+
+            // Capability flags lower 16 bits (2 bytes)
+            packet.CapabilityFlagsLower = BitConverter.ToUInt16(payload, offset);
+            offset += 2;
+
+            // Character set (1 byte)
+            packet.CharacterSet = payload[offset++];
+
+            // Status flags (2 bytes)
+            packet.StatusFlags = BitConverter.ToUInt16(payload, offset);
+            offset += 2;
+
+            // Capability flags upper 16 bits (2 bytes)
+            packet.CapabilityFlagsUpper = BitConverter.ToUInt16(payload, offset);
+            offset += 2;
+
+            // Auth plugin data length (1 byte)
+            packet.AuthPluginDataLength = payload[offset++];
+
+            // Reserved (10 bytes) - skip
+            offset += 10;
+
+            // Auth plugin data part 2 (max 13 bytes, but actual length is auth_plugin_data_len - 8)
+            if (packet.AuthPluginDataLength > 8)
+            {
+                var part2Length = Math.Min(packet.AuthPluginDataLength - 8, 13);
+                packet.AuthPluginDataPart2 = new byte[part2Length];
+                Array.Copy(payload, offset, packet.AuthPluginDataPart2, 0, part2Length);
+                offset += part2Length;
+            }
+
+            // Auth plugin name (null-terminated string) - if CLIENT_PLUGIN_AUTH capability is set
+            if ((packet.CapabilityFlags & (uint)ClientCapabilities.CLIENT_PLUGIN_AUTH) != 0)
+            {
+                var authPluginNameEnd = Array.IndexOf(payload, (byte)0, offset);
+                if (authPluginNameEnd > offset)
+                {
+                    packet.AuthPluginName = Encoding.UTF8.GetString(payload, offset, authPluginNameEnd - offset);
+                }
+            }
+
+            return packet;
+        }
+    }
+
+    /// 
+    /// Client capability flags used in the handshake.
+    /// Reference: https://dev.mysql.com/doc/internals/en/capability-flags.html
+    /// 
+    [Flags]
+    internal enum ClientCapabilities : uint
+    {
+        CLIENT_LONG_PASSWORD = 0x00000001,
+        CLIENT_FOUND_ROWS = 0x00000002,
+        CLIENT_LONG_FLAG = 0x00000004,
+        CLIENT_CONNECT_WITH_DB = 0x00000008,
+        CLIENT_NO_SCHEMA = 0x00000010,
+        CLIENT_COMPRESS = 0x00000020,
+        CLIENT_ODBC = 0x00000040,
+        CLIENT_LOCAL_FILES = 0x00000080,
+        CLIENT_IGNORE_SPACE = 0x00000100,
+        CLIENT_PROTOCOL_41 = 0x00000200,
+        CLIENT_INTERACTIVE = 0x00000400,
+        CLIENT_SSL = 0x00000800,
+        CLIENT_IGNORE_SIGPIPE = 0x00001000,
+        CLIENT_TRANSACTIONS = 0x00002000,
+        CLIENT_RESERVED = 0x00004000,
+        CLIENT_SECURE_CONNECTION = 0x00008000,
+        CLIENT_MULTI_STATEMENTS = 0x00010000,
+        CLIENT_MULTI_RESULTS = 0x00020000,
+        CLIENT_PS_MULTI_RESULTS = 0x00040000,
+        CLIENT_PLUGIN_AUTH = 0x00080000,
+        CLIENT_CONNECT_ATTRS = 0x00100000,
+        CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000,
+        CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000,
+        CLIENT_SESSION_TRACK = 0x00800000,
+        CLIENT_DEPRECATE_EOF = 0x01000000
+    }
+}
\ No newline at end of file
diff --git a/src/SciSharp.MySQL.Replication/Protocol/HandshakeResponsePacket.cs b/src/SciSharp.MySQL.Replication/Protocol/HandshakeResponsePacket.cs
new file mode 100644
index 0000000..370a050
--- /dev/null
+++ b/src/SciSharp.MySQL.Replication/Protocol/HandshakeResponsePacket.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SciSharp.MySQL.Replication.Protocol
+{
+    /// 
+    /// Represents the handshake response packet sent by the client.
+    /// Reference: https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
+    /// 
+    internal class HandshakeResponsePacket : MySQLPacket
+    {
+        public uint CapabilityFlags { get; set; }
+        public uint MaxPacketSize { get; set; }
+        public byte CharacterSet { get; set; }
+        public string Username { get; set; }
+        public byte[] AuthResponse { get; set; }
+        public string Database { get; set; }
+        public string AuthPluginName { get; set; }
+
+        public HandshakeResponsePacket(string username, byte[] authResponse, string database = null, string authPluginName = "mysql_native_password")
+        {
+            Username = username ?? throw new ArgumentNullException(nameof(username));
+            AuthResponse = authResponse ?? throw new ArgumentNullException(nameof(authResponse));
+            Database = database;
+            AuthPluginName = authPluginName;
+            
+            // Set default capability flags for replication client
+            CapabilityFlags = (uint)(
+                ClientCapabilities.CLIENT_PROTOCOL_41 |
+                ClientCapabilities.CLIENT_SECURE_CONNECTION |
+                ClientCapabilities.CLIENT_LONG_PASSWORD |
+                ClientCapabilities.CLIENT_TRANSACTIONS |
+                ClientCapabilities.CLIENT_PLUGIN_AUTH |
+                ClientCapabilities.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
+            );
+            
+            if (!string.IsNullOrEmpty(database))
+            {
+                CapabilityFlags |= (uint)ClientCapabilities.CLIENT_CONNECT_WITH_DB;
+            }
+            
+            MaxPacketSize = 0x01000000; // 16MB
+            CharacterSet = 8; // latin1_swedish_ci
+        }
+
+        protected override byte[] GetPayload()
+        {
+            var payload = new List();
+
+            // Capability flags (4 bytes)
+            payload.AddRange(BitConverter.GetBytes(CapabilityFlags));
+
+            // Max packet size (4 bytes)
+            payload.AddRange(BitConverter.GetBytes(MaxPacketSize));
+
+            // Character set (1 byte)
+            payload.Add(CharacterSet);
+
+            // Reserved (23 bytes of zeros)
+            payload.AddRange(new byte[23]);
+
+            // Username (null-terminated string)
+            payload.AddRange(Encoding.UTF8.GetBytes(Username));
+            payload.Add(0);
+
+            // Auth response
+            if ((CapabilityFlags & (uint)ClientCapabilities.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) != 0)
+            {
+                // Length-encoded auth response
+                payload.Add((byte)AuthResponse.Length);
+                payload.AddRange(AuthResponse);
+            }
+            else if ((CapabilityFlags & (uint)ClientCapabilities.CLIENT_SECURE_CONNECTION) != 0)
+            {
+                // Length-prefixed auth response
+                payload.Add((byte)AuthResponse.Length);
+                payload.AddRange(AuthResponse);
+            }
+            else
+            {
+                // Null-terminated auth response
+                payload.AddRange(AuthResponse);
+                payload.Add(0);
+            }
+
+            // Database (null-terminated string) - if CLIENT_CONNECT_WITH_DB is set
+            if ((CapabilityFlags & (uint)ClientCapabilities.CLIENT_CONNECT_WITH_DB) != 0 && !string.IsNullOrEmpty(Database))
+            {
+                payload.AddRange(Encoding.UTF8.GetBytes(Database));
+                payload.Add(0);
+            }
+
+            // Auth plugin name (null-terminated string) - if CLIENT_PLUGIN_AUTH is set
+            if ((CapabilityFlags & (uint)ClientCapabilities.CLIENT_PLUGIN_AUTH) != 0 && !string.IsNullOrEmpty(AuthPluginName))
+            {
+                payload.AddRange(Encoding.UTF8.GetBytes(AuthPluginName));
+                payload.Add(0);
+            }
+
+            return payload.ToArray();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/SciSharp.MySQL.Replication/Protocol/MySQLAuth.cs b/src/SciSharp.MySQL.Replication/Protocol/MySQLAuth.cs
new file mode 100644
index 0000000..4847959
--- /dev/null
+++ b/src/SciSharp.MySQL.Replication/Protocol/MySQLAuth.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace SciSharp.MySQL.Replication.Protocol
+{
+    /// 
+    /// Implements MySQL authentication mechanisms.
+    /// 
+    internal static class MySQLAuth
+    {
+        /// 
+        /// Implements the mysql_native_password authentication method.
+        /// Formula: SHA1(password) XOR SHA1(scramble + SHA1(SHA1(password)))
+        /// Reference: https://dev.mysql.com/doc/internals/en/secure-password-authentication.html
+        /// 
+        public static byte[] MySqlNativePassword(string password, byte[] scramble)
+        {
+            if (string.IsNullOrEmpty(password))
+                return new byte[0];
+
+            if (scramble == null || scramble.Length < 20)
+                throw new ArgumentException("Scramble must be at least 20 bytes", nameof(scramble));
+
+            using (var sha1 = SHA1.Create())
+            {
+                // Step 1: SHA1(password)
+                var passwordBytes = Encoding.UTF8.GetBytes(password);
+                var sha1Password = sha1.ComputeHash(passwordBytes);
+
+                // Step 2: SHA1(SHA1(password))
+                var sha1Sha1Password = sha1.ComputeHash(sha1Password);
+
+                // Step 3: scramble + SHA1(SHA1(password))
+                var scrambleAndHash = new byte[20 + sha1Sha1Password.Length];
+                Array.Copy(scramble, 0, scrambleAndHash, 0, 20);
+                Array.Copy(sha1Sha1Password, 0, scrambleAndHash, 20, sha1Sha1Password.Length);
+
+                // Step 4: SHA1(scramble + SHA1(SHA1(password)))
+                var sha1ScrambleAndHash = sha1.ComputeHash(scrambleAndHash);
+
+                // Step 5: SHA1(password) XOR SHA1(scramble + SHA1(SHA1(password)))
+                var result = new byte[20];
+                for (int i = 0; i < 20; i++)
+                {
+                    result[i] = (byte)(sha1Password[i] ^ sha1ScrambleAndHash[i]);
+                }
+
+                return result;
+            }
+        }
+
+        /// 
+        /// Gets the auth plugin name for mysql_native_password.
+        /// 
+        public const string MySqlNativePasswordPlugin = "mysql_native_password";
+    }
+}
\ No newline at end of file
diff --git a/src/SciSharp.MySQL.Replication/Protocol/MySQLPacket.cs b/src/SciSharp.MySQL.Replication/Protocol/MySQLPacket.cs
new file mode 100644
index 0000000..fba72b1
--- /dev/null
+++ b/src/SciSharp.MySQL.Replication/Protocol/MySQLPacket.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Buffers.Binary;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace SciSharp.MySQL.Replication.Protocol
+{
+    /// 
+    /// Base class for MySQL protocol packets.
+    /// MySQL protocol packet format: [3 bytes length][1 byte sequence_id][payload]
+    /// 
+    internal abstract class MySQLPacket
+    {
+        public byte SequenceId { get; set; }
+
+        /// 
+        /// Writes the packet to a stream.
+        /// 
+        public async Task WriteToStreamAsync(Stream stream)
+        {
+            var payload = GetPayload();
+            var length = payload.Length;
+
+            // Write packet header (3 bytes length + 1 byte sequence_id)
+            var header = new byte[4];
+            header[0] = (byte)(length & 0xFF);
+            header[1] = (byte)((length >> 8) & 0xFF);
+            header[2] = (byte)((length >> 16) & 0xFF);
+            header[3] = SequenceId;
+
+            await stream.WriteAsync(header).ConfigureAwait(false);
+            await stream.WriteAsync(payload).ConfigureAwait(false);
+            await stream.FlushAsync().ConfigureAwait(false);
+        }
+
+        /// 
+        /// Reads a packet from a stream.
+        /// 
+        public static async Task<(byte[] payload, byte sequenceId)> ReadFromStreamAsync(Stream stream)
+        {
+            // Read packet header
+            var header = new byte[4];
+            await ReadExactlyAsync(stream, header, 4).ConfigureAwait(false);
+
+            var length = header[0] | (header[1] << 8) | (header[2] << 16);
+            var sequenceId = header[3];
+
+            // Read payload
+            var payload = new byte[length];
+            await ReadExactlyAsync(stream, payload, length).ConfigureAwait(false);
+
+            return (payload, sequenceId);
+        }
+
+        /// 
+        /// Helper method to read exactly the specified number of bytes.
+        /// 
+        private static async Task ReadExactlyAsync(Stream stream, byte[] buffer, int count)
+        {
+            int totalBytesRead = 0;
+            while (totalBytesRead < count)
+            {
+                int bytesRead = await stream.ReadAsync(buffer, totalBytesRead, count - totalBytesRead).ConfigureAwait(false);
+                if (bytesRead == 0)
+                    throw new EndOfStreamException("Unexpected end of stream while reading MySQL packet");
+                totalBytesRead += bytesRead;
+            }
+        }
+
+        /// 
+        /// Gets the payload bytes for this packet.
+        /// 
+        protected abstract byte[] GetPayload();
+    }
+}
\ No newline at end of file
diff --git a/src/SciSharp.MySQL.Replication/ReplicationClient.cs b/src/SciSharp.MySQL.Replication/ReplicationClient.cs
index ae754a2..288442d 100644
--- a/src/SciSharp.MySQL.Replication/ReplicationClient.cs
+++ b/src/SciSharp.MySQL.Replication/ReplicationClient.cs
@@ -7,8 +7,8 @@
 using System.Reflection;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
-using MySql.Data.MySqlClient;
 using SciSharp.MySQL.Replication.Events;
+using SciSharp.MySQL.Replication.Protocol;
 using SuperSocket.Client;
 using SuperSocket.Connection;
 
@@ -28,7 +28,7 @@ public class ReplicationClient : EasyClient, IReplicationClient, IAsyn
 
         private const int BINLOG_SEND_ANNOTATE_ROWS_EVENT = 2;
 
-        private MySqlConnection _connection;
+        private DirectMySQLConnection _connection;
 
         private int _serverId;
 
@@ -96,20 +96,7 @@ private ReplicationClient(LogEventPipelineFilter logEventPipelineFilter)
             _tableSchemaMap = (logEventPipelineFilter.Context as ReplicationState).TableSchemaMap;
         }
 
-        /// 
-        /// Gets the underlying stream from a MySQL connection.
-        /// 
-        /// The MySQL connection.
-        /// The stream associated with the connection.
-        private Stream GetStreamFromMySQLConnection(MySqlConnection connection)
-        {
-            var driverField = connection.GetType().GetField("driver", BindingFlags.Instance | BindingFlags.NonPublic);
-            var driver = driverField.GetValue(connection);
-            var handlerField = driver.GetType().GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
-            var handler = handlerField.GetValue(driver);
-            var baseStreamField = handler.GetType().GetField("baseStream", BindingFlags.Instance | BindingFlags.NonPublic);
-            return baseStreamField.GetValue(handler) as Stream;
-        }
+
 
         /// 
         /// Connects to a MySQL server as a replication client.
@@ -152,12 +139,11 @@ public async Task ConnectAsync(string server, string username, stri
         /// A task representing the asynchronous operation, with a result indicating whether the login was successful.
         private async Task ConnectInternalAsync(string server, string username, string password, int serverId, BinlogPosition binlogPosition)
         {
-            var connString = $"Server={server}; UID={username}; Password={password}";
-            var mysqlConn = new MySqlConnection(connString);
+            var directConn = new DirectMySQLConnection();
 
             try
             {
-                await mysqlConn.OpenAsync().ConfigureAwait(false);
+                await directConn.ConnectAsync(server, 3306, username, password).ConfigureAwait(false);
             }
             catch (Exception e)
             {
@@ -171,27 +157,27 @@ private async Task ConnectInternalAsync(string server, string usern
             try
             {
                 // Load database schema using the established connection
-                await LoadDatabaseSchemaAsync(mysqlConn).ConfigureAwait(false);
+                await LoadDatabaseSchemaAsync(directConn).ConfigureAwait(false);
 
                 // If no binlog position was provided, get the current position from the server
                 if (binlogPosition == null)
                 {
-                    binlogPosition = await GetBinlogFileNameAndPosition(mysqlConn).ConfigureAwait(false);
+                    binlogPosition = await GetBinlogFileNameAndPosition(directConn).ConfigureAwait(false);
                 }
                 
                 // Set up checksum verification
-                var binlogChecksum = await GetBinlogChecksum(mysqlConn).ConfigureAwait(false);
-                await ConfirmChecksum(mysqlConn).ConfigureAwait(false);
+                var binlogChecksum = await GetBinlogChecksum(directConn).ConfigureAwait(false);
+                await ConfirmChecksum(directConn).ConfigureAwait(false);
                 LogEvent.ChecksumType = binlogChecksum;
 
                 // Get the underlying stream and start the binlog dump
-                _stream = GetStreamFromMySQLConnection(mysqlConn);
+                _stream = directConn.Stream;
                 _serverId = serverId;
                 _currentPosition = new BinlogPosition(binlogPosition);
 
                 await StartDumpBinlog(_stream, serverId, binlogPosition.Filename, binlogPosition.Position).ConfigureAwait(false);
 
-                _connection = mysqlConn;
+                _connection = directConn;
 
                 // Create a connection for the event stream
                 var connection = new StreamPipeConnection(
@@ -210,7 +196,7 @@ private async Task ConnectInternalAsync(string server, string usern
             }
             catch (Exception e)
             {
-                await mysqlConn.CloseAsync().ConfigureAwait(false);
+                directConn.Dispose();
                 
                 return new LoginResult
                 {
@@ -267,30 +253,32 @@ private void TrackBinlogPosition(LogEvent logEvent)
             }
         }
 
-        private async Task LoadDatabaseSchemaAsync(MySqlConnection mysqlConn)
+        private async Task LoadDatabaseSchemaAsync(DirectMySQLConnection directConn)
         {
-            var tableSchemaTable = await mysqlConn.GetSchemaAsync("Columns").ConfigureAwait(false);
-
-            var systemDatabases = new HashSet(
-                new [] { "mysql", "information_schema", "performance_schema", "sys" },
-                StringComparer.OrdinalIgnoreCase);
-
-            var userDatabaseColumns = tableSchemaTable.Rows.OfType()
-                .Where(row => !systemDatabases.Contains(row.ItemArray[1].ToString()))
-                .ToArray();
+            var query = @"SELECT 
+                            TABLE_SCHEMA,
+                            TABLE_NAME,
+                            COLUMN_NAME,
+                            DATA_TYPE,
+                            CHARACTER_MAXIMUM_LENGTH
+                          FROM information_schema.COLUMNS
+                          WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')";
+
+            var result = await directConn.ExecuteQueryAsync(query).ConfigureAwait(false);
+            
+            if (!result.IsSuccess || result.Rows == null)
+                return;
 
-            userDatabaseColumns.Select(row =>
-                {
-                    var columnSizeCell = row["CHARACTER_MAXIMUM_LENGTH"];
-                
-                    return new {
-                        TableName = row["TABLE_NAME"].ToString(),
-                        DatabaseName = row["TABLE_SCHEMA"].ToString(),
-                        ColumnName = row["COLUMN_NAME"].ToString(),
-                        ColumnType = row["DATA_TYPE"].ToString(),
-                        ColumnSize = columnSizeCell == DBNull.Value ? 0 : Convert.ToUInt64(columnSizeCell),
-                    };
-                })
+            var userDatabaseColumns = result.Rows.Select(row => new
+            {
+                TableName = row.Values[1],
+                DatabaseName = row.Values[0],
+                ColumnName = row.Values[2],
+                ColumnType = row.Values[3],
+                ColumnSize = string.IsNullOrEmpty(row.Values[4]) ? 0UL : Convert.ToUInt64(row.Values[4])
+            }).ToArray();
+
+            userDatabaseColumns
                 .GroupBy(row => new { row.TableName, row.DatabaseName })
                 .ToList()
                 .ForEach(group =>
@@ -315,59 +303,46 @@ private async Task LoadDatabaseSchemaAsync(MySqlConnection mysqlConn)
         /// Retrieves the binary log file name and position from the MySQL server.
         /// https://dev.mysql.com/doc/refman/5.6/en/replication-howto-masterstatus.html
         /// 
-        /// The MySQL connection.
+        /// The direct MySQL connection.
         /// A tuple containing the binary log file name and position.
-        private async Task GetBinlogFileNameAndPosition(MySqlConnection mysqlConn)
+        private async Task GetBinlogFileNameAndPosition(DirectMySQLConnection directConn)
         {
-            var cmd = mysqlConn.CreateCommand();
-            cmd.CommandText = "SHOW MASTER STATUS;";
+            var result = await directConn.ExecuteQueryAsync("SHOW MASTER STATUS").ConfigureAwait(false);
             
-            using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
-            {
-                if (!await reader.ReadAsync())
-                    throw new Exception("No binlog information has been returned.");
-
-                var fileName = reader.GetString(0);
-                var position = reader.GetInt32(1);
+            if (!result.IsSuccess || result.Rows == null || result.Rows.Count == 0)
+                throw new Exception("No binlog information has been returned.");
 
-                await reader.CloseAsync().ConfigureAwait(false);
+            var firstRow = result.Rows[0];
+            var fileName = firstRow.Values[0];
+            var position = int.Parse(firstRow.Values[1]);
 
-                return new BinlogPosition(fileName, position);
-            }
+            return new BinlogPosition(fileName, position);
         }
 
         /// 
         /// Retrieves the binary log checksum type from the MySQL server.
         /// 
-        /// The MySQL connection.
+        /// The direct MySQL connection.
         /// The checksum type.
-        private async Task GetBinlogChecksum(MySqlConnection mysqlConn)
+        private async Task GetBinlogChecksum(DirectMySQLConnection directConn)
         {
-            var cmd = mysqlConn.CreateCommand();
-            cmd.CommandText = "show global variables like 'binlog_checksum';";
+            var result = await directConn.ExecuteQueryAsync("show global variables like 'binlog_checksum'").ConfigureAwait(false);
             
-            using (var reader = await cmd.ExecuteReaderAsync())
-            {
-                if (!await reader.ReadAsync().ConfigureAwait(false))
-                    return ChecksumType.NONE;
+            if (!result.IsSuccess || result.Rows == null || result.Rows.Count == 0)
+                return ChecksumType.NONE;
 
-                var checksumTypeName = reader.GetString(1).ToUpper();
-                await reader.CloseAsync().ConfigureAwait(false);
-
-                return (ChecksumType)Enum.Parse(typeof(ChecksumType), checksumTypeName);
-            }
+            var checksumTypeName = result.Rows[0].Values[1].ToUpper();
+            return (ChecksumType)Enum.Parse(typeof(ChecksumType), checksumTypeName);
         }
         
         /// 
         /// Confirms the binary log checksum setting on the MySQL server.
         /// 
-        /// The MySQL connection.
+        /// The direct MySQL connection.
         /// A task representing the asynchronous operation.
-        private async ValueTask ConfirmChecksum(MySqlConnection mysqlConn)
+        private async ValueTask ConfirmChecksum(DirectMySQLConnection directConn)
         {
-            var cmd = mysqlConn.CreateCommand();
-            cmd.CommandText = "set @`master_binlog_checksum` = @@binlog_checksum;";        
-            await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
+            await directConn.ExecuteQueryAsync("set @`master_binlog_checksum` = @@binlog_checksum").ConfigureAwait(false);
         }
 
         /// 
@@ -490,7 +465,7 @@ public override async ValueTask CloseAsync()
             if (connection != null)
             {
                 _connection = null;
-                await connection.CloseAsync().ConfigureAwait(false);
+                connection.Dispose();
             }
 
             await base.CloseAsync().ConfigureAwait(false);
diff --git a/src/SciSharp.MySQL.Replication/SciSharp.MySQL.Replication.csproj b/src/SciSharp.MySQL.Replication/SciSharp.MySQL.Replication.csproj
index a014509..b61b2fd 100644
--- a/src/SciSharp.MySQL.Replication/SciSharp.MySQL.Replication.csproj
+++ b/src/SciSharp.MySQL.Replication/SciSharp.MySQL.Replication.csproj
@@ -1,6 +1,6 @@
 
   
-    net6.0;net7.0;net8.0;net9.0
+    net6.0;net7.0;net8.0
     12.0
     true
   
@@ -24,7 +24,6 @@
     
   
   
-    
     
     
   
diff --git a/tests/Test/DirectConnectionTest.cs b/tests/Test/DirectConnectionTest.cs
new file mode 100644
index 0000000..58857c9
--- /dev/null
+++ b/tests/Test/DirectConnectionTest.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Threading.Tasks;
+using SciSharp.MySQL.Replication;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Test
+{
+    [Trait("Category", "DirectConnection")]
+    public class DirectConnectionTest
+    {
+        protected readonly ITestOutputHelper _outputHelper;
+
+        public DirectConnectionTest(ITestOutputHelper outputHelper)
+        {
+            _outputHelper = outputHelper;
+        }
+        
+        [Fact]
+        public async Task TestReplicationClientWithDirectConnection()
+        {
+            var client = new ReplicationClient();
+            
+            try
+            {
+                // Test connection using the new implementation
+                var result = await client.ConnectAsync("localhost", "root", "root", 1001);
+                
+                Assert.True(result.Result, $"Connection failed: {result.Message}");
+                _outputHelper.WriteLine($"ReplicationClient connected successfully using direct MySQL protocol");
+                _outputHelper.WriteLine($"Connection result message: {result.Message ?? "Success"}");
+                
+                // Verify current position is available
+                Assert.NotNull(client.CurrentPosition);
+                _outputHelper.WriteLine($"Current binlog position: {client.CurrentPosition.Filename}:{client.CurrentPosition.Position}");
+                
+                _outputHelper.WriteLine("Direct MySQL protocol implementation is working correctly!");
+            }
+            catch (Exception ex)
+            {
+                _outputHelper.WriteLine($"Test failed with exception: {ex.Message}");
+                _outputHelper.WriteLine($"Stack trace: {ex.StackTrace}");
+                throw;
+            }
+            finally
+            {
+                await client.CloseAsync();
+            }
+        }
+    }
+}
diff --git a/tests/Test/Test.csproj b/tests/Test/Test.csproj
index cfc4ee1..aff0f71 100644
--- a/tests/Test/Test.csproj
+++ b/tests/Test/Test.csproj
@@ -1,7 +1,7 @@
 
 
   
-    net9.0
+    net8.0
     false
   
 
@@ -11,6 +11,7 @@
     
     
     
+