Currently, when starting a console, GNS3 creates a new one, no matter if a console for that node already exists or not. For Linux and macOS I created scripts for starting conssoles, that avoid having duplicate instances.

Linux

The following script checks, if the console command is already active. If yes, no new console is started. The script is using the XFCE4 terminal emulator. By modifying the cmdline variable, other terminal emulators can be used.

Save the following script to /usr/local/bin/run-term, make it executable and set the console application command within GNS3 to
run-term 'telnet %h %p' '%d'

#!/usr/bin/env python3
#
# run a single invocation of a command in (tabbed) terminal window
#
# Usage: run-term <command> [<title>]
#

import os
import sys
import psutil
import shlex
import subprocess

# parse arguments
argc = len(sys.argv)
if argc < 2 or argc > 3:
    sys.exit("Usage: run-term <command> [<title>]")

cmd = sys.argv[1]
if argc >= 3:
    title = sys.argv[2]
else:
    title = None

# cmdline to run command
cmdline = ["xfce4-terminal", "--tab"]
if title is not None:
    cmdline.extend(["-T", title])
cmdline.extend(["-e", cmd])

# get process list
procs = {p.pid: p.info for p in psutil.process_iter(attrs=['cmdline', 'ppid', 'uids'])}

# check, if command is already running
uid = os.getuid()
cmd_split = shlex.split(cmd)
term_name = os.path.basename(cmdline[0])
for pid in procs:
    if procs[pid]['uids'].real == uid and \
       procs[pid]['cmdline'] == cmd_split and \
       os.path.basename(procs[procs[pid]['ppid']]['cmdline'][0]) == term_name:
        sys.exit(0)

# run command
try:
    subprocess.Popen(cmdline)
except (OSError, subprocess.SubprocessError) as err:
    sys.exit(str(err))

MacOS

Applescript allows a nice extra feature: If a console for a node is already active, it can activate that window/tab to make it the frontmost one.

In contrast to Linux, it checks for duplicate window titles, not duplicate console commands. The script uses iTerm2 for terminal emulation, adapting it to other terminal emulators will require a major rewrite.

Save the following script to /usr/local/bin/run-iTerm, make it executable and set the console application command within GNS3 to
run-iTerm 'exec telnet %h %p' '%d'

#!/usr/bin/osascript

-- start command in new iTerm tab

on run (args)
	-- cmd $1, title $2 (optional)
	set cmd to first item of args
	if (count of args) >= 2 then
		set cmd_title to second item of args
	else
		set cmd_title to ""
	end if

        -- get PATH
	set posix_path to do shell script "echo \"$PATH\""

	tell application "iTerm"
		activate

		-- check if session with cmd_title already active
		if cmd_title is not equal to "" then
			set AppleScript's text item delimiters to " ("
			repeat with w in windows
				repeat with t in tabs of w
					repeat with s in sessions of t
						set sess_title to name of s
    						set sess_title to first text item of sess_title
						if cmd_title is equal to sess_title then
							tell s to select
							tell t to select
							tell w to select
							return
						end if
					end repeat
				end repeat
			end repeat
			set AppleScript's text item delimiters to ""
		end if

		-- create session in new tab of current window
		if (number of windows) = 0 then
			set w to (create window with default profile)
		else
			set w to current window
		end if
		tell w
			set t to (create tab with default profile command "sh")
			set s to first session of t
		end tell

		-- run command, optionally set title
		tell s
			if cmd_title is not equal to "" then
				set name to cmd_title
			end if
			write text "PATH=" & quoted form of posix_path
			write text cmd
		end tell
	end tell
end run