diff --git a/src/color_ssh/__init__.py b/src/color_ssh/__init__.py
index df9144c..10939f0 100644
--- a/src/color_ssh/__init__.py
+++ b/src/color_ssh/__init__.py
@@ -1,1 +1,1 @@
-__version__ = '0.1.1'
+__version__ = '0.1.2'
diff --git a/src/color_ssh/color_ssh.py b/src/color_ssh/color_ssh.py
index 1d2e798..e575962 100644
--- a/src/color_ssh/color_ssh.py
+++ b/src/color_ssh/color_ssh.py
@@ -4,6 +4,7 @@ import sys
 import io
 import shlex
 import subprocess
+import re
 from optparse import OptionParser
 from multiprocessing.pool import Pool
 from color_ssh.util.util import *
@@ -64,20 +65,25 @@ class Setting(object):
             stdout.write(arg2bytes(parser.format_help().encode('utf-8')))
             parser.exit(2)
 
-        prefix = shlex.split(option.ssh)
-
         if not hosts:
             hosts = args[:1]
             del args[0]
 
-        # distribute args
+        # parse hosts
+        parsed_hosts = [self._parse_host(h) for h in hosts]
+
+        tasks = []
         if option.distribute:
+            # distribute args
             dist_prefix = shlex.split(option.distribute)
             d = distribute(len(hosts), args)
-            tasks = [(option.label or self._extract_label(host),
-                      prefix + [host] + dist_prefix + d[i]) for i, host in enumerate(hosts) if d[i]]
+            for i, (user, host, port) in enumerate(parsed_hosts):
+                if d[i]:
+                    label = option.label or host
+                    tasks.append((label, self._ssh_args(option.ssh, user, host, port) + dist_prefix + d[i]))
         else:
-            tasks = [(option.label or self._extract_label(host), prefix + [host] + args) for host in hosts]
+            for user, host, port in parsed_hosts:
+                tasks.append((option.label or host, self._ssh_args(option.ssh, user, host, port) + args))
 
         self.parallelism = option.parallelism
         self.tasks = tasks
@@ -93,8 +99,20 @@ class Setting(object):
         return list(filter(lambda x: x, (line.strip() for line in lines)))
 
     @staticmethod
-    def _extract_label(host):
-        return host.rsplit('@', 1)[-1]
+    def _parse_host(s):
+        """
+        :param s: string : [user@]host[:port]
+        :return: tuple of (user, host, port)
+        """
+        ret = re.match('^(?:([^:@]+)@)?([^:@]+)(?::(\d+))?$', s)
+        if not ret:
+            raise ValueError('Illegal format: %s' % s)
+        return ret.groups()
+
+    @staticmethod
+    def _ssh_args(ssh_cmd, user, host, port):
+        user_host = [('' if user is None else '%s@' % user) + host]
+        return shlex.split(ssh_cmd) + ([] if port is None else ['-p', port]) + user_host
 
 
 def run_task(args):

Support port option in host list and host string
diff --git a/tests/color_ssh/test_color_ssh.py b/tests/color_ssh/test_color_ssh.py
index 67684f8..e2fc45a 100644
--- a/tests/color_ssh/test_color_ssh.py
+++ b/tests/color_ssh/test_color_ssh.py
@@ -62,14 +62,15 @@ class TestSetting(TestCase):
             ('server-4', ['ssh', 'server-4', 'pwd']),
             ('server-5', ['ssh', 'server-5', 'pwd']),
             ('server-6', ['ssh', 'server-6', 'pwd']),
-            ('server-7', ['ssh', 'server-7', 'pwd']),
-            ('server-8', ['ssh', 'server-8', 'pwd']),
+            ('server-7', ['ssh', '-p', '22', 'server-7', 'pwd']),
+            ('server-8', ['ssh', '-p', '1022', 'server-8', 'pwd']),
             ('server-9', ['ssh', 'root@server-9', 'pwd']),
-            ('server-10', ['ssh', 'root@server-10', 'pwd']),
+            ('server-10', ['ssh', '-p', '1022', 'root@server-10', 'pwd']),
         ])
