paralith-mcp 0.3.0 → 0.3.1
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/chains.json +15 -1
- package/dist/http.mjs +56 -7
- package/dist/server.mjs +57 -8
- package/package.json +1 -1
package/dist/chains.json
CHANGED
|
@@ -146,5 +146,19 @@
|
|
|
146
146
|
"solana": "9eVvxEPKgpQ4Y2BZV8BWVAeRHWWfSEJy3vrM2AFNzdQ2",
|
|
147
147
|
"sui": "0x46bd8f40263f6e056262f82f13c61d0849d813a030cde4c5bd6a8dd768144e9f",
|
|
148
148
|
"ao": "z2OMYtbWHqNZY01ehkN0tsepznlrZQW-6dXPQO5lxDM"
|
|
149
|
-
}
|
|
149
|
+
},
|
|
150
|
+
"nodes": [
|
|
151
|
+
{
|
|
152
|
+
"ao": "tkqULqMDeHKXCN79Cm_bDIV560JxXl6pBSmdPgxqwSw",
|
|
153
|
+
"url": "https://hyperbeam.tylerw.ai"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"ao": "lcP5YsqL7SGNgylyzqlEO2M7VU6ntGUGNSSNO2WeytI",
|
|
157
|
+
"url": "https://hb.paralithmarkets.com"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"ao": "yUPIU4jjmkeR1RVACTj5__KavHcMoNoQ_Ly80F7u3GQ",
|
|
161
|
+
"url": "https://hb.randao.net"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
150
164
|
}
|
package/dist/http.mjs
CHANGED
|
@@ -304,11 +304,27 @@ import { z as z9 } from "zod";
|
|
|
304
304
|
|
|
305
305
|
// src/tool.mjs
|
|
306
306
|
import { z } from "zod";
|
|
307
|
+
var migrationSeen = null;
|
|
308
|
+
async function migrationRefusal(read = readKey, now = Date.now()) {
|
|
309
|
+
if (!migrationSeen || now - migrationSeen.at > 15e3) {
|
|
310
|
+
migrationSeen = { at: now, value: await read("game", "migration").catch(() => null) };
|
|
311
|
+
}
|
|
312
|
+
const m = migrationSeen.value;
|
|
313
|
+
if (!m || typeof m !== "object" || m.phase === "live") return null;
|
|
314
|
+
if (m.phase === "retired") {
|
|
315
|
+
return `Paralith has moved to new processes (the game is now ${m.successor}). Nothing was sent. Update paralith-mcp to its latest version to use them.`;
|
|
316
|
+
}
|
|
317
|
+
return "A migration is in progress: Paralith is paused while every balance moves to new processes. Nothing was sent, and nothing is lost. Reads still work; try writes again later.";
|
|
318
|
+
}
|
|
307
319
|
function tool(server, name, description, inputSchema, run, annotations = {}, view = null) {
|
|
308
320
|
if (READ_ONLY && annotations !== READ) return;
|
|
309
321
|
const schema = view ? { ...inputSchema, full: z.boolean().optional().describe("Return the raw record instead of the compact view.") } : inputSchema;
|
|
310
322
|
server.registerTool(name, { description, inputSchema: schema, annotations }, async (args) => {
|
|
311
323
|
try {
|
|
324
|
+
if (annotations === WRITE) {
|
|
325
|
+
const refusal = await migrationRefusal();
|
|
326
|
+
if (refusal) return { isError: true, content: [{ type: "text", text: refusal }] };
|
|
327
|
+
}
|
|
312
328
|
const raw = await run(args ?? {});
|
|
313
329
|
const value = view && !args?.full ? await view(raw) : raw;
|
|
314
330
|
const text = typeof value === "string" ? value : JSON.stringify(value, bigints, 2);
|
|
@@ -562,7 +578,7 @@ function registerGame(server) {
|
|
|
562
578
|
tool(
|
|
563
579
|
server,
|
|
564
580
|
"game_daily",
|
|
565
|
-
"Claim the daily crate and Rune. Once per UTC day.",
|
|
581
|
+
"Claim the daily crate (and accrued Rune, pass holders only). Once per UTC day.",
|
|
566
582
|
{},
|
|
567
583
|
async () => (await me()).api.claimDaily(),
|
|
568
584
|
WRITE,
|
|
@@ -1667,7 +1683,8 @@ import fs4 from "node:fs";
|
|
|
1667
1683
|
import path4 from "node:path";
|
|
1668
1684
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1669
1685
|
import { z as z7 } from "zod";
|
|
1670
|
-
import {
|
|
1686
|
+
import { spawn } from "node:child_process";
|
|
1687
|
+
import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE, getUiCapability } from "@modelcontextprotocol/ext-apps/server";
|
|
1671
1688
|
var GAME = (process.env.PARALITH_GAME_URL || "https://game.paralithmarkets.com").replace(/\/$/, "");
|
|
1672
1689
|
var TRADE = (process.env.PARALITH_TRADE_URL || "https://trade.paralithmarkets.com").replace(/\/$/, "");
|
|
1673
1690
|
var URI = "ui://paralith/view";
|
|
@@ -1700,6 +1717,16 @@ async function ownAddress() {
|
|
|
1700
1717
|
const { wallets } = await runtime();
|
|
1701
1718
|
return wallets?.ao.address;
|
|
1702
1719
|
}
|
|
1720
|
+
function openInBrowser(url) {
|
|
1721
|
+
const [cmd, args] = process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url]] : process.platform === "darwin" ? ["open", [url]] : ["xdg-open", [url]];
|
|
1722
|
+
try {
|
|
1723
|
+
spawn(cmd, args, { detached: true, stdio: "ignore" }).on("error", () => {
|
|
1724
|
+
}).unref();
|
|
1725
|
+
return true;
|
|
1726
|
+
} catch {
|
|
1727
|
+
return false;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1703
1730
|
function registerShow(server) {
|
|
1704
1731
|
const csp = { frameDomains: [GAME, TRADE] };
|
|
1705
1732
|
registerAppResource(
|
|
@@ -1710,7 +1737,7 @@ function registerShow(server) {
|
|
|
1710
1737
|
async () => ({ contents: [{ uri: URI, mimeType: RESOURCE_MIME_TYPE, text: viewHtml(), _meta: { ui: { csp } } }] })
|
|
1711
1738
|
);
|
|
1712
1739
|
registerAppTool(server, "show", {
|
|
1713
|
-
description: "Show something with the game's and exchange's own visuals, live: battle (follows a player's arena fights, animated), companion (card), hunt, market (order book and chart), vault, position, bridge (transfers).
|
|
1740
|
+
description: "Show something with the game's and exchange's own visuals, live: battle (follows a player's arena fights, animated), companion (card), hunt, market (order book and chart), vault, position, bridge (transfers). Seeing it is a far better experience than reading about it: call show whenever you do something worth watching. It displays inline where the client supports that, and otherwise (local server) opens in the user's browser. Address defaults to yours.",
|
|
1714
1741
|
inputSchema: {
|
|
1715
1742
|
what: z7.enum(Object.keys(VIEWS)),
|
|
1716
1743
|
address: z7.string().optional().describe("AO address; omit for yours."),
|
|
@@ -1721,14 +1748,19 @@ function registerShow(server) {
|
|
|
1721
1748
|
market: z7.string().optional().describe("market/vault: the market, as exchange_markets lists it."),
|
|
1722
1749
|
vault: z7.enum(["amm", "active", "grid"]).optional(),
|
|
1723
1750
|
chain: z7.enum(["base", "solana", "sui"]).optional().describe("bridge: with tx, one transfer."),
|
|
1724
|
-
tx: z7.string().optional()
|
|
1751
|
+
tx: z7.string().optional(),
|
|
1752
|
+
open: z7.boolean().optional().describe("Open in the user's browser. Default: only when this client cannot display it inline.")
|
|
1725
1753
|
},
|
|
1726
1754
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
1727
1755
|
_meta: { ui: { resourceUri: URI } }
|
|
1728
1756
|
}, async (args) => {
|
|
1729
1757
|
try {
|
|
1730
1758
|
const view = VIEWS[args.what]({ ...args, address: args.address ?? await ownAddress() });
|
|
1731
|
-
|
|
1759
|
+
const inline = !!getUiCapability(server.server.getClientCapabilities());
|
|
1760
|
+
const opened = !READ_ONLY && (args.open ?? !inline) && openInBrowser(view);
|
|
1761
|
+
const where = inline ? "Displayed inline." : opened ? "Opened in the user's browser." : "Give the user this link.";
|
|
1762
|
+
return { structuredContent: { what: args.what, view }, content: [{ type: "text", text: `${args.what}: ${view}
|
|
1763
|
+
${where}` }] };
|
|
1732
1764
|
} catch (error) {
|
|
1733
1765
|
return { isError: true, content: [{ type: "text", text: error.message }] };
|
|
1734
1766
|
}
|
|
@@ -1847,9 +1879,26 @@ Vaults (pooled liquidity, one amm/active/grid per market): vault_list, vault_pos
|
|
|
1847
1879
|
Rune: rune_move withdraw (game -> token) / deposit (token -> game). Bridge: bridge_balances, bridge_faucet, bridge_deposit, bridge_redeem.
|
|
1848
1880
|
DAO (stake TEST-RUNE; a passed proposal may send one attached message): dao_info, dao_proposals, dao_stake stake/unstake/withdraw, dao_propose, dao_vote.
|
|
1849
1881
|
|
|
1882
|
+
HOW RESOURCES FLOW. When asked for a resource, find its path here, check what you hold (progress), then say the route before acting.
|
|
1883
|
+
- Gold (in-game only, never leaves the game). Earn: companion play/quest/claim (capped at 60 Gold per 20 h), arena bot wins,
|
|
1884
|
+
selling berries/Scrolls/Rune to the shop (game_shop sell) or on the game venue. Spend: arena stakes, shop buys, game-venue buys.
|
|
1885
|
+
- Berries and Scrolls. Get: joining, crates (game_daily, game_lootbox), buying with Gold (game_shop, or exchange_order venue "game").
|
|
1886
|
+
Use: feed the companion, hunt escrow (2 of each berry), arena boosts; a Scroll plus 1-3 Rune for a hunt capture.
|
|
1887
|
+
- Rune exists twice: in-game Rune and the TEST-RUNE wallet token; rune_move converts 1:1 either way.
|
|
1888
|
+
Get Rune: (1) the shop, only if game_shop quote shows an ask (it often only bids); (2) sell a companion on companion_market;
|
|
1889
|
+
(3) the token route, which always works: element_claim (free daily, 1-10 of one element) -> exchange_order venue "token"
|
|
1890
|
+
sell that element for TEST-RUNE -> rune_move deposit. Public TEST accounts accrue no Rune from game_daily (pass holders only).
|
|
1891
|
+
Spend in-game Rune: game_level_up, hunt capture, companion_market buys. TEST-RUNE: token-venue buys, vaults, dao_stake.
|
|
1892
|
+
- Element tokens (TEST-EARTH/AIR/FIRE/WATER): element_claim daily; trade against TEST-RUNE on the token venue; vault liquidity.
|
|
1893
|
+
- PUSD: bridge in TEST-USDC from Base, Solana or Sui (needs that chain's gas, which the user funds; bridge_faucet gives TEST-USDC).
|
|
1894
|
+
No PUSD market is listed yet. Redeeming back out needs a release claim this server cannot submit yet: say so rather than start it.
|
|
1895
|
+
- Vaults: deposit both sides of a market to earn from its strategy; withdraw with vault_shares.
|
|
1896
|
+
|
|
1850
1897
|
To report how you (or every agent set up on this machine) are doing, call progress (who: "all" for every agent); it also lists what needs doing next.
|
|
1851
1898
|
|
|
1852
|
-
|
|
1899
|
+
SHOW IT. Watching beats reading: call show for anything worth seeing (a fight as it happens, the companion after a level-up, the book
|
|
1900
|
+
you are trading, a vault, a bridge transfer). It displays inline where the client supports it, otherwise it opens in the user's browser.
|
|
1901
|
+
Show once per thing, not once per round.
|
|
1853
1902
|
|
|
1854
1903
|
Rules: if a tool says a write WAS accepted but unconfirmed, never resend it; re-read state instead.
|
|
1855
1904
|
A refusal ({"error": ...}) costs nothing. Use game_catalog for exact costs and move stats; docs at ${DOCS}/llms-full.txt.`;
|
|
@@ -1857,7 +1906,7 @@ var READ_ONLY_NOTE = `This endpoint is READ-ONLY: it explains the protocol and r
|
|
|
1857
1906
|
To play, trade or bridge, run the local server with a wallet phrase: ${DOCS}/ai/mcp`;
|
|
1858
1907
|
function buildServer() {
|
|
1859
1908
|
const server = new McpServer(
|
|
1860
|
-
{ name: "paralith", version: "0.3.
|
|
1909
|
+
{ name: "paralith", version: "0.3.1" },
|
|
1861
1910
|
{ instructions: READ_ONLY ? `${READ_ONLY_NOTE}
|
|
1862
1911
|
|
|
1863
1912
|
${INSTRUCTIONS}` : INSTRUCTIONS }
|
package/dist/server.mjs
CHANGED
|
@@ -513,11 +513,26 @@ var init_runtime = __esm({
|
|
|
513
513
|
|
|
514
514
|
// src/tool.mjs
|
|
515
515
|
import { z } from "zod";
|
|
516
|
+
async function migrationRefusal(read = readKey, now = Date.now()) {
|
|
517
|
+
if (!migrationSeen || now - migrationSeen.at > 15e3) {
|
|
518
|
+
migrationSeen = { at: now, value: await read("game", "migration").catch(() => null) };
|
|
519
|
+
}
|
|
520
|
+
const m = migrationSeen.value;
|
|
521
|
+
if (!m || typeof m !== "object" || m.phase === "live") return null;
|
|
522
|
+
if (m.phase === "retired") {
|
|
523
|
+
return `Paralith has moved to new processes (the game is now ${m.successor}). Nothing was sent. Update paralith-mcp to its latest version to use them.`;
|
|
524
|
+
}
|
|
525
|
+
return "A migration is in progress: Paralith is paused while every balance moves to new processes. Nothing was sent, and nothing is lost. Reads still work; try writes again later.";
|
|
526
|
+
}
|
|
516
527
|
function tool(server, name, description, inputSchema, run2, annotations = {}, view = null) {
|
|
517
528
|
if (READ_ONLY && annotations !== READ) return;
|
|
518
529
|
const schema = view ? { ...inputSchema, full: z.boolean().optional().describe("Return the raw record instead of the compact view.") } : inputSchema;
|
|
519
530
|
server.registerTool(name, { description, inputSchema: schema, annotations }, async (args) => {
|
|
520
531
|
try {
|
|
532
|
+
if (annotations === WRITE) {
|
|
533
|
+
const refusal = await migrationRefusal();
|
|
534
|
+
if (refusal) return { isError: true, content: [{ type: "text", text: refusal }] };
|
|
535
|
+
}
|
|
521
536
|
const raw = await run2(args ?? {});
|
|
522
537
|
const value = view && !args?.full ? await view(raw) : raw;
|
|
523
538
|
const text = typeof value === "string" ? value : JSON.stringify(value, bigints, 2);
|
|
@@ -537,11 +552,12 @@ The message WAS accepted (slot ${error?.slot ?? "?"}); its result could not be c
|
|
|
537
552
|
}
|
|
538
553
|
return message;
|
|
539
554
|
}
|
|
540
|
-
var bigints, READ, OWN, WRITE;
|
|
555
|
+
var migrationSeen, bigints, READ, OWN, WRITE;
|
|
541
556
|
var init_tool = __esm({
|
|
542
557
|
"src/tool.mjs"() {
|
|
543
558
|
"use strict";
|
|
544
559
|
init_runtime();
|
|
560
|
+
migrationSeen = null;
|
|
545
561
|
bigints = (_k, v) => typeof v === "bigint" ? v.toString() : v;
|
|
546
562
|
READ = { readOnlyHint: true, openWorldHint: true };
|
|
547
563
|
OWN = { readOnlyHint: true, openWorldHint: true };
|
|
@@ -780,7 +796,7 @@ function registerGame(server) {
|
|
|
780
796
|
tool(
|
|
781
797
|
server,
|
|
782
798
|
"game_daily",
|
|
783
|
-
"Claim the daily crate and Rune. Once per UTC day.",
|
|
799
|
+
"Claim the daily crate (and accrued Rune, pass holders only). Once per UTC day.",
|
|
784
800
|
{},
|
|
785
801
|
async () => (await me()).api.claimDaily(),
|
|
786
802
|
WRITE,
|
|
@@ -1928,7 +1944,8 @@ import fs5 from "node:fs";
|
|
|
1928
1944
|
import path5 from "node:path";
|
|
1929
1945
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1930
1946
|
import { z as z7 } from "zod";
|
|
1931
|
-
import {
|
|
1947
|
+
import { spawn } from "node:child_process";
|
|
1948
|
+
import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE, getUiCapability } from "@modelcontextprotocol/ext-apps/server";
|
|
1932
1949
|
function viewHtml() {
|
|
1933
1950
|
for (const file of [path5.join(HERE2, "view.html"), path5.join(HERE2, "..", "dist", "view.html")]) {
|
|
1934
1951
|
if (fs5.existsSync(file)) return fs5.readFileSync(file, "utf8");
|
|
@@ -1944,6 +1961,16 @@ async function ownAddress() {
|
|
|
1944
1961
|
const { wallets } = await runtime();
|
|
1945
1962
|
return wallets?.ao.address;
|
|
1946
1963
|
}
|
|
1964
|
+
function openInBrowser(url) {
|
|
1965
|
+
const [cmd, args] = process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url]] : process.platform === "darwin" ? ["open", [url]] : ["xdg-open", [url]];
|
|
1966
|
+
try {
|
|
1967
|
+
spawn(cmd, args, { detached: true, stdio: "ignore" }).on("error", () => {
|
|
1968
|
+
}).unref();
|
|
1969
|
+
return true;
|
|
1970
|
+
} catch {
|
|
1971
|
+
return false;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1947
1974
|
function registerShow(server) {
|
|
1948
1975
|
const csp = { frameDomains: [GAME, TRADE] };
|
|
1949
1976
|
registerAppResource(
|
|
@@ -1954,7 +1981,7 @@ function registerShow(server) {
|
|
|
1954
1981
|
async () => ({ contents: [{ uri: URI, mimeType: RESOURCE_MIME_TYPE, text: viewHtml(), _meta: { ui: { csp } } }] })
|
|
1955
1982
|
);
|
|
1956
1983
|
registerAppTool(server, "show", {
|
|
1957
|
-
description: "Show something with the game's and exchange's own visuals, live: battle (follows a player's arena fights, animated), companion (card), hunt, market (order book and chart), vault, position, bridge (transfers).
|
|
1984
|
+
description: "Show something with the game's and exchange's own visuals, live: battle (follows a player's arena fights, animated), companion (card), hunt, market (order book and chart), vault, position, bridge (transfers). Seeing it is a far better experience than reading about it: call show whenever you do something worth watching. It displays inline where the client supports that, and otherwise (local server) opens in the user's browser. Address defaults to yours.",
|
|
1958
1985
|
inputSchema: {
|
|
1959
1986
|
what: z7.enum(Object.keys(VIEWS)),
|
|
1960
1987
|
address: z7.string().optional().describe("AO address; omit for yours."),
|
|
@@ -1965,14 +1992,19 @@ function registerShow(server) {
|
|
|
1965
1992
|
market: z7.string().optional().describe("market/vault: the market, as exchange_markets lists it."),
|
|
1966
1993
|
vault: z7.enum(["amm", "active", "grid"]).optional(),
|
|
1967
1994
|
chain: z7.enum(["base", "solana", "sui"]).optional().describe("bridge: with tx, one transfer."),
|
|
1968
|
-
tx: z7.string().optional()
|
|
1995
|
+
tx: z7.string().optional(),
|
|
1996
|
+
open: z7.boolean().optional().describe("Open in the user's browser. Default: only when this client cannot display it inline.")
|
|
1969
1997
|
},
|
|
1970
1998
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
1971
1999
|
_meta: { ui: { resourceUri: URI } }
|
|
1972
2000
|
}, async (args) => {
|
|
1973
2001
|
try {
|
|
1974
2002
|
const view = VIEWS[args.what]({ ...args, address: args.address ?? await ownAddress() });
|
|
1975
|
-
|
|
2003
|
+
const inline = !!getUiCapability(server.server.getClientCapabilities());
|
|
2004
|
+
const opened = !READ_ONLY && (args.open ?? !inline) && openInBrowser(view);
|
|
2005
|
+
const where = inline ? "Displayed inline." : opened ? "Opened in the user's browser." : "Give the user this link.";
|
|
2006
|
+
return { structuredContent: { what: args.what, view }, content: [{ type: "text", text: `${args.what}: ${view}
|
|
2007
|
+
${where}` }] };
|
|
1976
2008
|
} catch (error) {
|
|
1977
2009
|
return { isError: true, content: [{ type: "text", text: error.message }] };
|
|
1978
2010
|
}
|
|
@@ -2120,7 +2152,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2120
2152
|
import { z as z9 } from "zod";
|
|
2121
2153
|
function buildServer() {
|
|
2122
2154
|
const server = new McpServer(
|
|
2123
|
-
{ name: "paralith", version: "0.3.
|
|
2155
|
+
{ name: "paralith", version: "0.3.1" },
|
|
2124
2156
|
{ instructions: READ_ONLY ? `${READ_ONLY_NOTE}
|
|
2125
2157
|
|
|
2126
2158
|
${INSTRUCTIONS}` : INSTRUCTIONS }
|
|
@@ -2225,9 +2257,26 @@ Vaults (pooled liquidity, one amm/active/grid per market): vault_list, vault_pos
|
|
|
2225
2257
|
Rune: rune_move withdraw (game -> token) / deposit (token -> game). Bridge: bridge_balances, bridge_faucet, bridge_deposit, bridge_redeem.
|
|
2226
2258
|
DAO (stake TEST-RUNE; a passed proposal may send one attached message): dao_info, dao_proposals, dao_stake stake/unstake/withdraw, dao_propose, dao_vote.
|
|
2227
2259
|
|
|
2260
|
+
HOW RESOURCES FLOW. When asked for a resource, find its path here, check what you hold (progress), then say the route before acting.
|
|
2261
|
+
- Gold (in-game only, never leaves the game). Earn: companion play/quest/claim (capped at 60 Gold per 20 h), arena bot wins,
|
|
2262
|
+
selling berries/Scrolls/Rune to the shop (game_shop sell) or on the game venue. Spend: arena stakes, shop buys, game-venue buys.
|
|
2263
|
+
- Berries and Scrolls. Get: joining, crates (game_daily, game_lootbox), buying with Gold (game_shop, or exchange_order venue "game").
|
|
2264
|
+
Use: feed the companion, hunt escrow (2 of each berry), arena boosts; a Scroll plus 1-3 Rune for a hunt capture.
|
|
2265
|
+
- Rune exists twice: in-game Rune and the TEST-RUNE wallet token; rune_move converts 1:1 either way.
|
|
2266
|
+
Get Rune: (1) the shop, only if game_shop quote shows an ask (it often only bids); (2) sell a companion on companion_market;
|
|
2267
|
+
(3) the token route, which always works: element_claim (free daily, 1-10 of one element) -> exchange_order venue "token"
|
|
2268
|
+
sell that element for TEST-RUNE -> rune_move deposit. Public TEST accounts accrue no Rune from game_daily (pass holders only).
|
|
2269
|
+
Spend in-game Rune: game_level_up, hunt capture, companion_market buys. TEST-RUNE: token-venue buys, vaults, dao_stake.
|
|
2270
|
+
- Element tokens (TEST-EARTH/AIR/FIRE/WATER): element_claim daily; trade against TEST-RUNE on the token venue; vault liquidity.
|
|
2271
|
+
- PUSD: bridge in TEST-USDC from Base, Solana or Sui (needs that chain's gas, which the user funds; bridge_faucet gives TEST-USDC).
|
|
2272
|
+
No PUSD market is listed yet. Redeeming back out needs a release claim this server cannot submit yet: say so rather than start it.
|
|
2273
|
+
- Vaults: deposit both sides of a market to earn from its strategy; withdraw with vault_shares.
|
|
2274
|
+
|
|
2228
2275
|
To report how you (or every agent set up on this machine) are doing, call progress (who: "all" for every agent); it also lists what needs doing next.
|
|
2229
2276
|
|
|
2230
|
-
|
|
2277
|
+
SHOW IT. Watching beats reading: call show for anything worth seeing (a fight as it happens, the companion after a level-up, the book
|
|
2278
|
+
you are trading, a vault, a bridge transfer). It displays inline where the client supports it, otherwise it opens in the user's browser.
|
|
2279
|
+
Show once per thing, not once per round.
|
|
2231
2280
|
|
|
2232
2281
|
Rules: if a tool says a write WAS accepted but unconfirmed, never resend it; re-read state instead.
|
|
2233
2282
|
A refusal ({"error": ...}) costs nothing. Use game_catalog for exact costs and move stats; docs at ${DOCS}/llms-full.txt.`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paralith-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "MCP server for Paralith on AO: an AI with one 24-word phrase plays Rune Realm, trades and bridges PUSD (TEST deployment).",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://docs.paralithmarkets.com/ai/mcp",
|