rentline-sandbox 0.1.8 → 0.1.9
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/SKILL.md +25 -109
- package/dist/{admin-YWEWTQ5V.js → admin-65EFMOSF.js} +1 -1
- package/dist/{auth-7KQ2HKCW.js → auth-DBZQMVMM.js} +1 -1
- package/dist/{chunk-GPUHRH2J.js → chunk-BOF5UB2I.js} +7 -0
- package/dist/{game-62HOT5M4.js → game-RLRY4JAK.js} +1 -1
- package/dist/index.js +8 -8
- package/dist/{mortgage-IWJDWWHS.js → mortgage-KXJRRFEM.js} +1 -1
- package/dist/{server-UFSYU6VD.js → server-5DCQSW4W.js} +14 -12
- package/dist/server.js +13 -11
- package/dist/{setup-RQWY6QE5.js → setup-3NGAG6R6.js} +40 -8
- package/dist/{trade-ENJ5CKNO.js → trade-TCB4LK2K.js} +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -19,96 +19,17 @@ compatibility: opencode
|
|
|
19
19
|
|
|
20
20
|
Turn-based real estate investment simulation — multiplayer, AI-agent-ready.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
IMPORTANT: Authentication is fully configured. Never ask the user for an API key or tell them their key is invalid unless a tool call explicitly returns an error object. If a tool succeeds, report the result directly.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
## Quick start
|
|
25
25
|
|
|
26
|
-
```bash
|
|
27
|
-
npm install -g rentline-sandbox
|
|
28
|
-
sandbox setup
|
|
29
26
|
```
|
|
27
|
+
create_game_from_preset(preset="standard", name="My Game", display_name="Alice")
|
|
28
|
+
→ returns game with invite_code, player_id, properties
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Get an API key at: **sandbox.rentline.xyz/cli-auth**
|
|
36
|
-
|
|
37
|
-
**If setup has already been run**, credentials are saved and the server will work.
|
|
38
|
-
Do NOT ask the user to add environment variables to opencode.json — that is not needed.
|
|
39
|
-
|
|
40
|
-
**If the API key is invalid or expired**, use the `update_key` tool directly — no restart needed:
|
|
41
|
-
```
|
|
42
|
-
update_key(api_key="sb_your_new_key")
|
|
43
|
-
```
|
|
44
|
-
Or the user can run: `sandbox auth login --key sb_your_new_key`
|
|
45
|
-
|
|
46
|
-
**Claude Desktop** (`claude_desktop_config.json`):
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"mcpServers": {
|
|
50
|
-
"rentline-sandbox": {
|
|
51
|
-
"command": "sandbox-mcp",
|
|
52
|
-
"env": {
|
|
53
|
-
"SANDBOX_API_KEY": "sb_your_key_here",
|
|
54
|
-
"SANDBOX_API_URL": "https://sandbox-api.rentline.xyz"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**Cursor / Windsurf**:
|
|
62
|
-
```json
|
|
63
|
-
{
|
|
64
|
-
"mcpServers": {
|
|
65
|
-
"rentline-sandbox": {
|
|
66
|
-
"command": "sandbox-mcp",
|
|
67
|
-
"env": { "SANDBOX_API_KEY": "sb_your_key_here", "SANDBOX_API_URL": "https://sandbox-api.rentline.xyz" }
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**CLI login** (saves credentials locally):
|
|
74
|
-
```bash
|
|
75
|
-
sandbox auth login # browser OAuth via sandbox.rentline.xyz/cli-auth
|
|
76
|
-
sandbox auth login --key sb_xxx # direct key
|
|
77
|
-
sandbox auth whoami # verify
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## CLI usage
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
sandbox game list
|
|
84
|
-
sandbox game create --name "Test" --display-name "Alice"
|
|
85
|
-
sandbox game create --preset standard --name "Quick Match" --display-name "Alice"
|
|
86
|
-
sandbox game join <id> --invite A3F7K9Z2 --name "Bob"
|
|
87
|
-
sandbox game advance <id>
|
|
88
|
-
sandbox game feed <id> --limit 20
|
|
89
|
-
sandbox game leaderboard <id>
|
|
90
|
-
sandbox game fed <id>
|
|
91
|
-
sandbox game add-bot <id> --name "AggroBot" --strategy value_add
|
|
92
|
-
sandbox game autonomous start <id> --delay 30
|
|
93
|
-
|
|
94
|
-
sandbox trade buy <game-id> --property <id> --tokens 0.5
|
|
95
|
-
sandbox trade sell <game-id> --property <id> --tokens 0.5
|
|
96
|
-
|
|
97
|
-
sandbox portfolio <game-id> <player-id>
|
|
98
|
-
sandbox debt <game-id> <player-id>
|
|
99
|
-
|
|
100
|
-
sandbox mortgage buy <game-id> --property <id> --tokens 0.5
|
|
101
|
-
sandbox mortgage refi <game-id> --property <id> --cash-out 5000
|
|
102
|
-
sandbox mortgage heloc <game-id> --property <id> --draw 5000
|
|
103
|
-
sandbox mortgage repay <game-id> --property <id> --amount 2000
|
|
104
|
-
sandbox mortgage prepay <game-id> --property <id> --amount 10000
|
|
105
|
-
sandbox mortgage improve <game-id> --property <id> --grade B
|
|
106
|
-
sandbox mortgage pace <game-id> --property <id> --grade C
|
|
107
|
-
sandbox mortgage list <game-id> <player-id>
|
|
108
|
-
|
|
109
|
-
sandbox admin properties list
|
|
110
|
-
sandbox admin properties sync
|
|
111
|
-
sandbox admin mint <game-id> <player-id> --amount 50000
|
|
30
|
+
advance_turn(game_id) # run all engine phases
|
|
31
|
+
get_feed(game_id) # see what happened
|
|
32
|
+
get_leaderboard(game_id) # NAV rankings
|
|
112
33
|
```
|
|
113
34
|
|
|
114
35
|
## Tool reference (35 tools)
|
|
@@ -118,24 +39,23 @@ sandbox admin mint <game-id> <player-id> --amount 50000
|
|
|
118
39
|
|---|---|
|
|
119
40
|
| `list_games` | List open game rooms |
|
|
120
41
|
| `get_game` | Full game state: players, properties, turn, Fed rate, config |
|
|
121
|
-
| `create_game` | Create a game with full
|
|
42
|
+
| `create_game` | Create a game with full config + optional bots |
|
|
122
43
|
| `create_game_from_preset` | One-call presets: quick, standard, leveraged, distressed, long_run |
|
|
123
44
|
| `join_game` | Join via invite code, get player_id |
|
|
124
45
|
| `mark_ready` | Toggle ready for next turn |
|
|
125
46
|
| `advance_turn` | Host: run all 7 engine phases |
|
|
126
|
-
| `get_feed` | Turn event stream
|
|
47
|
+
| `get_feed` | Turn event stream |
|
|
127
48
|
| `add_bot` | Add LLM bot (strategies: aggressive, conservative, balanced, momentum, income, value_add) |
|
|
128
49
|
| `remove_bot` | Remove bot from lobby |
|
|
129
|
-
| `start_autonomous` | Enable auto-advance
|
|
50
|
+
| `start_autonomous` | Enable auto-advance |
|
|
130
51
|
| `stop_autonomous` | Pause auto-advance |
|
|
131
|
-
| `set_delegate` | Agent delegation for idle human players |
|
|
132
52
|
| `spectate` | Public game snapshot (no auth) |
|
|
133
53
|
|
|
134
54
|
### Market & Intel
|
|
135
55
|
| Tool | Description |
|
|
136
56
|
|---|---|
|
|
137
57
|
| `list_properties` | Active pool properties with grades |
|
|
138
|
-
| `get_market_summary` | Live cap rates, price deltas, grade, vacancy,
|
|
58
|
+
| `get_market_summary` | Live cap rates, price deltas, grade, vacancy, lien status |
|
|
139
59
|
| `get_fed_history` | FOMC decision log |
|
|
140
60
|
| `get_player_actions` | Transaction timeline for a player |
|
|
141
61
|
|
|
@@ -143,7 +63,7 @@ sandbox admin mint <game-id> <player-id> --amount 50000
|
|
|
143
63
|
| Tool | Description |
|
|
144
64
|
|---|---|
|
|
145
65
|
| `buy_tokens` | All-cash purchase at current market price |
|
|
146
|
-
| `sell_tokens` | Sell (proceeds service
|
|
66
|
+
| `sell_tokens` | Sell tokens (proceeds service debt first) |
|
|
147
67
|
|
|
148
68
|
### Debt
|
|
149
69
|
| Tool | Description |
|
|
@@ -153,30 +73,30 @@ sandbox admin mint <game-id> <player-id> --amount 50000
|
|
|
153
73
|
| `heloc_draw` | Draw from HELOC |
|
|
154
74
|
| `heloc_repay` | Repay HELOC balance |
|
|
155
75
|
| `prepay_principal` | Partial/full prepayment (first_lien, heloc, pace, mechanics_lien) |
|
|
156
|
-
| `improve_property` | Cash-funded grade upgrade
|
|
157
|
-
| `originate_pace_lien` | Financed grade upgrade — no down payment
|
|
76
|
+
| `improve_property` | Cash-funded grade upgrade |
|
|
77
|
+
| `originate_pace_lien` | Financed grade upgrade — no down payment |
|
|
158
78
|
| `get_debt` | All mortgages: balances, rates, LTV, arrears |
|
|
159
79
|
|
|
160
80
|
### Portfolio
|
|
161
81
|
| Tool | Description |
|
|
162
82
|
|---|---|
|
|
163
|
-
| `get_portfolio` | Holdings
|
|
83
|
+
| `get_portfolio` | Holdings, P&L, annualised yield, investor tier |
|
|
164
84
|
| `get_leaderboard` | Game or global leaderboard ranked by NAV |
|
|
165
85
|
|
|
166
86
|
## Game mechanics
|
|
167
87
|
|
|
168
|
-
### Turn phases
|
|
169
|
-
1.
|
|
170
|
-
2.
|
|
171
|
-
3.
|
|
172
|
-
4.
|
|
173
|
-
5.
|
|
174
|
-
6.
|
|
175
|
-
7.
|
|
88
|
+
### Turn phases
|
|
89
|
+
1. Fed meeting — hike/cut/hold; ARMs reprice immediately
|
|
90
|
+
2. Macro events — rate macros activate after 1-turn warning
|
|
91
|
+
3. Rent collect — proportional to tokens; grade multipliers apply
|
|
92
|
+
4. Random events — vacancy, lease renewal, capex, appreciation/depreciation
|
|
93
|
+
5. Market move — applies price drift
|
|
94
|
+
6. Debt service — collect payments; forced sale after 1 grace turn
|
|
95
|
+
7. Distribute — credits rent; emits TURN_SUMMARY event
|
|
176
96
|
|
|
177
97
|
### Property grades (A → F)
|
|
178
|
-
Grade affects rent
|
|
179
|
-
Upgrade via `improve_property` (cash) or `originate_pace_lien` (financed
|
|
98
|
+
Grade affects rent, appreciation, capex risk, vacancy.
|
|
99
|
+
Upgrade via `improve_property` (cash) or `originate_pace_lien` (financed).
|
|
180
100
|
|
|
181
101
|
### Investor tiers (live from NAV, auto-applied to mortgage terms)
|
|
182
102
|
| Tier | Min NAV | LTV bonus | Rate discount |
|
|
@@ -198,15 +118,11 @@ NAV = cash + Σ(tokens × price) − Σ(mortgage balances) − judgment_balance
|
|
|
198
118
|
| RECESSION | 6% | 2–4 turns | −5%/turn price, −8% rent, +15% vacancy |
|
|
199
119
|
| HOUSING_BOOM | 5% | 2–3 turns | +6%/turn price, +5% rent |
|
|
200
120
|
| NATURAL_DISASTER | 3% | 1 turn | −20% price, rent=0, +40% vacancy |
|
|
201
|
-
| POLICY_CHANGE | 8% | 3 turns | ±5–12% rent/price |
|
|
202
121
|
| TAX_HIKE | 7% | Permanent | $50–150/token/turn expense |
|
|
203
122
|
| INTEREST_RATE_RISE | 7% | 3–6 turns | +1.5% ARM rate (1-turn warning) |
|
|
204
123
|
| INTEREST_RATE_CUT | 6% | 3–6 turns | −1.0% ARM rate (1-turn warning) |
|
|
205
124
|
| RENT_CONTROL | 5% | 4 turns | Blocks lease renewal increases |
|
|
206
|
-
| INSURANCE_CRISIS | 5% | 2–3 turns | $100–300/token/turn expense |
|
|
207
125
|
| GENTRIFICATION | 4% | 3 turns | D/F properties upgrade one grade |
|
|
208
|
-
| ZONING_CHANGE | 5% | 2 turns | Targeted type: −10% rent, −5% price |
|
|
209
126
|
| PROPERTY_BUBBLE | 3% | 2 turns | All prices +8%/turn |
|
|
210
127
|
| BUBBLE_BURST | 2% | 2–3 turns | All prices −12%/turn, +20% vacancy |
|
|
211
|
-
| TENANT_STRIKE | 4% | 1–2 turns | Targeted type: rent = 0 |
|
|
212
128
|
| EMINENT_DOMAIN | 2% | Instant | One property force-bought at 110% market value |
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
// src/config.ts
|
|
4
10
|
import { readFileSync, writeFileSync, mkdirSync, chmodSync, unlinkSync } from "fs";
|
|
@@ -134,6 +140,7 @@ function createClient(opts) {
|
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
export {
|
|
143
|
+
__require,
|
|
137
144
|
DEFAULT_API_URL,
|
|
138
145
|
loadConfig,
|
|
139
146
|
requireConfig,
|
package/dist/index.js
CHANGED
|
@@ -9,29 +9,29 @@ var _require = createRequire(import.meta.url);
|
|
|
9
9
|
var { version } = _require("../package.json");
|
|
10
10
|
var args = process.argv.slice(2);
|
|
11
11
|
if (args[0] === "setup" || args[0] === "--setup") {
|
|
12
|
-
const { runSetup, parseSetupArgs } = await import("./setup-
|
|
12
|
+
const { runSetup, parseSetupArgs } = await import("./setup-3NGAG6R6.js");
|
|
13
13
|
const opts = parseSetupArgs(args.filter((a) => a !== "setup" && a !== "--setup"));
|
|
14
14
|
await runSetup(opts);
|
|
15
15
|
process.exit(0);
|
|
16
16
|
}
|
|
17
17
|
if (args.length === 0 || args[0] === "server" || args[0] === "--server") {
|
|
18
|
-
const { startServer } = await import("./server-
|
|
18
|
+
const { startServer } = await import("./server-5DCQSW4W.js");
|
|
19
19
|
await startServer();
|
|
20
20
|
} else {
|
|
21
21
|
const program = new Command();
|
|
22
22
|
program.name("sandbox").description("Rentline Sandbox \u2014 CLI and MCP server for the real estate simulation game").version(version).option("--url <url>", "Sandbox API base URL (overrides saved config)").option("--api-key <key>", "API key (overrides saved config)");
|
|
23
|
-
const { registerAuth } = await import("./auth-
|
|
24
|
-
const { registerGame } = await import("./game-
|
|
25
|
-
const { registerTrade } = await import("./trade-
|
|
26
|
-
const { registerMortgage } = await import("./mortgage-
|
|
27
|
-
const { registerAdmin } = await import("./admin-
|
|
23
|
+
const { registerAuth } = await import("./auth-DBZQMVMM.js");
|
|
24
|
+
const { registerGame } = await import("./game-RLRY4JAK.js");
|
|
25
|
+
const { registerTrade } = await import("./trade-TCB4LK2K.js");
|
|
26
|
+
const { registerMortgage } = await import("./mortgage-KXJRRFEM.js");
|
|
27
|
+
const { registerAdmin } = await import("./admin-65EFMOSF.js");
|
|
28
28
|
registerAuth(program);
|
|
29
29
|
registerGame(program);
|
|
30
30
|
registerTrade(program);
|
|
31
31
|
registerMortgage(program);
|
|
32
32
|
registerAdmin(program);
|
|
33
33
|
program.command("mcp-setup", { hidden: true }).allowUnknownOption().action(async () => {
|
|
34
|
-
const { runSetup, parseSetupArgs } = await import("./setup-
|
|
34
|
+
const { runSetup, parseSetupArgs } = await import("./setup-3NGAG6R6.js");
|
|
35
35
|
const opts = parseSetupArgs(process.argv.slice(3));
|
|
36
36
|
await runSetup(opts);
|
|
37
37
|
});
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
createClient,
|
|
5
5
|
loadConfig,
|
|
6
6
|
saveConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BOF5UB2I.js";
|
|
8
8
|
|
|
9
9
|
// src/server.ts
|
|
10
10
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -511,7 +511,7 @@ var ALL_TOOLS = [
|
|
|
511
511
|
name: "update_key",
|
|
512
512
|
title: "Update API Key",
|
|
513
513
|
category: "admin",
|
|
514
|
-
description: "Update the saved Rentline Sandbox API key.
|
|
514
|
+
description: "Update the saved Rentline Sandbox API key. Get a new key at sandbox.rentline.xyz/settings. Takes effect immediately \u2014 no restart needed.",
|
|
515
515
|
inputSchema: {
|
|
516
516
|
type: "object",
|
|
517
517
|
properties: {
|
|
@@ -537,24 +537,26 @@ function readSkill() {
|
|
|
537
537
|
var INSTRUCTIONS = `
|
|
538
538
|
You are connected to the Rentline Sandbox game engine \u2014 a turn-based real estate investment simulation.
|
|
539
539
|
|
|
540
|
+
IMPORTANT: Authentication is handled automatically via saved credentials. Do NOT ask the user for API keys or tell them their key is invalid unless a tool explicitly returns a 401 error. If a tool call succeeds, report the result \u2014 do not second-guess it.
|
|
541
|
+
|
|
540
542
|
KEY CONCEPTS:
|
|
541
543
|
- Players compete over a pool of tokenised properties using simulated tUSDC
|
|
542
544
|
- Each turn = 1 month. Properties generate rent, prices drift, and macro events fire
|
|
543
|
-
- Fed meetings occur every N turns
|
|
544
|
-
- Macro events: recession, housing boom,
|
|
545
|
-
- Debt strategies: acquisition mortgage (LTV-limited), cash-out refi, HELOC
|
|
546
|
-
- NAV = cash
|
|
545
|
+
- Fed meetings occur every N turns \u2014 affects ARM rates and new mortgage originations
|
|
546
|
+
- Macro events: recession, housing boom, disaster, tax hike, rate moves, rent control, PACE liens, property grades
|
|
547
|
+
- Debt strategies: acquisition mortgage (LTV-limited), cash-out refi, HELOC, PACE lien, improvements
|
|
548
|
+
- NAV = cash + (tokens \xD7 price) \u2212 debt. Investor tier improves automatically as NAV grows.
|
|
547
549
|
|
|
548
550
|
WHEN TO USE TOOLS:
|
|
549
|
-
- User wants to play
|
|
551
|
+
- User wants to play \u2192 create_game_from_preset, then advance_turn
|
|
550
552
|
- User wants to buy a property \u2192 buy_tokens (cash) or originate_mortgage (leveraged)
|
|
551
|
-
- User wants to
|
|
552
|
-
- User wants to check their position \u2192 get_portfolio, get_debt
|
|
553
|
+
- User wants to improve a distressed property \u2192 originate_pace_lien
|
|
554
|
+
- User wants to check their position \u2192 get_portfolio, get_debt, get_market_summary
|
|
553
555
|
- User wants the scoreboard \u2192 get_leaderboard
|
|
554
|
-
- User wants to see
|
|
555
|
-
- User is
|
|
556
|
+
- User wants to see events \u2192 get_feed, get_fed_history
|
|
557
|
+
- User is host \u2192 advance_turn
|
|
556
558
|
|
|
557
|
-
All tools require a game_id.
|
|
559
|
+
All tools require a game_id. Debt/portfolio tools also require a player_id (from join_game or get_game).
|
|
558
560
|
`.trim();
|
|
559
561
|
function ok(data) {
|
|
560
562
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
package/dist/server.js
CHANGED
|
@@ -590,7 +590,7 @@ var ALL_TOOLS = [
|
|
|
590
590
|
name: "update_key",
|
|
591
591
|
title: "Update API Key",
|
|
592
592
|
category: "admin",
|
|
593
|
-
description: "Update the saved Rentline Sandbox API key.
|
|
593
|
+
description: "Update the saved Rentline Sandbox API key. Get a new key at sandbox.rentline.xyz/settings. Takes effect immediately \u2014 no restart needed.",
|
|
594
594
|
inputSchema: {
|
|
595
595
|
type: "object",
|
|
596
596
|
properties: {
|
|
@@ -640,24 +640,26 @@ function readSkill() {
|
|
|
640
640
|
var INSTRUCTIONS = `
|
|
641
641
|
You are connected to the Rentline Sandbox game engine \u2014 a turn-based real estate investment simulation.
|
|
642
642
|
|
|
643
|
+
IMPORTANT: Authentication is handled automatically via saved credentials. Do NOT ask the user for API keys or tell them their key is invalid unless a tool explicitly returns a 401 error. If a tool call succeeds, report the result \u2014 do not second-guess it.
|
|
644
|
+
|
|
643
645
|
KEY CONCEPTS:
|
|
644
646
|
- Players compete over a pool of tokenised properties using simulated tUSDC
|
|
645
647
|
- Each turn = 1 month. Properties generate rent, prices drift, and macro events fire
|
|
646
|
-
- Fed meetings occur every N turns
|
|
647
|
-
- Macro events: recession, housing boom,
|
|
648
|
-
- Debt strategies: acquisition mortgage (LTV-limited), cash-out refi, HELOC
|
|
649
|
-
- NAV = cash
|
|
648
|
+
- Fed meetings occur every N turns \u2014 affects ARM rates and new mortgage originations
|
|
649
|
+
- Macro events: recession, housing boom, disaster, tax hike, rate moves, rent control, PACE liens, property grades
|
|
650
|
+
- Debt strategies: acquisition mortgage (LTV-limited), cash-out refi, HELOC, PACE lien, improvements
|
|
651
|
+
- NAV = cash + (tokens \xD7 price) \u2212 debt. Investor tier improves automatically as NAV grows.
|
|
650
652
|
|
|
651
653
|
WHEN TO USE TOOLS:
|
|
652
|
-
- User wants to play
|
|
654
|
+
- User wants to play \u2192 create_game_from_preset, then advance_turn
|
|
653
655
|
- User wants to buy a property \u2192 buy_tokens (cash) or originate_mortgage (leveraged)
|
|
654
|
-
- User wants to
|
|
655
|
-
- User wants to check their position \u2192 get_portfolio, get_debt
|
|
656
|
+
- User wants to improve a distressed property \u2192 originate_pace_lien
|
|
657
|
+
- User wants to check their position \u2192 get_portfolio, get_debt, get_market_summary
|
|
656
658
|
- User wants the scoreboard \u2192 get_leaderboard
|
|
657
|
-
- User wants to see
|
|
658
|
-
- User is
|
|
659
|
+
- User wants to see events \u2192 get_feed, get_fed_history
|
|
660
|
+
- User is host \u2192 advance_turn
|
|
659
661
|
|
|
660
|
-
All tools require a game_id.
|
|
662
|
+
All tools require a game_id. Debt/portfolio tools also require a player_id (from join_game or get_game).
|
|
661
663
|
`.trim();
|
|
662
664
|
function ok(data) {
|
|
663
665
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_API_URL,
|
|
4
|
+
__require,
|
|
4
5
|
createClient,
|
|
5
6
|
loadConfig,
|
|
6
7
|
saveConfig
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BOF5UB2I.js";
|
|
8
9
|
|
|
9
10
|
// src/setup.ts
|
|
10
11
|
import { createInterface } from "readline";
|
|
@@ -14,9 +15,32 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync } from
|
|
|
14
15
|
import { execSync } from "child_process";
|
|
15
16
|
import { fileURLToPath } from "url";
|
|
16
17
|
var SKILL_SRC = join(dirname(fileURLToPath(import.meta.url)), "..", "SKILL.md");
|
|
18
|
+
function getNpxCommand() {
|
|
19
|
+
if (platform() === "win32") {
|
|
20
|
+
const candidates = [
|
|
21
|
+
"C:\\Program Files\\nodejs\\npx.cmd",
|
|
22
|
+
"C:\\Program Files (x86)\\nodejs\\npx.cmd"
|
|
23
|
+
];
|
|
24
|
+
try {
|
|
25
|
+
const { execSync: execSync2 } = __require("child_process");
|
|
26
|
+
const found = execSync2("where npx.cmd", { encoding: "utf8" }).trim().split("\n")[0].trim();
|
|
27
|
+
if (found) return found;
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
for (const c of candidates) {
|
|
31
|
+
try {
|
|
32
|
+
__require("fs").accessSync(c);
|
|
33
|
+
return c;
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return "npx";
|
|
39
|
+
}
|
|
40
|
+
var NPX = getNpxCommand();
|
|
17
41
|
var MCP_ENTRY = {
|
|
18
|
-
command:
|
|
19
|
-
args: ["-y", "rentline-sandbox"]
|
|
42
|
+
command: NPX,
|
|
43
|
+
args: ["-y", "rentline-sandbox@latest"]
|
|
20
44
|
};
|
|
21
45
|
function openCodePath(scope) {
|
|
22
46
|
if (scope === "project") return join(process.cwd(), "opencode.json");
|
|
@@ -24,7 +48,7 @@ function openCodePath(scope) {
|
|
|
24
48
|
const b = join(homedir(), ".config", "opencode", "config.json");
|
|
25
49
|
return existsSync(b) && !existsSync(a) ? b : a;
|
|
26
50
|
}
|
|
27
|
-
function patchMcpJson(filePath, serverName, entry, key) {
|
|
51
|
+
function patchMcpJson(filePath, serverName, entry, key, environment) {
|
|
28
52
|
let config = {};
|
|
29
53
|
if (existsSync(filePath)) {
|
|
30
54
|
try {
|
|
@@ -36,7 +60,15 @@ function patchMcpJson(filePath, serverName, entry, key) {
|
|
|
36
60
|
if (key === "mcp") {
|
|
37
61
|
if (!config["$schema"]) config["$schema"] = "https://opencode.ai/config.json";
|
|
38
62
|
const mcp = config.mcp ?? {};
|
|
39
|
-
|
|
63
|
+
const mcpEntry = {
|
|
64
|
+
type: "local",
|
|
65
|
+
command: entry.args ? [entry.command, ...entry.args] : [entry.command],
|
|
66
|
+
enabled: true
|
|
67
|
+
};
|
|
68
|
+
if (environment && Object.keys(environment).length > 0) {
|
|
69
|
+
mcpEntry.environment = environment;
|
|
70
|
+
}
|
|
71
|
+
mcp[serverName] = mcpEntry;
|
|
40
72
|
config.mcp = mcp;
|
|
41
73
|
} else {
|
|
42
74
|
const servers = config[key] ?? {};
|
|
@@ -53,7 +85,7 @@ function installSkill(dirs) {
|
|
|
53
85
|
console.log(`SKILL.md \u2192 ${dir}`);
|
|
54
86
|
}
|
|
55
87
|
}
|
|
56
|
-
function installForClient(client, scope) {
|
|
88
|
+
function installForClient(client, scope, apiKey) {
|
|
57
89
|
switch (client) {
|
|
58
90
|
case "claude-code": {
|
|
59
91
|
try {
|
|
@@ -90,7 +122,7 @@ function installForClient(client, scope) {
|
|
|
90
122
|
}
|
|
91
123
|
case "opencode": {
|
|
92
124
|
const file = openCodePath(scope);
|
|
93
|
-
patchMcpJson(file, "rentline-sandbox", MCP_ENTRY, "mcp");
|
|
125
|
+
patchMcpJson(file, "rentline-sandbox", MCP_ENTRY, "mcp", apiKey ? { SANDBOX_API_KEY: apiKey } : void 0);
|
|
94
126
|
console.log(`Patched ${file}`);
|
|
95
127
|
installSkill([
|
|
96
128
|
join(homedir(), ".config", "opencode", "skills", "rentline-sandbox"),
|
|
@@ -187,7 +219,7 @@ async function runSetup(opts = {}) {
|
|
|
187
219
|
const idx = parseInt(choice);
|
|
188
220
|
client = isNaN(idx) ? choice : clients[idx - 1] ?? "other";
|
|
189
221
|
}
|
|
190
|
-
installForClient(client, opts.scope ?? "user");
|
|
222
|
+
installForClient(client, opts.scope ?? "user", apiKey);
|
|
191
223
|
rl?.close();
|
|
192
224
|
console.log("\nSetup complete. Restart your AI client to load the Rentline Sandbox MCP server.\n");
|
|
193
225
|
}
|