kill-switch-mcp 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server.js +88 -126
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -3834,10 +3834,6 @@ var SERVER_URL = (() => {
|
|
|
3834
3834
|
return process.argv[idx + 1];
|
|
3835
3835
|
return process.env.KILL_SWITCH_SERVER || "localhost";
|
|
3836
3836
|
})();
|
|
3837
|
-
function getWebBase() {
|
|
3838
|
-
const isLocal = SERVER_URL === "localhost" || SERVER_URL === "127.0.0.1";
|
|
3839
|
-
return isLocal ? "http://localhost:8888" : `https://${SERVER_URL}`;
|
|
3840
|
-
}
|
|
3841
3837
|
var ERC20_ABI = [
|
|
3842
3838
|
{
|
|
3843
3839
|
name: "approve",
|
|
@@ -4000,14 +3996,6 @@ function saveAccessKey(privateKey, accountAddress) {
|
|
|
4000
3996
|
createdAt: new Date().toISOString()
|
|
4001
3997
|
});
|
|
4002
3998
|
}
|
|
4003
|
-
async function getTournamentSchedule() {
|
|
4004
|
-
const res = await fetch(`${getWebBase()}/api/paid-schedule`);
|
|
4005
|
-
const data = await res.json();
|
|
4006
|
-
if (data.error) {
|
|
4007
|
-
throw new Error(data.error);
|
|
4008
|
-
}
|
|
4009
|
-
return data.slots || [];
|
|
4010
|
-
}
|
|
4011
3999
|
async function joinTournament(tournamentAddress, username) {
|
|
4012
4000
|
const wallet = loadWallet();
|
|
4013
4001
|
if (!wallet) {
|
|
@@ -4084,7 +4072,7 @@ YOU are the brain of your bot. Your human talks strategy, you execute it in the
|
|
|
4084
4072
|
## Quick Start
|
|
4085
4073
|
|
|
4086
4074
|
1. \`login\` — connects to the game (creates account if needed)
|
|
4087
|
-
2. \`join_game\`
|
|
4075
|
+
2. \`join_game\` — shows available games and buy-in tiers, or joins an existing queued game
|
|
4088
4076
|
3. \`wait_for_game_start\` — blocks until teleported to the arena
|
|
4089
4077
|
4. \`execute_code\` — fight! Use \`bot\`, \`sdk\`, and \`actions\` globals.
|
|
4090
4078
|
|
|
@@ -4092,18 +4080,25 @@ Before writing any execute_code, read \`killswitch://sdk-reference\` for the com
|
|
|
4092
4080
|
|
|
4093
4081
|
---
|
|
4094
4082
|
|
|
4095
|
-
## Game
|
|
4083
|
+
## Joining a Game
|
|
4084
|
+
|
|
4085
|
+
Call \`join_game\` with no arguments to see what's available:
|
|
4086
|
+
- **If a game is queued**: You'll see the current game's buy-in and player count. You can only join that game.
|
|
4087
|
+
- **If no game is queued**: You'll see all available buy-in tiers (Free, $5, $15, $50, $100, $1000). Call \`join_game\` with a \`tier_id\` to start a new game.
|
|
4088
|
+
- **If a game is active**: You must wait for it to finish.
|
|
4089
|
+
|
|
4090
|
+
**Paid games** require a Tempo wallet (\`setup_game_wallet\`). Your buy-in is deposited on-chain when you join. No refunds once deposited — the only refund path is if the game is cancelled (not enough players).
|
|
4096
4091
|
|
|
4097
|
-
|
|
4098
|
-
-
|
|
4092
|
+
**Game start triggers:**
|
|
4093
|
+
- 12 players join → starts immediately
|
|
4094
|
+
- 2+ players joined and 5-minute countdown expires → starts with whoever joined
|
|
4095
|
+
- Only 1 player after 30 minutes → game cancelled (refunded if paid)
|
|
4096
|
+
|
|
4097
|
+
### The Arena
|
|
4099
4098
|
- **Stats**: 50 Attack, 50 Strength, 50 Defence, 99 Hitpoints
|
|
4100
4099
|
- **Start**: Empty inventory — everything comes from ground loot
|
|
4101
4100
|
- **Win condition**: Last agent alive
|
|
4102
4101
|
|
|
4103
|
-
### Longy (Coming Soon)
|
|
4104
|
-
- Large map: Falador to Port Sarim
|
|
4105
|
-
- Level 1 everything — skill up, craft gear, fish food, outlast everyone
|
|
4106
|
-
|
|
4107
4102
|
---
|
|
4108
4103
|
|
|
4109
4104
|
## The Arena (Shorty)
|
|
@@ -4482,17 +4477,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
4482
4477
|
},
|
|
4483
4478
|
{
|
|
4484
4479
|
name: "join_game",
|
|
4485
|
-
description: "Join
|
|
4480
|
+
description: "Join an available game. Call with no arguments to see what's available, or provide tier_id to join a specific buy-in tier. For paid games, handles deposit automatically. After joining, call wait_for_game_start.",
|
|
4486
4481
|
inputSchema: {
|
|
4487
4482
|
type: "object",
|
|
4488
4483
|
properties: {
|
|
4489
|
-
|
|
4490
|
-
type: "
|
|
4491
|
-
|
|
4492
|
-
description: 'Game mode: "shorty" (quick battle royale) or "longy" (coming soon)'
|
|
4484
|
+
tier_id: {
|
|
4485
|
+
type: "number",
|
|
4486
|
+
description: "Tier ID to join (from available tiers list). Only needed when starting a new game — omit to join an existing queued game."
|
|
4493
4487
|
}
|
|
4494
|
-
}
|
|
4495
|
-
required: ["mode"]
|
|
4488
|
+
}
|
|
4496
4489
|
}
|
|
4497
4490
|
},
|
|
4498
4491
|
{
|
|
@@ -4524,28 +4517,6 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
4524
4517
|
type: "object",
|
|
4525
4518
|
properties: {}
|
|
4526
4519
|
}
|
|
4527
|
-
},
|
|
4528
|
-
{
|
|
4529
|
-
name: "tournament_schedule",
|
|
4530
|
-
description: "View upcoming paid tournaments — start times, buy-ins, player counts. Read-only.",
|
|
4531
|
-
inputSchema: {
|
|
4532
|
-
type: "object",
|
|
4533
|
-
properties: {}
|
|
4534
|
-
}
|
|
4535
|
-
},
|
|
4536
|
-
{
|
|
4537
|
-
name: "join_tournament",
|
|
4538
|
-
description: "Join a paid tournament by depositing buy-in from game wallet. SPENDS REAL MONEY. Confirm with user before calling. Must be logged in.",
|
|
4539
|
-
inputSchema: {
|
|
4540
|
-
type: "object",
|
|
4541
|
-
properties: {
|
|
4542
|
-
tournament_address: {
|
|
4543
|
-
type: "string",
|
|
4544
|
-
description: "Tournament contract address (from tournament_schedule)"
|
|
4545
|
-
}
|
|
4546
|
-
},
|
|
4547
|
-
required: ["tournament_address"]
|
|
4548
|
-
}
|
|
4549
4520
|
}
|
|
4550
4521
|
]
|
|
4551
4522
|
};
|
|
@@ -4981,29 +4952,84 @@ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
|
4981
4952
|
if (!connection) {
|
|
4982
4953
|
return errorResponse("Not connected. Call login first.");
|
|
4983
4954
|
}
|
|
4984
|
-
const mode = args?.mode;
|
|
4985
|
-
if (!mode || !["shorty", "longy"].includes(mode)) {
|
|
4986
|
-
return errorResponse('mode must be "shorty" or "longy"');
|
|
4987
|
-
}
|
|
4988
4955
|
const isLocal = SERVER_URL2 === "localhost" || SERVER_URL2 === "127.0.0.1";
|
|
4989
4956
|
const webBase = isLocal ? `http://localhost:8888` : `https://${SERVER_URL2}`;
|
|
4990
|
-
const
|
|
4957
|
+
const availRes = await fetch(`${webBase}/api/game/available`);
|
|
4958
|
+
const available = await availRes.json();
|
|
4959
|
+
if (available.status === "active") {
|
|
4960
|
+
return errorResponse(`A game is currently in progress with ${available.player_count} player(s) remaining. Try again when it finishes.`);
|
|
4961
|
+
}
|
|
4962
|
+
const tierId = args?.tier_id;
|
|
4963
|
+
if (available.status === "open" && !tierId) {
|
|
4964
|
+
const tiers = available.tiers;
|
|
4965
|
+
const lines = [
|
|
4966
|
+
"No game currently queued. Available buy-in tiers:",
|
|
4967
|
+
"",
|
|
4968
|
+
...tiers.map((t) => ` [${t.tier_id}] ${t.label} — $${(t.buy_in / 100).toFixed(2)} buy-in (max ${t.max_players} players)`),
|
|
4969
|
+
"",
|
|
4970
|
+
"Call join_game again with tier_id to start a game."
|
|
4971
|
+
];
|
|
4972
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
4973
|
+
`) }] };
|
|
4974
|
+
}
|
|
4991
4975
|
try {
|
|
4992
|
-
const
|
|
4993
|
-
const
|
|
4994
|
-
|
|
4995
|
-
|
|
4976
|
+
const joinUrl = `${webBase}/api/game/join?username=${encodeURIComponent(activeBotName)}&tier_id=${tierId ?? ""}`;
|
|
4977
|
+
const joinRes = await fetch(joinUrl, { method: "POST" });
|
|
4978
|
+
const joinData = await joinRes.json();
|
|
4979
|
+
if (joinData.error) {
|
|
4980
|
+
return errorResponse(joinData.error);
|
|
4981
|
+
}
|
|
4982
|
+
if (joinData.contract_address && joinData.player_count === 0) {
|
|
4983
|
+
if (!hasGameWallet()) {
|
|
4984
|
+
return errorResponse("This is a paid game but no game wallet found. Run setup_game_wallet first.");
|
|
4985
|
+
}
|
|
4986
|
+
try {
|
|
4987
|
+
const result = await joinTournament(joinData.contract_address, activeBotName);
|
|
4988
|
+
const parts2 = [
|
|
4989
|
+
`Joined game ${joinData.game_id} (paid).`,
|
|
4990
|
+
`Buy-in deposited: $${result.amount} USDC`,
|
|
4991
|
+
`Transaction: ${result.txHash}`,
|
|
4992
|
+
`Players: waiting for more...`,
|
|
4993
|
+
"",
|
|
4994
|
+
"Once deposited, you cannot leave or get a refund (unless the game is cancelled).",
|
|
4995
|
+
"Next: call wait_for_game_start to wait for the match."
|
|
4996
|
+
];
|
|
4997
|
+
return { content: [{ type: "text", text: parts2.join(`
|
|
4998
|
+
`) }] };
|
|
4999
|
+
} catch (e) {
|
|
5000
|
+
return errorResponse(`Failed to deposit: ${e.message}`);
|
|
5001
|
+
}
|
|
5002
|
+
}
|
|
5003
|
+
if (joinData.contract_address && joinData.player_count > 0) {
|
|
5004
|
+
if (!hasGameWallet()) {
|
|
5005
|
+
return errorResponse("This is a paid game but no game wallet found. Run setup_game_wallet first.");
|
|
5006
|
+
}
|
|
5007
|
+
try {
|
|
5008
|
+
const result = await joinTournament(joinData.contract_address, activeBotName);
|
|
5009
|
+
const parts2 = [
|
|
5010
|
+
`Joined game ${joinData.game_id} (paid).`,
|
|
5011
|
+
`Buy-in deposited: $${result.amount} USDC`,
|
|
5012
|
+
`Players: ${joinData.player_count}/${joinData.max_players}`,
|
|
5013
|
+
"",
|
|
5014
|
+
"Once deposited, you cannot leave or get a refund (unless the game is cancelled).",
|
|
5015
|
+
"Next: call wait_for_game_start to wait for the match."
|
|
5016
|
+
];
|
|
5017
|
+
return { content: [{ type: "text", text: parts2.join(`
|
|
5018
|
+
`) }] };
|
|
5019
|
+
} catch (e) {
|
|
5020
|
+
return errorResponse(`Failed to deposit: ${e.message}`);
|
|
5021
|
+
}
|
|
4996
5022
|
}
|
|
4997
5023
|
const parts = [
|
|
4998
|
-
`Joined ${
|
|
4999
|
-
`Players
|
|
5024
|
+
`Joined game ${joinData.game_id} (free).`,
|
|
5025
|
+
`Players: ${joinData.player_count}/${joinData.max_players}`,
|
|
5000
5026
|
"",
|
|
5001
5027
|
"Next: call wait_for_game_start to wait for the match."
|
|
5002
5028
|
];
|
|
5003
5029
|
return { content: [{ type: "text", text: parts.join(`
|
|
5004
5030
|
`) }] };
|
|
5005
5031
|
} catch (e) {
|
|
5006
|
-
return errorResponse(`Failed to join game: ${e.message}
|
|
5032
|
+
return errorResponse(`Failed to join game: ${e.message}`);
|
|
5007
5033
|
}
|
|
5008
5034
|
}
|
|
5009
5035
|
case "disconnect_bot": {
|
|
@@ -5087,7 +5113,7 @@ Prerequisites:
|
|
|
5087
5113
|
`Account: ${info.address}`,
|
|
5088
5114
|
`USDC Balance: $${info.balance}`,
|
|
5089
5115
|
"",
|
|
5090
|
-
info.balanceRaw === 0n ? "Your wallet is empty. Fund it by sending USDC to your account address on the Tempo network." : "Your wallet is funded and ready for paid
|
|
5116
|
+
info.balanceRaw === 0n ? "Your wallet is empty. Fund it by sending USDC to your account address on the Tempo network." : "Your wallet is funded and ready for paid games. Use join_game to see available tiers."
|
|
5091
5117
|
].join(`
|
|
5092
5118
|
`)
|
|
5093
5119
|
}]
|
|
@@ -5096,70 +5122,6 @@ Prerequisites:
|
|
|
5096
5122
|
return errorResponse(`Failed to check wallet: ${e.message}`);
|
|
5097
5123
|
}
|
|
5098
5124
|
}
|
|
5099
|
-
case "tournament_schedule": {
|
|
5100
|
-
try {
|
|
5101
|
-
const slots = await getTournamentSchedule();
|
|
5102
|
-
if (slots.length === 0) {
|
|
5103
|
-
return {
|
|
5104
|
-
content: [{
|
|
5105
|
-
type: "text",
|
|
5106
|
-
text: "No upcoming paid tournaments scheduled. Check back later, or paid tournaments may not be enabled on this server."
|
|
5107
|
-
}]
|
|
5108
|
-
};
|
|
5109
|
-
}
|
|
5110
|
-
const lines = ["── Upcoming Paid Tournaments ──", ""];
|
|
5111
|
-
for (let i = 0;i < slots.length; i++) {
|
|
5112
|
-
const s = slots[i];
|
|
5113
|
-
const time = new Date(s.startTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
5114
|
-
const buyIn = (parseInt(s.buyIn) / 1e6).toFixed(2);
|
|
5115
|
-
lines.push(`[${i + 1}] ${time} — $${buyIn} buy-in — ${s.depositorCount}/${s.maxPlayers} players`);
|
|
5116
|
-
lines.push(` Contract: ${s.contractAddress}`);
|
|
5117
|
-
}
|
|
5118
|
-
lines.push("");
|
|
5119
|
-
lines.push("To join a tournament, use join_tournament with the contract address.");
|
|
5120
|
-
lines.push("Make sure you have enough USDC in your game wallet (check with check_wallet).");
|
|
5121
|
-
return { content: [{ type: "text", text: lines.join(`
|
|
5122
|
-
`) }] };
|
|
5123
|
-
} catch (e) {
|
|
5124
|
-
return errorResponse(`Failed to get tournament schedule: ${e.message}`);
|
|
5125
|
-
}
|
|
5126
|
-
}
|
|
5127
|
-
case "join_tournament": {
|
|
5128
|
-
const tournamentAddress = args?.tournament_address;
|
|
5129
|
-
if (!tournamentAddress || !tournamentAddress.startsWith("0x")) {
|
|
5130
|
-
return errorResponse("A valid tournament contract address (0x...) is required. Use tournament_schedule to find one.");
|
|
5131
|
-
}
|
|
5132
|
-
if (!hasGameWallet()) {
|
|
5133
|
-
return errorResponse("No game wallet found. Run setup_game_wallet first.");
|
|
5134
|
-
}
|
|
5135
|
-
if (!activeBotName) {
|
|
5136
|
-
return errorResponse("Not logged in. Call login first so we know your in-game username.");
|
|
5137
|
-
}
|
|
5138
|
-
try {
|
|
5139
|
-
const result = await joinTournament(tournamentAddress, activeBotName);
|
|
5140
|
-
return {
|
|
5141
|
-
content: [{
|
|
5142
|
-
type: "text",
|
|
5143
|
-
text: [
|
|
5144
|
-
"Tournament joined!",
|
|
5145
|
-
"",
|
|
5146
|
-
`Buy-in: $${result.amount} USDC`,
|
|
5147
|
-
`Transaction: ${result.txHash}`,
|
|
5148
|
-
`Username: ${activeBotName}`,
|
|
5149
|
-
"",
|
|
5150
|
-
"Your deposit is held in the tournament escrow contract.",
|
|
5151
|
-
"Be online when the match starts or you'll be eliminated (buy-in stays in the pot).",
|
|
5152
|
-
"",
|
|
5153
|
-
"If the match is cancelled (< 2 players), you'll get a full refund.",
|
|
5154
|
-
"If the server goes down, you can claim a refund after 1 hour."
|
|
5155
|
-
].join(`
|
|
5156
|
-
`)
|
|
5157
|
-
}]
|
|
5158
|
-
};
|
|
5159
|
-
} catch (e) {
|
|
5160
|
-
return errorResponse(`Failed to join tournament: ${e.message}`);
|
|
5161
|
-
}
|
|
5162
|
-
}
|
|
5163
5125
|
default:
|
|
5164
5126
|
throw new Error(`Unknown tool: ${name}`);
|
|
5165
5127
|
}
|