diff --git a/include/mcdstub/mcdstub.h b/include/mcdstub/mcdstub.h
index c3e9c7e9dc..c4370bb177 100644
--- a/include/mcdstub/mcdstub.h
+++ b/include/mcdstub/mcdstub.h
@@ -402,6 +402,18 @@ int process_string_cmd(void *user_ctx, const char *data,
  * @params: GArray with all extracted parameters.
  */
 int cmd_parse_params(const char *data, const char *schema, GArray *params);
+
+/**
+ * handle_gen_query() - Handler for all TCP query packets.
+ *
+ * Calls :c:func:`process_string_cmd` with all query functions in the
+ * mcd_query_cmds_table. :c:func:`process_string_cmd` then selects the correct
+ * one. This function just passes on the TCP packet data string from the
+ * parameters.
+ * @params: GArray with all TCP packet parameters.
+ */
+void handle_gen_query(GArray *params, void *user_ctx);
+
 /**
  * mcd_get_cpu_index() - Returns the internal CPU index plus one.
  *
@@ -415,6 +427,24 @@ int mcd_get_cpu_index(CPUState *cpu);
  * @cpu_index: Index of the desired CPU.
  */
 CPUState *mcd_get_cpu(uint32_t cpu_index);
+
+/**
+ * handle_query_cores() - Handler for the core query.
+ *
+ * This function sends the type of core and number of cores currently
+ * simulated by QEMU. It also sends a device name for the MCD data structure.
+ * @params: GArray with all TCP packet parameters.
+ */
+void handle_query_cores(GArray *params, void *user_ctx);
+
+/**
+ * handle_query_system() - Handler for the system query.
+ *
+ * Sends the system name, which is "qemu-system".
+ * @params: GArray with all TCP packet parameters.
+ */
+void handle_query_system(GArray *params, void *user_ctx);
+
 /**
  * get_first_cpu_in_process() - Returns the first CPU in the provided process.
  *
diff --git a/mcdstub/mcdstub.c b/mcdstub/mcdstub.c
index 858e79632b..a090268e70 100644
--- a/mcdstub/mcdstub.c
+++ b/mcdstub/mcdstub.c
@@ -81,6 +81,20 @@ void init_query_cmds_table(MCDCmdParseEntry *mcd_query_cmds_table)
     /* initalizes a list of all query commands */
     int cmd_number = 0;
 
+    MCDCmdParseEntry query_system = {
+        .handler = handle_query_system,
+        .cmd = QUERY_ARG_SYSTEM,
+    };
+    mcd_query_cmds_table[cmd_number] = query_system;
+    cmd_number++;
+
+    MCDCmdParseEntry query_cores = {
+        .handler = handle_query_cores,
+        .cmd = QUERY_ARG_CORES,
+    };
+    mcd_query_cmds_table[cmd_number] = query_cores;
+    cmd_number++;
+
 void reset_mcdserver_state(void)
 {
     g_free(mcdserver_state.processes);
@@ -345,6 +359,17 @@ int mcd_handle_packet(const char *line_buf)
         error_report("QEMU: Terminated via MCDstub");
         mcd_exit(0);
         exit(0);
+    case TCP_CHAR_QUERY:
+        {
+            static MCDCmdParseEntry query_cmd_desc = {
+                .handler = handle_gen_query,
+            };
+            query_cmd_desc.cmd = (char[2]) { TCP_CHAR_QUERY, '\0' };
+            strcpy(query_cmd_desc.schema,
+                (char[2]) { ARG_SCHEMA_STRING, '\0' });
+            cmd_parser = &query_cmd_desc;
+        }
+        break;
     case TCP_CHAR_CLOSE_SERVER:
         {
             static MCDCmdParseEntry close_server_cmd_desc = {
@@ -368,6 +393,20 @@ int mcd_handle_packet(const char *line_buf)
 
     return RS_IDLE;
 }
+
+void handle_gen_query(GArray *params, void *user_ctx)
+{
+    if (!params->len) {
+        return;
+    }
+    /* iterate over all possible query functions and execute the right one */
+    if (process_string_cmd(NULL, get_param(params, 0)->data,
+                           mcdserver_state.mcd_query_cmds_table,
+                           ARRAY_SIZE(mcdserver_state.mcd_query_cmds_table))) {
+        mcd_put_packet("");
+    }
+}
+
 void run_cmd_parser(const char *data, const MCDCmdParseEntry *cmd)
 {
     if (!data) {
@@ -735,6 +774,37 @@ void handle_open_server(GArray *params, void *user_ctx)
     mcd_put_packet(TCP_HANDSHAKE_SUCCESS);
 }
 
+void handle_query_system(GArray *params, void *user_ctx)
+{
+    mcd_put_packet(MCD_SYSTEM_NAME);
+}
+
+void handle_query_cores(GArray *params, void *user_ctx)
+{
+    /* get first cpu */
+    CPUState *cpu = mcd_first_attached_cpu();
+    if (!cpu) {
+        return;
+    }
+
+    ObjectClass *oc = object_get_class(OBJECT(cpu));
+    const char *cpu_model = object_class_get_name(oc);
+
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+    const gchar *arch = cc->gdb_arch_name(cpu);
+
+    uint32_t nr_cores = cpu->nr_cores;
+    char device_name[ARGUMENT_STRING_LENGTH] = {0};
+    if (arch) {
+        snprintf(device_name, sizeof(device_name), "%s",
+            DEVICE_NAME_TEMPLATE(arch));
+    }
+    g_string_printf(mcdserver_state.str_buf, "%s=%s.%s=%s.%s=%u.",
+        TCP_ARGUMENT_DEVICE, device_name, TCP_ARGUMENT_CORE, cpu_model,
+        TCP_ARGUMENT_AMOUNT_CORE, nr_cores);
+    mcd_put_strbuf();
+}
+
 
 void handle_close_server(GArray *params, void *user_ctx)
 {
