diff --git a/code/game/world.dm b/code/game/world.dm
index fdb0b8f63be..02c613e9ac8 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -266,6 +266,13 @@ GLOBAL_VAR_INIT(world_topic_spam_protect_time, world.timeofday)
update_status()
return "Set listed status to invisible."
+
+ else if("hostannounce" in input)
+ if(!key_valid)
+ return keySpamProtect(addr)
+
+ to_chat(world, "
Server Announcement: [input["message"]]
")
+
/proc/keySpamProtect(var/addr)
if(GLOB.world_topic_spam_protect_ip == addr && abs(GLOB.world_topic_spam_protect_time - world.time) < 50)
spawn(50)
diff --git a/tools/send2server.py b/tools/send2server.py
new file mode 100644
index 00000000000..fd255a3cfb5
--- /dev/null
+++ b/tools/send2server.py
@@ -0,0 +1,14 @@
+# Script to send world/Topic announcements to a server via automated tooling
+# Author: AffectedArc07
+# Takes a message as command line argument
+# Example: python send2server.py "This is a message that will be sent to the server"
+import socket, struct, urllib.parse, sys
+
+message = sys.argv[1]
+commskey = "YOURKEYHERE"
+
+sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+cmd = "?hostannounce&key={}&message={}".format(urllib.parse.quote(commskey), urllib.parse.quote(message))
+query = b"\x00\x83" + struct.pack('>H', len(cmd) + 6) + b"\x00\x00\x00\x00\x00" + cmd.encode() + b"\x00"
+sock.connect(("localhost", 6666))
+sock.sendall(query)