diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 00f9bb80b6bd773cc6aad4b5d4ce99ad77e1c8a9..09d6ebc7e831c7368b9f8869052a226f5b43b84a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -132,6 +132,13 @@ losoto_clip:
   allow_failure: true
   script:
     - cwl-runner --no-container steps/LoSoTo.Clip.cwl test_jobs/losoto_clip.json
+
+losoto_clocktec:
+  stage: test_steps
+  allow_failure: true
+  script:
+    - cwl-runner --no-container steps/LoSoTo.ClockTec.cwl test_jobs/losoto_clocktec.json
+
 losoto_flagextend:
   stage: test_steps
   allow_failure: true
diff --git a/steps/LoSoTo.ClockTec.cwl b/steps/LoSoTo.ClockTec.cwl
new file mode 100644
index 0000000000000000000000000000000000000000..2159d2d68863946e056eb37fd22b13e4e3d696a2
--- /dev/null
+++ b/steps/LoSoTo.ClockTec.cwl
@@ -0,0 +1,83 @@
+#!/usr/bin/env cwl-runner
+
+class: CommandLineTool
+cwlVersion: v1.0
+id: losoto_clocktec
+
+$namespaces:
+  lofar: https://git.astron.nl/eosc/ontologies/raw/master/schema/lofar.owl
+doc: |
+  Separate phase solutions into Clock and TEC.
+  The Clock and TEC values are stored in the specified output soltab with type 'clock', 'tec', 'tec3rd'.
+
+requirements:
+  InlineJavascriptRequirement:
+    expressionLib:
+      - { $include: utils.js}
+  InitialWorkDirRequirement:
+    listing:
+      - entryname: 'parset.config'
+        entry: $(get_losoto_config('CLOCKTEC').join('\n'))
+
+      - entryname: $(inputs.input_h5parm.basename)
+        entry: $(inputs.input_h5parm)
+        writable: true
+
+baseCommand: "losoto"
+
+arguments:
+  - $(inputs.input_h5parm.basename)
+  - parset.config
+
+hints:
+  DockerRequirement:
+    dockerPull: lofareosc/lofar-pipeline-ci:latest
+
+inputs:
+  - id: input_h5parm
+    type: File
+    format: lofar:#H5Parm
+  - id: soltab
+    type: string
+    doc: "Solution table"
+  - id: flagBadChannels
+    type: boolean?
+    doc: Detect and remove bad channel before fitting, by default True.
+  - id: flagCut
+    type: float?
+  - id: chi2cut
+    type: float?
+  - id: combinePol
+    type: boolean?
+    doc: |
+      Find a combined polarization solution, by default False.
+  - id: removePhaseWraps
+    type: boolean?
+    doc: |
+      Detect and remove phase wraps, by default True.
+  - id: fit3rdorder
+    type: boolean?
+    doc: |
+      Fit a 3rd order ionospheric ocmponent (usefult <40 MHz). By default False.
+  - id: circular
+    type: boolean?
+    doc: |
+      Assume circular polarization with FR not removed. By default False.
+  - id: reverse
+    type: boolean?
+    doc:
+      Reverse the time axis. By default False.
+  - id: invertOffset
+    type: boolean?
+    doc: |
+      Invert (reverse the sign of) the phase offsets. By default False. Set to True
+      if you want to use them with the residuals operation.
+
+outputs:
+  - id: output_h5parm
+    type: File
+    format: lofar:#H5Parm
+    outputBinding:
+      glob: $(inputs.input_h5parm.basename)
+$schema:
+  - https://git.astron.nl/eosc/ontologies/raw/master/schema/lofar.owl
diff --git a/test_jobs/losoto_clocktec.json b/test_jobs/losoto_clocktec.json
new file mode 100644
index 0000000000000000000000000000000000000000..3632d7f13c8786836692e86a0a59a0cc1c9c96f0
--- /dev/null
+++ b/test_jobs/losoto_clocktec.json
@@ -0,0 +1,5 @@
+{
+  "input_h5parm": {"class": "File", "path": "/data/example.h5", "format": "lofar:#H5Parm"},
+  "soltab":  "sol000/phase000",
+  "ncpu": 1
+}