-        self._check(self._parse(['-H', 'server-11 root@server-12', 'pwd']), [
+        self._check(self._parse(['-H', 'server-11 root@server-12 root@server-13:1022', 'pwd']), [
             ('server-11', ['ssh', 'server-11', 'pwd']),
             ('server-12', ['ssh', 'root@server-12', 'pwd']),
+            ('server-13', ['ssh', '-p', '1022', 'root@server-13', 'pwd']),
         ])
         self._check(self._parse(['--hosts', hosts_path, '--host', 'server-11 root@server-12', 'pwd']), [
             ('server-1', ['ssh', 'server-1', 'pwd']),
@@ -78,10 +79,10 @@ class TestSetting(TestCase):
             ('server-4', ['ssh', 'server-4', 'pwd']),
             ('server-5', ['ssh', 'server-5', 'pwd']),
             ('server-6', ['ssh', 'server-6', 'pwd']),
-            ('server-7', ['ssh', 'server-7', 'pwd']),
-            ('server-8', ['ssh', 'server-8', 'pwd']),
+            ('server-7', ['ssh', '-p', '22', 'server-7', 'pwd']),
+            ('server-8', ['ssh', '-p', '1022', 'server-8', 'pwd']),
             ('server-9', ['ssh', 'root@server-9', 'pwd']),
-            ('server-10', ['ssh', 'root@server-10', 'pwd']),
+            ('server-10', ['ssh', '-p', '1022', 'root@server-10', 'pwd']),
             ('server-11', ['ssh', 'server-11', 'pwd']),
             ('server-12', ['ssh', 'root@server-12', 'pwd']),
         ])
@@ -103,6 +104,16 @@ class TestSetting(TestCase):
             self.assertSystemExit(2, Setting().parse_args, ['color-ssh', '--label', 'x'], out)
             self.assertSystemExit(2, Setting().parse_args, ['color-ssh', '--host', '  ', 'pwd'], out)
 
+    def test_parse_host_error(self):
+        self.assertRaises(ValueError, Setting._parse_host, '')
+        self.assertRaises(ValueError, Setting._parse_host, '@')
+        self.assertRaises(ValueError, Setting._parse_host, ':')
+        self.assertRaises(ValueError, Setting._parse_host, 'a:')
+        self.assertRaises(ValueError, Setting._parse_host, 'a:b')
+        self.assertRaises(ValueError, Setting._parse_host, '@a:0')
+        self.assertRaises(ValueError, Setting._parse_host, 'a:b@c:0')
+        self.assertRaises(ValueError, Setting._parse_host, 'a@@c:0')
+
 
 class TestMain(TestCase):
     def test_main_single_proc(self):
diff --git a/tests/resources/test_color_ssh_hosts.txt b/tests/resources/test_color_ssh_hosts.txt
index 3b9d2dd..f91ff9f 100644
--- a/tests/resources/test_color_ssh_hosts.txt
+++ b/tests/resources/test_color_ssh_hosts.txt
@@ -4,7 +4,7 @@ server-3
 server-4
 server-5
 server-6
-server-7
-server-8
+server-7:22
+server-8:1022
 root@server-9
-root@server-10
\ No newline at end of file
+root@server-10:1022
\ No newline at end of file

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov six mog-commons>=0.2.2
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/mogproject/color-ssh.git@b39783565319ee50b34988c29193f02a90122e2c#egg=color_ssh
coverage==7.8.0
exceptiongroup==1.2.2
iniconfig==2.1.0
Jinja2==3.1.6
MarkupSafe==3.0.2
mog-commons==0.2.3
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-cov==6.0.0
six==1.17.0
tomli==2.2.1

name: color-ssh
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - markupsafe==3.0.2
      - mog-commons==0.2.3
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - six==1.17.0
      - tomli==2.2.1
prefix: /opt/conda/envs/color-ssh

tests/color_ssh/test_color_ssh.py::TestSetting::test_parse_args tests/color_ssh/test_color_ssh.py::TestSetting::test_parse_host_error
tests/color_ssh/test_color_ssh.py::TestSetting::test_parse_args_error tests/color_ssh/test_color_ssh.py::TestMain::test_main_load_error tests/color_ssh/test_color_ssh.py::TestMain::test_main_multi_proc tests/color_ssh/test_color_ssh.py::TestMain::test_main_single_proc tests/color_ssh/test_color_ssh.py::TestMain::test_main_task_error
src/color_ssh/color_ssh.py src/color_ssh/__init__.py
src/color_ssh/color_ssh.py src/color_ssh/__init__.py