@tamago-labs/wayfind-mcp 0.1.0 → 0.2.0
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/index.js +80 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/agent/index.ts +16 -3
- package/src/config.ts +7 -3
- package/src/index.ts +2 -2
- package/src/mcp/index.ts +12 -2
- package/src/mcp/wayfind/get_market_overview_tool.ts +11 -0
- package/src/mcp/wayfind/get_pre_ipo_tool.ts +11 -0
- package/src/mcp/wayfind/get_risk_profile_tool.ts +11 -0
- package/src/mcp/wayfind/get_tokenized_stocks_tool.ts +14 -0
- package/src/mcp/wayfind/get_tokens_tool.ts +14 -0
package/dist/index.js
CHANGED
|
@@ -39,9 +39,70 @@ var GetWalletAddressTool = {
|
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
+
// src/mcp/wayfind/get_tokens_tool.ts
|
|
43
|
+
var import_zod = require("zod");
|
|
44
|
+
var WayfindGetTokensTool = {
|
|
45
|
+
name: "wayfind_get_tokens",
|
|
46
|
+
description: "List all tokenized stocks with prices and market data",
|
|
47
|
+
schema: {
|
|
48
|
+
chain: import_zod.z.string().optional().describe("Filter by blockchain (e.g., 'solana', 'ethereum')")
|
|
49
|
+
},
|
|
50
|
+
handler: async (agent, input) => {
|
|
51
|
+
return agent.wayfindFetch("/tokens", input?.chain ? { chain: input.chain } : void 0);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/mcp/wayfind/get_tokenized_stocks_tool.ts
|
|
56
|
+
var import_zod2 = require("zod");
|
|
57
|
+
var WayfindGetTokenizedStocksTool = {
|
|
58
|
+
name: "wayfind_get_tokenized_stocks",
|
|
59
|
+
description: "Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)",
|
|
60
|
+
schema: {
|
|
61
|
+
ticker: import_zod2.z.string().describe("Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')")
|
|
62
|
+
},
|
|
63
|
+
handler: async (agent, input) => {
|
|
64
|
+
return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/mcp/wayfind/get_risk_profile_tool.ts
|
|
69
|
+
var WayfindGetRiskProfileTool = {
|
|
70
|
+
name: "wayfind_get_risk_profile",
|
|
71
|
+
description: "Get the user's portfolio risk profile including overall score, label, and answers",
|
|
72
|
+
schema: {},
|
|
73
|
+
handler: async (agent, _input) => {
|
|
74
|
+
return agent.wayfindFetch("/risk-profile");
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/mcp/wayfind/get_market_overview_tool.ts
|
|
79
|
+
var WayfindGetMarketOverviewTool = {
|
|
80
|
+
name: "wayfind_get_market_overview",
|
|
81
|
+
description: "Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens",
|
|
82
|
+
schema: {},
|
|
83
|
+
handler: async (agent, _input) => {
|
|
84
|
+
return agent.wayfindFetch("/market-overview");
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// src/mcp/wayfind/get_pre_ipo_tool.ts
|
|
89
|
+
var WayfindGetPreIpoTool = {
|
|
90
|
+
name: "wayfind_get_pre_ipo",
|
|
91
|
+
description: "List pre-IPO markets with mark prices and valuations",
|
|
92
|
+
schema: {},
|
|
93
|
+
handler: async (agent, _input) => {
|
|
94
|
+
return agent.wayfindFetch("/pre-ipo");
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
42
98
|
// src/mcp/index.ts
|
|
43
|
-
var
|
|
44
|
-
GetWalletAddressTool
|
|
99
|
+
var McpTools = {
|
|
100
|
+
SolanaGetWalletAddress: GetWalletAddressTool,
|
|
101
|
+
WayfindGetTokens: WayfindGetTokensTool,
|
|
102
|
+
WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,
|
|
103
|
+
WayfindGetRiskProfile: WayfindGetRiskProfileTool,
|
|
104
|
+
WayfindGetMarketOverview: WayfindGetMarketOverviewTool,
|
|
105
|
+
WayfindGetPreIpo: WayfindGetPreIpoTool
|
|
45
106
|
};
|
|
46
107
|
|
|
47
108
|
// src/agent/index.ts
|
|
@@ -55,20 +116,33 @@ function validateEnvironment() {
|
|
|
55
116
|
throw new Error("Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)");
|
|
56
117
|
}
|
|
57
118
|
const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
58
|
-
|
|
119
|
+
const wayfindApiKey = process.env.WAYFIND_API_KEY || "e1ee8520-305a-49b5-a2de-3e1a7e6078c0";
|
|
120
|
+
const wayfindApiUrl = process.env.WAYFIND_API_URL || "https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws";
|
|
121
|
+
return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };
|
|
59
122
|
}
|
|
60
123
|
|
|
61
124
|
// src/agent/index.ts
|
|
62
125
|
var Agent = class _Agent {
|
|
63
|
-
constructor(walletAddress) {
|
|
126
|
+
constructor(walletAddress, config) {
|
|
64
127
|
this.walletAddress = walletAddress;
|
|
128
|
+
this.config = config;
|
|
65
129
|
}
|
|
66
130
|
static async create() {
|
|
67
131
|
const config = validateEnvironment();
|
|
68
132
|
const decoded = import_bs58.default.decode(config.privateKey);
|
|
69
133
|
const seed = decoded.slice(0, 32);
|
|
70
134
|
const signer = await (0, import_kit.createKeyPairSignerFromPrivateKeyBytes)(seed, false);
|
|
71
|
-
return new _Agent(signer.address);
|
|
135
|
+
return new _Agent(signer.address, config);
|
|
136
|
+
}
|
|
137
|
+
async wayfindFetch(path, params) {
|
|
138
|
+
const url = new URL(`${this.config.wayfindApiUrl}${path}`);
|
|
139
|
+
if (params) {
|
|
140
|
+
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
|
|
141
|
+
}
|
|
142
|
+
const res = await fetch(url.toString(), {
|
|
143
|
+
headers: { "x-api-key": this.config.wayfindApiKey }
|
|
144
|
+
});
|
|
145
|
+
return res.json();
|
|
72
146
|
}
|
|
73
147
|
};
|
|
74
148
|
|
|
@@ -78,7 +152,7 @@ function createMcpServer(agent) {
|
|
|
78
152
|
name: "wayfind-solana-mcp",
|
|
79
153
|
version: "0.1.0"
|
|
80
154
|
});
|
|
81
|
-
for (const [_key, tool] of Object.entries(
|
|
155
|
+
for (const [_key, tool] of Object.entries(McpTools)) {
|
|
82
156
|
server.tool(tool.name, tool.description, tool.schema, async (params) => {
|
|
83
157
|
try {
|
|
84
158
|
const result = await tool.handler(agent, params);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { SolanaMcpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(SolanaMcpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\n\nexport const SolanaMcpTools: Record<string, McpTool> = {\n GetWalletAddressTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n\n private constructor(walletAddress: string) {\n this.walletAddress = walletAddress;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address);\n }\n}\n","export interface SolanaConfig {\n privateKey: string;\n rpcUrl: string;\n}\n\nexport function validateEnvironment(): SolanaConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n return { privateKey, rpcUrl };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,iBAA0B;AAC1B,mBAAqC;;;ACC9B,IAAM,uBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,SAAS,OAAO,OAAc,WAAgC;AAC5D,WAAO;AAAA,MACL,eAAe,MAAM;AAAA,IACvB;AAAA,EACF;AACF;;;ACVO,IAAM,iBAA0C;AAAA,EACrD;AACF;;;ACLA,iBAAuD;AACvD,kBAAiB;;;ACIV,SAAS,sBAAoC;AAClD,QAAM,aAAa,QAAQ,IAAI;AAC/B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,mFAAmF;AAAA,EACrG;AACA,QAAM,SAAS,QAAQ,IAAI,kBAAkB;AAC7C,SAAO,EAAE,YAAY,OAAO;AAC9B;;;ADRO,IAAM,QAAN,MAAM,OAAM;AAAA,EAGT,YAAY,eAAuB;AACzC,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,aAAa,SAAyB;AACpC,UAAM,SAAS,oBAAoB;AACnC,UAAM,UAAU,YAAAA,QAAK,OAAO,OAAO,UAAU;AAC7C,UAAM,OAAO,QAAQ,MAAM,GAAG,EAAE;AAChC,UAAM,SAAS,UAAM,mDAAuC,MAAM,KAAK;AACvE,WAAO,IAAI,OAAM,OAAO,OAAO;AAAA,EACjC;AACF;;;AHXA,SAAS,gBAAgB,OAAc;AACrC,QAAM,SAAS,IAAI,qBAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,WAAO,KAAK,KAAK,MAAM,KAAK,aAAa,KAAK,QAAQ,OAAO,WAA8B;AACzF,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,MAAM;AAC/C,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,QAC5E;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB,CAAC;AAAA,QACrG;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,OAAO;AACpB,QAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAM,SAAS,gBAAgB,KAAK;AACpC,QAAM,YAAY,IAAI,kCAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK;","names":["bs58"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/wayfind/get_tokens_tool.ts","../src/mcp/wayfind/get_tokenized_stocks_tool.ts","../src/mcp/wayfind/get_risk_profile_tool.ts","../src/mcp/wayfind/get_market_overview_tool.ts","../src/mcp/wayfind/get_pre_ipo_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { McpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(McpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokensTool: McpTool = {\n name: \"wayfind_get_tokens\",\n description: \"List all tokenized stocks with prices and market data\",\n schema: {\n chain: z.string().optional().describe(\"Filter by blockchain (e.g., 'solana', 'ethereum')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(\"/tokens\", input?.chain ? { chain: input.chain } : undefined);\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokenizedStocksTool: McpTool = {\n name: \"wayfind_get_tokenized_stocks\",\n description: \"Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)\",\n schema: {\n ticker: z.string().describe(\"Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetRiskProfileTool: McpTool = {\n name: \"wayfind_get_risk_profile\",\n description: \"Get the user's portfolio risk profile including overall score, label, and answers\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/risk-profile\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetMarketOverviewTool: McpTool = {\n name: \"wayfind_get_market_overview\",\n description: \"Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/market-overview\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetPreIpoTool: McpTool = {\n name: \"wayfind_get_pre_ipo\",\n description: \"List pre-IPO markets with mark prices and valuations\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/pre-ipo\");\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\nimport { WayfindGetTokensTool } from \"./wayfind/get_tokens_tool\";\nimport { WayfindGetTokenizedStocksTool } from \"./wayfind/get_tokenized_stocks_tool\";\nimport { WayfindGetRiskProfileTool } from \"./wayfind/get_risk_profile_tool\";\nimport { WayfindGetMarketOverviewTool } from \"./wayfind/get_market_overview_tool\";\nimport { WayfindGetPreIpoTool } from \"./wayfind/get_pre_ipo_tool\";\n\nexport const McpTools: Record<string, McpTool> = {\n SolanaGetWalletAddress: GetWalletAddressTool,\n WayfindGetTokens: WayfindGetTokensTool,\n WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,\n WayfindGetRiskProfile: WayfindGetRiskProfileTool,\n WayfindGetMarketOverview: WayfindGetMarketOverviewTool,\n WayfindGetPreIpo: WayfindGetPreIpoTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment, type AppConfig } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n private config: AppConfig;\n\n private constructor(walletAddress: string, config: AppConfig) {\n this.walletAddress = walletAddress;\n this.config = config;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address, config);\n }\n\n async wayfindFetch(path: string, params?: Record<string, string>) {\n const url = new URL(`${this.config.wayfindApiUrl}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n const res = await fetch(url.toString(), {\n headers: { \"x-api-key\": this.config.wayfindApiKey },\n });\n return res.json();\n }\n}\n","export interface AppConfig {\n privateKey: string;\n rpcUrl: string;\n wayfindApiKey: string;\n wayfindApiUrl: string;\n}\n\nexport function validateEnvironment(): AppConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n const wayfindApiKey = process.env.WAYFIND_API_KEY || \"e1ee8520-305a-49b5-a2de-3e1a7e6078c0\";\n const wayfindApiUrl = process.env.WAYFIND_API_URL || \"https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws\";\n return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };\n}\n"],"mappings":"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","names":["import_zod","bs58"]}
|
package/dist/index.mjs
CHANGED
|
@@ -16,9 +16,70 @@ var GetWalletAddressTool = {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
// src/mcp/wayfind/get_tokens_tool.ts
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
var WayfindGetTokensTool = {
|
|
22
|
+
name: "wayfind_get_tokens",
|
|
23
|
+
description: "List all tokenized stocks with prices and market data",
|
|
24
|
+
schema: {
|
|
25
|
+
chain: z.string().optional().describe("Filter by blockchain (e.g., 'solana', 'ethereum')")
|
|
26
|
+
},
|
|
27
|
+
handler: async (agent, input) => {
|
|
28
|
+
return agent.wayfindFetch("/tokens", input?.chain ? { chain: input.chain } : void 0);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// src/mcp/wayfind/get_tokenized_stocks_tool.ts
|
|
33
|
+
import { z as z2 } from "zod";
|
|
34
|
+
var WayfindGetTokenizedStocksTool = {
|
|
35
|
+
name: "wayfind_get_tokenized_stocks",
|
|
36
|
+
description: "Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)",
|
|
37
|
+
schema: {
|
|
38
|
+
ticker: z2.string().describe("Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')")
|
|
39
|
+
},
|
|
40
|
+
handler: async (agent, input) => {
|
|
41
|
+
return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/mcp/wayfind/get_risk_profile_tool.ts
|
|
46
|
+
var WayfindGetRiskProfileTool = {
|
|
47
|
+
name: "wayfind_get_risk_profile",
|
|
48
|
+
description: "Get the user's portfolio risk profile including overall score, label, and answers",
|
|
49
|
+
schema: {},
|
|
50
|
+
handler: async (agent, _input) => {
|
|
51
|
+
return agent.wayfindFetch("/risk-profile");
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/mcp/wayfind/get_market_overview_tool.ts
|
|
56
|
+
var WayfindGetMarketOverviewTool = {
|
|
57
|
+
name: "wayfind_get_market_overview",
|
|
58
|
+
description: "Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens",
|
|
59
|
+
schema: {},
|
|
60
|
+
handler: async (agent, _input) => {
|
|
61
|
+
return agent.wayfindFetch("/market-overview");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/mcp/wayfind/get_pre_ipo_tool.ts
|
|
66
|
+
var WayfindGetPreIpoTool = {
|
|
67
|
+
name: "wayfind_get_pre_ipo",
|
|
68
|
+
description: "List pre-IPO markets with mark prices and valuations",
|
|
69
|
+
schema: {},
|
|
70
|
+
handler: async (agent, _input) => {
|
|
71
|
+
return agent.wayfindFetch("/pre-ipo");
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
19
75
|
// src/mcp/index.ts
|
|
20
|
-
var
|
|
21
|
-
GetWalletAddressTool
|
|
76
|
+
var McpTools = {
|
|
77
|
+
SolanaGetWalletAddress: GetWalletAddressTool,
|
|
78
|
+
WayfindGetTokens: WayfindGetTokensTool,
|
|
79
|
+
WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,
|
|
80
|
+
WayfindGetRiskProfile: WayfindGetRiskProfileTool,
|
|
81
|
+
WayfindGetMarketOverview: WayfindGetMarketOverviewTool,
|
|
82
|
+
WayfindGetPreIpo: WayfindGetPreIpoTool
|
|
22
83
|
};
|
|
23
84
|
|
|
24
85
|
// src/agent/index.ts
|
|
@@ -32,20 +93,33 @@ function validateEnvironment() {
|
|
|
32
93
|
throw new Error("Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)");
|
|
33
94
|
}
|
|
34
95
|
const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
35
|
-
|
|
96
|
+
const wayfindApiKey = process.env.WAYFIND_API_KEY || "e1ee8520-305a-49b5-a2de-3e1a7e6078c0";
|
|
97
|
+
const wayfindApiUrl = process.env.WAYFIND_API_URL || "https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws";
|
|
98
|
+
return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };
|
|
36
99
|
}
|
|
37
100
|
|
|
38
101
|
// src/agent/index.ts
|
|
39
102
|
var Agent = class _Agent {
|
|
40
|
-
constructor(walletAddress) {
|
|
103
|
+
constructor(walletAddress, config) {
|
|
41
104
|
this.walletAddress = walletAddress;
|
|
105
|
+
this.config = config;
|
|
42
106
|
}
|
|
43
107
|
static async create() {
|
|
44
108
|
const config = validateEnvironment();
|
|
45
109
|
const decoded = bs58.decode(config.privateKey);
|
|
46
110
|
const seed = decoded.slice(0, 32);
|
|
47
111
|
const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);
|
|
48
|
-
return new _Agent(signer.address);
|
|
112
|
+
return new _Agent(signer.address, config);
|
|
113
|
+
}
|
|
114
|
+
async wayfindFetch(path, params) {
|
|
115
|
+
const url = new URL(`${this.config.wayfindApiUrl}${path}`);
|
|
116
|
+
if (params) {
|
|
117
|
+
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
|
|
118
|
+
}
|
|
119
|
+
const res = await fetch(url.toString(), {
|
|
120
|
+
headers: { "x-api-key": this.config.wayfindApiKey }
|
|
121
|
+
});
|
|
122
|
+
return res.json();
|
|
49
123
|
}
|
|
50
124
|
};
|
|
51
125
|
|
|
@@ -55,7 +129,7 @@ function createMcpServer(agent) {
|
|
|
55
129
|
name: "wayfind-solana-mcp",
|
|
56
130
|
version: "0.1.0"
|
|
57
131
|
});
|
|
58
|
-
for (const [_key, tool] of Object.entries(
|
|
132
|
+
for (const [_key, tool] of Object.entries(McpTools)) {
|
|
59
133
|
server.tool(tool.name, tool.description, tool.schema, async (params) => {
|
|
60
134
|
try {
|
|
61
135
|
const result = await tool.handler(agent, params);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { SolanaMcpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(SolanaMcpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\n\nexport const SolanaMcpTools: Record<string, McpTool> = {\n GetWalletAddressTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n\n private constructor(walletAddress: string) {\n this.walletAddress = walletAddress;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address);\n }\n}\n","export interface SolanaConfig {\n privateKey: string;\n rpcUrl: string;\n}\n\nexport function validateEnvironment(): SolanaConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n return { privateKey, rpcUrl };\n}\n"],"mappings":";;;AAEA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;;;ACC9B,IAAM,uBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,SAAS,OAAO,OAAc,WAAgC;AAC5D,WAAO;AAAA,MACL,eAAe,MAAM;AAAA,IACvB;AAAA,EACF;AACF;;;ACVO,IAAM,iBAA0C;AAAA,EACrD;AACF;;;ACLA,SAAS,8CAA8C;AACvD,OAAO,UAAU;;;ACIV,SAAS,sBAAoC;AAClD,QAAM,aAAa,QAAQ,IAAI;AAC/B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,mFAAmF;AAAA,EACrG;AACA,QAAM,SAAS,QAAQ,IAAI,kBAAkB;AAC7C,SAAO,EAAE,YAAY,OAAO;AAC9B;;;ADRO,IAAM,QAAN,MAAM,OAAM;AAAA,EAGT,YAAY,eAAuB;AACzC,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,aAAa,SAAyB;AACpC,UAAM,SAAS,oBAAoB;AACnC,UAAM,UAAU,KAAK,OAAO,OAAO,UAAU;AAC7C,UAAM,OAAO,QAAQ,MAAM,GAAG,EAAE;AAChC,UAAM,SAAS,MAAM,uCAAuC,MAAM,KAAK;AACvE,WAAO,IAAI,OAAM,OAAO,OAAO;AAAA,EACjC;AACF;;;AHXA,SAAS,gBAAgB,OAAc;AACrC,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,WAAO,KAAK,KAAK,MAAM,KAAK,aAAa,KAAK,QAAQ,OAAO,WAA8B;AACzF,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,MAAM;AAC/C,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,QAC5E;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB,CAAC;AAAA,QACrG;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,OAAO;AACpB,QAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAM,SAAS,gBAAgB,KAAK;AACpC,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/wayfind/get_tokens_tool.ts","../src/mcp/wayfind/get_tokenized_stocks_tool.ts","../src/mcp/wayfind/get_risk_profile_tool.ts","../src/mcp/wayfind/get_market_overview_tool.ts","../src/mcp/wayfind/get_pre_ipo_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { McpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(McpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokensTool: McpTool = {\n name: \"wayfind_get_tokens\",\n description: \"List all tokenized stocks with prices and market data\",\n schema: {\n chain: z.string().optional().describe(\"Filter by blockchain (e.g., 'solana', 'ethereum')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(\"/tokens\", input?.chain ? { chain: input.chain } : undefined);\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokenizedStocksTool: McpTool = {\n name: \"wayfind_get_tokenized_stocks\",\n description: \"Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)\",\n schema: {\n ticker: z.string().describe(\"Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetRiskProfileTool: McpTool = {\n name: \"wayfind_get_risk_profile\",\n description: \"Get the user's portfolio risk profile including overall score, label, and answers\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/risk-profile\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetMarketOverviewTool: McpTool = {\n name: \"wayfind_get_market_overview\",\n description: \"Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/market-overview\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetPreIpoTool: McpTool = {\n name: \"wayfind_get_pre_ipo\",\n description: \"List pre-IPO markets with mark prices and valuations\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/pre-ipo\");\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\nimport { WayfindGetTokensTool } from \"./wayfind/get_tokens_tool\";\nimport { WayfindGetTokenizedStocksTool } from \"./wayfind/get_tokenized_stocks_tool\";\nimport { WayfindGetRiskProfileTool } from \"./wayfind/get_risk_profile_tool\";\nimport { WayfindGetMarketOverviewTool } from \"./wayfind/get_market_overview_tool\";\nimport { WayfindGetPreIpoTool } from \"./wayfind/get_pre_ipo_tool\";\n\nexport const McpTools: Record<string, McpTool> = {\n SolanaGetWalletAddress: GetWalletAddressTool,\n WayfindGetTokens: WayfindGetTokensTool,\n WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,\n WayfindGetRiskProfile: WayfindGetRiskProfileTool,\n WayfindGetMarketOverview: WayfindGetMarketOverviewTool,\n WayfindGetPreIpo: WayfindGetPreIpoTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment, type AppConfig } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n private config: AppConfig;\n\n private constructor(walletAddress: string, config: AppConfig) {\n this.walletAddress = walletAddress;\n this.config = config;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address, config);\n }\n\n async wayfindFetch(path: string, params?: Record<string, string>) {\n const url = new URL(`${this.config.wayfindApiUrl}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n const res = await fetch(url.toString(), {\n headers: { \"x-api-key\": this.config.wayfindApiKey },\n });\n return res.json();\n }\n}\n","export interface AppConfig {\n privateKey: string;\n rpcUrl: string;\n wayfindApiKey: string;\n wayfindApiUrl: string;\n}\n\nexport function validateEnvironment(): AppConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n const wayfindApiKey = process.env.WAYFIND_API_KEY || \"e1ee8520-305a-49b5-a2de-3e1a7e6078c0\";\n const wayfindApiUrl = process.env.WAYFIND_API_URL || \"https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws\";\n return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };\n}\n"],"mappings":"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","names":["z"]}
|
package/package.json
CHANGED
package/src/agent/index.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createKeyPairSignerFromPrivateKeyBytes } from "@solana/kit";
|
|
2
2
|
import bs58 from "bs58";
|
|
3
|
-
import { validateEnvironment } from "../config";
|
|
3
|
+
import { validateEnvironment, type AppConfig } from "../config";
|
|
4
4
|
|
|
5
5
|
export class Agent {
|
|
6
6
|
public walletAddress: string;
|
|
7
|
+
private config: AppConfig;
|
|
7
8
|
|
|
8
|
-
private constructor(walletAddress: string) {
|
|
9
|
+
private constructor(walletAddress: string, config: AppConfig) {
|
|
9
10
|
this.walletAddress = walletAddress;
|
|
11
|
+
this.config = config;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
static async create(): Promise<Agent> {
|
|
@@ -14,6 +16,17 @@ export class Agent {
|
|
|
14
16
|
const decoded = bs58.decode(config.privateKey);
|
|
15
17
|
const seed = decoded.slice(0, 32);
|
|
16
18
|
const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);
|
|
17
|
-
return new Agent(signer.address);
|
|
19
|
+
return new Agent(signer.address, config);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async wayfindFetch(path: string, params?: Record<string, string>) {
|
|
23
|
+
const url = new URL(`${this.config.wayfindApiUrl}${path}`);
|
|
24
|
+
if (params) {
|
|
25
|
+
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
|
|
26
|
+
}
|
|
27
|
+
const res = await fetch(url.toString(), {
|
|
28
|
+
headers: { "x-api-key": this.config.wayfindApiKey },
|
|
29
|
+
});
|
|
30
|
+
return res.json();
|
|
18
31
|
}
|
|
19
32
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface AppConfig {
|
|
2
2
|
privateKey: string;
|
|
3
3
|
rpcUrl: string;
|
|
4
|
+
wayfindApiKey: string;
|
|
5
|
+
wayfindApiUrl: string;
|
|
4
6
|
}
|
|
5
7
|
|
|
6
|
-
export function validateEnvironment():
|
|
8
|
+
export function validateEnvironment(): AppConfig {
|
|
7
9
|
const privateKey = process.env.SOLANA_PRIVATE_KEY;
|
|
8
10
|
if (!privateKey) {
|
|
9
11
|
throw new Error("Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)");
|
|
10
12
|
}
|
|
11
13
|
const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
12
|
-
|
|
14
|
+
const wayfindApiKey = process.env.WAYFIND_API_KEY || "e1ee8520-305a-49b5-a2de-3e1a7e6078c0";
|
|
15
|
+
const wayfindApiUrl = process.env.WAYFIND_API_URL || "https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws";
|
|
16
|
+
return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };
|
|
13
17
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
-
import {
|
|
5
|
+
import { McpTools } from "./mcp";
|
|
6
6
|
import { Agent } from "./agent";
|
|
7
7
|
|
|
8
8
|
function createMcpServer(agent: Agent) {
|
|
@@ -11,7 +11,7 @@ function createMcpServer(agent: Agent) {
|
|
|
11
11
|
version: "0.1.0",
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
for (const [_key, tool] of Object.entries(
|
|
14
|
+
for (const [_key, tool] of Object.entries(McpTools)) {
|
|
15
15
|
server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {
|
|
16
16
|
try {
|
|
17
17
|
const result = await tool.handler(agent, params);
|
package/src/mcp/index.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { McpTool } from "../types";
|
|
2
2
|
import { GetWalletAddressTool } from "./solana/get_wallet_address_tool";
|
|
3
|
+
import { WayfindGetTokensTool } from "./wayfind/get_tokens_tool";
|
|
4
|
+
import { WayfindGetTokenizedStocksTool } from "./wayfind/get_tokenized_stocks_tool";
|
|
5
|
+
import { WayfindGetRiskProfileTool } from "./wayfind/get_risk_profile_tool";
|
|
6
|
+
import { WayfindGetMarketOverviewTool } from "./wayfind/get_market_overview_tool";
|
|
7
|
+
import { WayfindGetPreIpoTool } from "./wayfind/get_pre_ipo_tool";
|
|
3
8
|
|
|
4
|
-
export const
|
|
5
|
-
GetWalletAddressTool,
|
|
9
|
+
export const McpTools: Record<string, McpTool> = {
|
|
10
|
+
SolanaGetWalletAddress: GetWalletAddressTool,
|
|
11
|
+
WayfindGetTokens: WayfindGetTokensTool,
|
|
12
|
+
WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,
|
|
13
|
+
WayfindGetRiskProfile: WayfindGetRiskProfileTool,
|
|
14
|
+
WayfindGetMarketOverview: WayfindGetMarketOverviewTool,
|
|
15
|
+
WayfindGetPreIpo: WayfindGetPreIpoTool,
|
|
6
16
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Agent } from "../../agent";
|
|
2
|
+
import type { McpTool } from "../../types";
|
|
3
|
+
|
|
4
|
+
export const WayfindGetMarketOverviewTool: McpTool = {
|
|
5
|
+
name: "wayfind_get_market_overview",
|
|
6
|
+
description: "Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens",
|
|
7
|
+
schema: {},
|
|
8
|
+
handler: async (agent: Agent, _input: Record<string, any>) => {
|
|
9
|
+
return agent.wayfindFetch("/market-overview");
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Agent } from "../../agent";
|
|
2
|
+
import type { McpTool } from "../../types";
|
|
3
|
+
|
|
4
|
+
export const WayfindGetPreIpoTool: McpTool = {
|
|
5
|
+
name: "wayfind_get_pre_ipo",
|
|
6
|
+
description: "List pre-IPO markets with mark prices and valuations",
|
|
7
|
+
schema: {},
|
|
8
|
+
handler: async (agent: Agent, _input: Record<string, any>) => {
|
|
9
|
+
return agent.wayfindFetch("/pre-ipo");
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Agent } from "../../agent";
|
|
2
|
+
import type { McpTool } from "../../types";
|
|
3
|
+
|
|
4
|
+
export const WayfindGetRiskProfileTool: McpTool = {
|
|
5
|
+
name: "wayfind_get_risk_profile",
|
|
6
|
+
description: "Get the user's portfolio risk profile including overall score, label, and answers",
|
|
7
|
+
schema: {},
|
|
8
|
+
handler: async (agent: Agent, _input: Record<string, any>) => {
|
|
9
|
+
return agent.wayfindFetch("/risk-profile");
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Agent } from "../../agent";
|
|
3
|
+
import type { McpTool } from "../../types";
|
|
4
|
+
|
|
5
|
+
export const WayfindGetTokenizedStocksTool: McpTool = {
|
|
6
|
+
name: "wayfind_get_tokenized_stocks",
|
|
7
|
+
description: "Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)",
|
|
8
|
+
schema: {
|
|
9
|
+
ticker: z.string().describe("Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')"),
|
|
10
|
+
},
|
|
11
|
+
handler: async (agent: Agent, input: Record<string, any>) => {
|
|
12
|
+
return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Agent } from "../../agent";
|
|
3
|
+
import type { McpTool } from "../../types";
|
|
4
|
+
|
|
5
|
+
export const WayfindGetTokensTool: McpTool = {
|
|
6
|
+
name: "wayfind_get_tokens",
|
|
7
|
+
description: "List all tokenized stocks with prices and market data",
|
|
8
|
+
schema: {
|
|
9
|
+
chain: z.string().optional().describe("Filter by blockchain (e.g., 'solana', 'ethereum')"),
|
|
10
|
+
},
|
|
11
|
+
handler: async (agent: Agent, input: Record<string, any>) => {
|
|
12
|
+
return agent.wayfindFetch("/tokens", input?.chain ? { chain: input.chain } : undefined);
|
|
13
|
+
},
|
|
14
|
+
};
|