diff --git a/Generator/CMakeLists.txt b/Generator/CMakeLists.txt
index 54c3bde8985bc77fbec7c7696f3d7ab9ae51d1bd..0e60cee6fefe1ecf9c48e29f9a33cb92e933b32b 100644
--- a/Generator/CMakeLists.txt
+++ b/Generator/CMakeLists.txt
@@ -4,14 +4,17 @@ gaudi_add_module(GenAlgo
                  SOURCES src/IGenTool.cpp 
                          src/GenAlgo.cpp 
                          src/GenEvent.cpp 
+                         src/GenPrinter.cpp
+                         # ------- Readers -------
                          src/GenReader.cpp 
                          src/StdHepRdr.cpp 
-                         src/GenPrinter.cpp
                          src/LCAscHepRdr.cc
                          src/HepevtRdr.cpp
                          src/SLCIORdr.cpp
                          src/HepMCRdr.cpp
+                         # ------- Signals -------
                          src/GtGunTool.cpp
+                         src/GtPythiaTool.cpp
                          # ------- Beam Background -------
                          src/GtBeamBackgroundTool.cpp
                          src/BeamBackgroundFileParserV0.cpp
@@ -25,6 +28,7 @@ gaudi_add_module(GenAlgo
                       ${HEPMC_LIBRARIES}
                       ${CLHEP_LIBRARIES}
                       ${LCIO_LIBRARIES}
+                      ${PYTHIA8_LIBRARY}
                       EDM4HEP::edm4hep EDM4HEP::edm4hepDict
                       ROOT::EG
 )
diff --git a/Generator/src/GtPythiaTool.cpp b/Generator/src/GtPythiaTool.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..b34c92ef32a8cf898166b46c6cb199720c3a9185
--- /dev/null
+++ b/Generator/src/GtPythiaTool.cpp
@@ -0,0 +1,62 @@
+#include "GtPythiaTool.hh"
+
+DECLARE_COMPONENT(GtPythiaTool)
+
+StatusCode GtPythiaTool::initialize() {
+    StatusCode sc;
+    m_pythia = std::make_unique<Pythia8::Pythia>();
+    // configure with the card file first
+    m_pythia->readFile(m_card.value());
+    // tune with the additional commands
+    for (auto cmd: m_cmds.value()) {
+        m_pythia->readString(cmd);
+    }
+    // initialize pythia
+    m_pythia->init();
+    return sc;
+}
+
+StatusCode GtPythiaTool::finalize() {
+    StatusCode sc;
+    return sc;
+}
+
+bool GtPythiaTool::mutate(Gen::GenEvent& event) {
+    // generate the event
+    while(!m_pythia->next()) {
+        // if failed, try again
+    }
+
+    // get the particles
+    auto& pythia_particles = m_pythia->event;
+    // loop over the particles
+    for (int i = 0; i < pythia_particles.size(); ++i) {
+        auto& p = pythia_particles[i];
+        // create the MCParticle
+        auto mcp = event.getMCVec().create();
+        // set the properties
+        mcp.setPDG(p.id());
+        int status = 0;
+        if (p.isFinal()) {
+            status = 1;
+        } else {
+            status = 0;
+        }
+        mcp.setGeneratorStatus(status);
+        mcp.setCharge(p.charge());
+        mcp.setTime(p.tau());
+        mcp.setMass(p.m());
+        mcp.setVertex(edm4hep::Vector3d(p.xProd(), p.yProd(), p.zProd()));
+        mcp.setEndpoint(edm4hep::Vector3d(p.xDec(), p.yDec(), p.zDec()));
+        mcp.setMomentum(edm4hep::Vector3f(p.px(), p.py(), p.pz()));
+    }
+    return true;
+}
+
+bool GtPythiaTool::finish() {
+    return true;
+}
+
+bool GtPythiaTool::configure_gentool() {
+    return true;
+}
\ No newline at end of file
diff --git a/Generator/src/GtPythiaTool.hh b/Generator/src/GtPythiaTool.hh
new file mode 100755
index 0000000000000000000000000000000000000000..ae10d62bc7f862a030bc4d4bf6fc01d3c5b96bd5
--- /dev/null
+++ b/Generator/src/GtPythiaTool.hh
@@ -0,0 +1,40 @@
+#ifndef GtPythiaTool_hh
+#define GtPythiaTool_hh
+
+/*
+ * Description:
+ *   This tool is used to generate particles using Pythia.
+ *   User need to specify the card.
+ */
+
+#include <GaudiKernel/AlgTool.h>
+#include <Gaudi/Property.h>
+#include "IGenTool.h"
+
+#include "Pythia8/Pythia.h"
+
+#include <vector>
+#include <memory>
+
+class GtPythiaTool: public extends<AlgTool, IGenTool> {
+public:
+    using extends::extends;
+
+    // Overriding initialize and finalize
+    StatusCode initialize() override;
+    StatusCode finalize() override;
+
+    // IGenTool
+    bool mutate(Gen::GenEvent& event) override;
+    bool finish() override;
+    bool configure_gentool() override;
+
+private:
+    std::unique_ptr<Pythia8::Pythia> m_pythia;
+
+    // below properties will be used by Pythia
+    Gaudi::Property<std::vector<std::string>> m_cmds{this, "Commands"};
+    Gaudi::Property<std::string> m_card{this, "Card"};
+};
+
+#endif
\ No newline at end of file
diff --git a/cmake/CEPCSWDependencies.cmake b/cmake/CEPCSWDependencies.cmake
index b8d28b7d7a782a6b1de884a13cb405b6af55e86d..c063ffc75e002a275cf298e06f06adefceada188 100644
--- a/cmake/CEPCSWDependencies.cmake
+++ b/cmake/CEPCSWDependencies.cmake
@@ -44,6 +44,7 @@ find_package(LCIO REQUIRED)
 find_package(OnnxRuntime REQUIRED)
 find_package(PandoraSDK REQUIRED)
 find_package(podio REQUIRED)
+find_package(Pythia8 REQUIRED)
 find_package(ROOT COMPONENTS EG Geom GenVector Graf Graf3d Gpad MathCore Net RIO Tree TreePlayer REQUIRED)
 
 if (CEPCSW_USE_SYSTEM_CKF_BELLE)
diff --git a/cmake/FindPythia8.cmake b/cmake/FindPythia8.cmake
new file mode 100755
index 0000000000000000000000000000000000000000..2ba201cecfbee1fe3f99e9401341b964d3264fc6
--- /dev/null
+++ b/cmake/FindPythia8.cmake
@@ -0,0 +1,54 @@
+# https://github.com/HSF/cmaketools/blob/master/modules/FindPythia8.cmake
+# Defines:
+#
+#  PYTHIA8_FOUND
+#  PYTHIA8_VERSION
+#  PYTHIA8_INCLUDE_DIR
+#  PYTHIA8_INCLUDE_DIRS (not cached)
+#  PYTHIA8_LIBRARY
+#  PYTHIA8_hepmcinterface_LIBRARY
+#  PYTHIA8_lhapdfdummy_LIBRARY
+#  PYTHIA8_LIBRARIES (not cached) : for PYTHIA8_VERSION < 200 includes 3 libraries above; not to be used if lhapdf is used
+
+
+find_path(PYTHIA8_INCLUDE_DIR Pythia.h Pythia8/Pythia.h
+          HINTS $ENV{PYTHIA8}/include ${PYTHIA8}/include)
+find_path(PYTHIA8_XML_DIR Version.xml
+          HINTS $ENV{PYTHIA8}/xmldoc ${PYTHIA8}/xmldoc $ENV{PYTHIA8}/share/Pythia8/xmldoc ${PYTHIA8}/share/Pythia8/xmldoc)
+
+message(STATUS "xml path: ${PYTHIA8_XML_DIR}")
+
+#file(READ ${PYTHIA8_INCLUDE_DIR}/../xmldoc/Version.xml versionstr)
+file(READ ${PYTHIA8_XML_DIR}/Version.xml versionstr)
+string(REGEX REPLACE ".*Pythia:versionNumber.*default.*[0-9][.]([0-9]+).*" "\\1" PYTHIA8_VERSION "${versionstr}")
+
+message(STATUS "pythia8 version extracted: ${PYTHIA8_VERSION}")
+
+find_library(PYTHIA8_LIBRARY NAMES pythia8 Pythia8
+             HINTS $ENV{PYTHIA8_ROOT_DIR}/lib ${PYTHIA8_ROOT_DIR}/lib)
+
+if(PYTHIA8_VERSION VERSION_LESS 200)
+  find_library(PYTHIA8_hepmcinterface_LIBRARY NAMES hepmcinterface pythia8tohepmc
+               HINTS $ENV{PYTHIA8_ROOT_DIR}/lib ${PYTHIA8_ROOT_DIR}/lib)
+
+  find_library(PYTHIA8_lhapdfdummy_LIBRARY NAMES lhapdfdummy
+               HINTS $ENV{PYTHIA8_ROOT_DIR}/lib ${PYTHIA8_ROOT_DIR}/lib)
+
+  set(PYTHIA8_LIBRARIES ${PYTHIA8_LIBRARY} ${PYTHIA8_hepmcinterface_LIBRARY} ${PYTHIA8_lhapdfdummy_LIBRARY})
+else()
+  set(PYTHIA8_LIBRARIES ${PYTHIA8_LIBRARY})
+endif()
+
+set(PYTHIA8_INCLUDE_DIRS ${PYTHIA8_INCLUDE_DIR} ${PYTHIA8_INCLUDE_DIR}/Pythia8 )
+
+# handle the QUIETLY and REQUIRED arguments and set PYTHIA8_FOUND to TRUE if
+# all listed variables are TRUE
+
+INCLUDE(FindPackageHandleStandardArgs)
+if(PYTHIA8_VERSION VERSION_LESS 200)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pythia8 DEFAULT_MSG PYTHIA8_INCLUDE_DIR PYTHIA8_LIBRARY PYTHIA8_hepmcinterface_LIBRARY PYTHIA8_lhapdfdummy_LIBRARY)
+  mark_as_advanced(PYTHIA8_FOUND PYTHIA8_INCLUDE_DIR PYTHIA8_LIBRARY PYTHIA8_hepmcinterface_LIBRARY PYTHIA8_lhapdfdummy_LIBRARY PYTHIA8_VERSION_CHECK)
+else()
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pythia8 DEFAULT_MSG PYTHIA8_INCLUDE_DIR PYTHIA8_LIBRARY)
+  mark_as_advanced(PYTHIA8_FOUND PYTHIA8_INCLUDE_DIR PYTHIA8_LIBRARY PYTHIA8_VERSION_CHECK)
+endif()
\ No newline at end of file