kill-switch-mcp 1.2.10 → 1.2.12
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 +75 -11
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -3855,13 +3855,19 @@ import {
|
|
|
3855
3855
|
stringToHex,
|
|
3856
3856
|
pad
|
|
3857
3857
|
} from "viem";
|
|
3858
|
-
import { Account } from "viem/tempo";
|
|
3858
|
+
import { Account, withFeePayer } from "viem/tempo";
|
|
3859
3859
|
import { tempoModerato, tempo } from "viem/chains";
|
|
3860
3860
|
var TEMPO_BIN = join2(homedir2(), ".tempo", "bin", "tempo");
|
|
3861
3861
|
var TEMPO_CHAIN_ID = parseInt(process.env.TEMPO_CHAIN_ID || "4217");
|
|
3862
|
-
var
|
|
3863
|
-
var TEMPO_NETWORK =
|
|
3864
|
-
var USDC_ADDRESS = process.env.USDC_ADDRESS || "0x20c000000000000000000000b9537d11c60e8b50";
|
|
3862
|
+
var isMainnet = TEMPO_CHAIN_ID === 4217;
|
|
3863
|
+
var TEMPO_NETWORK = isMainnet ? "mainnet" : "testnet";
|
|
3864
|
+
var USDC_ADDRESS = process.env.USDC_ADDRESS || (isMainnet ? "0x20c000000000000000000000b9537d11c60e8b50" : "0x20c0000000000000000000000000000000000000");
|
|
3865
|
+
var feePayerUrl = null;
|
|
3866
|
+
function setFeePayerUrl(url) {
|
|
3867
|
+
feePayerUrl = url;
|
|
3868
|
+
}
|
|
3869
|
+
var baseChain = isMainnet ? tempo : tempoModerato;
|
|
3870
|
+
var tempoChain = { ...baseChain, feeToken: USDC_ADDRESS };
|
|
3865
3871
|
function runTempo(...args) {
|
|
3866
3872
|
return new Promise((resolve, reject) => {
|
|
3867
3873
|
execFile(TEMPO_BIN, args, { timeout: 30000 }, (error, stdout, stderr) => {
|
|
@@ -3978,12 +3984,25 @@ async function tempoFund() {
|
|
|
3978
3984
|
async function tempoRefresh() {
|
|
3979
3985
|
await runTempoInteractive("wallet", "refresh", "-n", TEMPO_NETWORK);
|
|
3980
3986
|
}
|
|
3987
|
+
function readKeyAuthorization() {
|
|
3988
|
+
const tomlPath = join2(homedir2(), ".tempo", "wallet", "keys.toml");
|
|
3989
|
+
if (!existsSync2(tomlPath))
|
|
3990
|
+
return null;
|
|
3991
|
+
try {
|
|
3992
|
+
const content = readFileSync(tomlPath, "utf-8");
|
|
3993
|
+
const match = content.match(/key_authorization\s*=\s*"(0x[0-9a-fA-F]+)"/);
|
|
3994
|
+
return match ? match[1] : null;
|
|
3995
|
+
} catch {
|
|
3996
|
+
return null;
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3981
3999
|
function getWalletClient(privateKey, parentAddress) {
|
|
3982
4000
|
const account = Account.fromSecp256k1(privateKey, { access: parentAddress });
|
|
4001
|
+
const transport = feePayerUrl ? withFeePayer(http(), http(feePayerUrl), { policy: "sign-and-broadcast" }) : http();
|
|
3983
4002
|
return createWalletClient({
|
|
3984
4003
|
account,
|
|
3985
4004
|
chain: tempoChain,
|
|
3986
|
-
transport
|
|
4005
|
+
transport
|
|
3987
4006
|
});
|
|
3988
4007
|
}
|
|
3989
4008
|
function getPublicClient() {
|
|
@@ -4070,11 +4089,15 @@ async function joinTournament(tournamentAddress, username) {
|
|
|
4070
4089
|
if (remaining < buyInUsd) {
|
|
4071
4090
|
throw new Error(`Spending limit too low. Need $${buyInUsd.toFixed(2)}, limit remaining: $${remaining.toFixed(2)}. ` + "Run `tempo wallet refresh` to reset your spending limit.");
|
|
4072
4091
|
}
|
|
4092
|
+
const keyAuth = readKeyAuthorization();
|
|
4093
|
+
const sponsorOpts = feePayerUrl ? { feePayer: true } : {};
|
|
4073
4094
|
const approveHash = await walletClient.writeContract({
|
|
4074
4095
|
address: USDC_ADDRESS,
|
|
4075
4096
|
abi: ERC20_ABI,
|
|
4076
4097
|
functionName: "approve",
|
|
4077
|
-
args: [tournamentAddress, buyIn]
|
|
4098
|
+
args: [tournamentAddress, buyIn],
|
|
4099
|
+
...keyAuth ? { keyAuthorization: keyAuth } : {},
|
|
4100
|
+
...sponsorOpts
|
|
4078
4101
|
});
|
|
4079
4102
|
await pub.waitForTransactionReceipt({ hash: approveHash });
|
|
4080
4103
|
const usernameBytes = pad(stringToHex(username), { size: 32 });
|
|
@@ -4082,7 +4105,9 @@ async function joinTournament(tournamentAddress, username) {
|
|
|
4082
4105
|
address: tournamentAddress,
|
|
4083
4106
|
abi: TOURNAMENT_ABI,
|
|
4084
4107
|
functionName: "deposit",
|
|
4085
|
-
args: [usernameBytes]
|
|
4108
|
+
args: [usernameBytes],
|
|
4109
|
+
...keyAuth ? { keyAuthorization: keyAuth } : {},
|
|
4110
|
+
...sponsorOpts
|
|
4086
4111
|
});
|
|
4087
4112
|
await pub.waitForTransactionReceipt({ hash: depositHash });
|
|
4088
4113
|
return {
|
|
@@ -4099,6 +4124,10 @@ var SERVER_URL = (() => {
|
|
|
4099
4124
|
return process.env.KILL_SWITCH_SERVER || "localhost";
|
|
4100
4125
|
})();
|
|
4101
4126
|
console.error(`[Kill Switch MCP] Server: ${SERVER_URL}`);
|
|
4127
|
+
var isLocal = SERVER_URL === "localhost" || SERVER_URL === "127.0.0.1";
|
|
4128
|
+
var FEE_PAYER_URL = `${isLocal ? "http://localhost:8888" : `https://${SERVER_URL}`}/api/fee-payer`;
|
|
4129
|
+
setFeePayerUrl(FEE_PAYER_URL);
|
|
4130
|
+
console.error(`[Kill Switch MCP] Fee payer relay: ${FEE_PAYER_URL}`);
|
|
4102
4131
|
var KILLSWITCH_HOME = join3(homedir3(), ".killswitch");
|
|
4103
4132
|
var BOTS_DIR = join3(KILLSWITCH_HOME, "bots");
|
|
4104
4133
|
var GUIDE = `# Kill Switch — Player Guide
|
|
@@ -4122,6 +4151,41 @@ Before writing any execute_code, read \`killswitch://sdk-reference\` for the com
|
|
|
4122
4151
|
|
|
4123
4152
|
---
|
|
4124
4153
|
|
|
4154
|
+
## CRITICAL: API Method Names
|
|
4155
|
+
|
|
4156
|
+
**DO NOT GUESS METHOD NAMES.** If you call a method that doesn't exist, you waste a turn. These are the ONLY methods available:
|
|
4157
|
+
|
|
4158
|
+
**\`bot\` methods (high-level, async, THROW on failure — use try/catch):**
|
|
4159
|
+
- \`bot.pickupItem(pattern)\` — walk to and pick up item (NOT bot.pickup, NOT bot.getGroundItems)
|
|
4160
|
+
- \`bot.equipItem(pattern)\` — equip from inventory (NOT bot.equip, NOT bot.wield, NOT bot.wear)
|
|
4161
|
+
- \`bot.eatFood(pattern)\` — eat food (ALWAYS pass a food name like "Lobster" — without a pattern it may try to eat non-food)
|
|
4162
|
+
- \`bot.attackPlayer(name)\` — attack a player (NOT bot.attack)
|
|
4163
|
+
- \`bot.walkTo(x, z)\` — pathfind walk (slow, can fail in arena — prefer sdk.sendWalk)
|
|
4164
|
+
- \`bot.interactLoc(name, option)\` — interact with object
|
|
4165
|
+
|
|
4166
|
+
**\`sdk\` methods (low-level, instant reads + async commands):**
|
|
4167
|
+
- \`sdk.getGroundItems()\` — ground items (NOT bot.getGroundItems, NOT bot.nearbyObjects)
|
|
4168
|
+
- \`sdk.getNearbyPlayers()\` — nearby players (NOT bot.nearbyPlayers)
|
|
4169
|
+
- \`sdk.getNearbyLocs()\` — nearby objects (NOT bot.nearbyObjects)
|
|
4170
|
+
- \`sdk.getInventory()\` — your inventory
|
|
4171
|
+
- \`sdk.getEquipment()\` — your equipment
|
|
4172
|
+
- \`sdk.sendWalk(x, z)\` — click-walk (fast, no pathfinding)
|
|
4173
|
+
- \`sdk.sendPickup(x, z, itemId)\` — raw pickup
|
|
4174
|
+
- \`sdk.waitForTicks(n)\` — wait n game ticks (~0.6s each)
|
|
4175
|
+
|
|
4176
|
+
**\`actions\` (pre-built strategies — USE THESE FIRST):**
|
|
4177
|
+
- \`actions.lootAndEquip()\` — grab + equip best gear
|
|
4178
|
+
- \`actions.fightLoop()\` — find and fight nearest player with auto-eat
|
|
4179
|
+
|
|
4180
|
+
**Common mistakes that WASTE TURNS:**
|
|
4181
|
+
- ❌ \`bot.equip()\` → ✅ \`bot.equipItem()\`
|
|
4182
|
+
- ❌ \`bot.pickup()\` → ✅ \`bot.pickupItem()\`
|
|
4183
|
+
- ❌ \`bot.nearbyObjects()\` → ✅ \`sdk.getNearbyLocs()\`
|
|
4184
|
+
- ❌ \`bot.getGroundItems()\` → ��� \`sdk.getGroundItems()\`
|
|
4185
|
+
- ❌ \`bot.eatFood()\` (no args) → ✅ \`bot.eatFood(/lobster|swordfish|salmon|trout|bread|meat/i)\`
|
|
4186
|
+
|
|
4187
|
+
---
|
|
4188
|
+
|
|
4125
4189
|
## Joining a Game
|
|
4126
4190
|
|
|
4127
4191
|
Call \`join_game\` with no arguments to see what's available:
|
|
@@ -4749,8 +4813,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
|
4749
4813
|
}
|
|
4750
4814
|
}
|
|
4751
4815
|
try {
|
|
4752
|
-
const
|
|
4753
|
-
const webBase =
|
|
4816
|
+
const isLocal2 = SERVER_URL === "localhost" || SERVER_URL === "127.0.0.1";
|
|
4817
|
+
const webBase = isLocal2 ? `http://localhost:8888` : `https://${SERVER_URL}`;
|
|
4754
4818
|
const aliveRes = await fetch(`${webBase}/api/agent-alive?username=${encodeURIComponent(username.toLowerCase())}`);
|
|
4755
4819
|
const aliveData = await aliveRes.json();
|
|
4756
4820
|
if (aliveData.alive === false) {
|
|
@@ -4996,8 +5060,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
|
4996
5060
|
if (!connection) {
|
|
4997
5061
|
return errorResponse("Not connected. Call login first.");
|
|
4998
5062
|
}
|
|
4999
|
-
const
|
|
5000
|
-
const webBase =
|
|
5063
|
+
const isLocal2 = SERVER_URL === "localhost" || SERVER_URL === "127.0.0.1";
|
|
5064
|
+
const webBase = isLocal2 ? `http://localhost:8888` : `https://${SERVER_URL}`;
|
|
5001
5065
|
const availRes = await fetch(`${webBase}/api/game/available`);
|
|
5002
5066
|
const available = await availRes.json();
|
|
5003
5067
|
if (available.status === "active") {
|