finoptima 1.1.0 → 1.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/package.json +2 -2
- package/tools/index.js +18 -1
- package/tools/intent-tools.js +58 -0
- package/tools/performance-tools.js +30 -0
- package/tools/strategy-tools.js +102 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "finoptima",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "FINOPTIMA — EcoChain AI Finance Agent via MCP. Portfolio optimization, AMM liquidity, trading, swaps. Secured by EcoAuth 2FA.",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "FINOPTIMA — EcoChain AI Finance Agent via MCP. Portfolio optimization, AMM liquidity, AI trading strategies, swaps. Secured by EcoAuth 2FA.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"finoptima": "index.js"
|
package/tools/index.js
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
const apiClient = require('../lib/api-client');
|
|
13
13
|
const { withLogging } = require('../lib/logger');
|
|
14
14
|
|
|
15
|
+
// [DEC-2026-046] AI Trading Platform tools
|
|
16
|
+
const { strategyTools } = require('./strategy-tools');
|
|
17
|
+
const { intentTools } = require('./intent-tools');
|
|
18
|
+
const { performanceTools } = require('./performance-tools');
|
|
19
|
+
|
|
15
20
|
// Helper: get user ID from env (set at startup from API key lookup)
|
|
16
21
|
function uid() {
|
|
17
22
|
return process.env.ECOCHAIN_USER_ID || 'me';
|
|
@@ -395,5 +400,17 @@ module.exports = {
|
|
|
395
400
|
swapTools,
|
|
396
401
|
liquidityTools,
|
|
397
402
|
sendTools,
|
|
398
|
-
|
|
403
|
+
strategyTools,
|
|
404
|
+
intentTools,
|
|
405
|
+
performanceTools,
|
|
406
|
+
allTools: [
|
|
407
|
+
...readTools,
|
|
408
|
+
...tradeTools,
|
|
409
|
+
...swapTools,
|
|
410
|
+
...liquidityTools,
|
|
411
|
+
...sendTools,
|
|
412
|
+
...strategyTools,
|
|
413
|
+
...intentTools,
|
|
414
|
+
...performanceTools
|
|
415
|
+
]
|
|
399
416
|
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Intent Tools (DEC-2026-046)
|
|
3
|
+
* 2 tools for AI agent intent management (scope: trade)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const apiClient = require('../lib/api-client');
|
|
7
|
+
const { withLogging } = require('../lib/logger');
|
|
8
|
+
|
|
9
|
+
const intentTools = [
|
|
10
|
+
{
|
|
11
|
+
name: 'create_intent',
|
|
12
|
+
description: 'Create a trading intent with policy validation. Returns canonical_display (human-readable JSON) and intent_hash (SHA256) for approval verification. Auto-approved if amount < 0.01 BTC, otherwise awaits manual approval (30min TTL).',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
strategy_id: { type: 'string', description: 'Optional: link to a strategy' },
|
|
17
|
+
action: { type: 'string', description: 'Trading action', enum: ['execute_swap', 'add_liquidity', 'remove_liquidity', 'place_order'] },
|
|
18
|
+
params: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
description: 'Action parameters. Swap: {token_in, token_out, amount_in, max_slippage_bps}. Liquidity: {pool_id, amount_a, amount_b}. Order: {pair_id, side, type, amount, price}.'
|
|
21
|
+
},
|
|
22
|
+
reasoning: { type: 'string', description: 'Why this trade (shown to user for approval)' }
|
|
23
|
+
},
|
|
24
|
+
required: ['action', 'params']
|
|
25
|
+
},
|
|
26
|
+
handler: withLogging('create_intent', async ({ strategy_id, action, params, reasoning }) => {
|
|
27
|
+
const body = { action, params };
|
|
28
|
+
if (strategy_id) body.strategy_id = strategy_id;
|
|
29
|
+
if (reasoning) body.reasoning = reasoning;
|
|
30
|
+
const data = await apiClient.post('/intents', body);
|
|
31
|
+
return JSON.stringify(data, null, 2);
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'list_intents',
|
|
36
|
+
description: 'List trading intents with optional filters. Shows status, canonical display, policy result, and execution result.',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {
|
|
40
|
+
status: { type: 'string', description: 'Filter by status', enum: ['pending', 'awaiting_approval', 'approved', 'rejected', 'executing', 'executed', 'failed', 'expired', 'canceled'] },
|
|
41
|
+
strategy_id: { type: 'string', description: 'Filter by strategy' },
|
|
42
|
+
limit: { type: 'number', description: 'Max results (default 50)' }
|
|
43
|
+
},
|
|
44
|
+
required: []
|
|
45
|
+
},
|
|
46
|
+
handler: withLogging('list_intents', async ({ status, strategy_id, limit }) => {
|
|
47
|
+
const params = new URLSearchParams();
|
|
48
|
+
if (status) params.set('status', status);
|
|
49
|
+
if (strategy_id) params.set('strategy_id', strategy_id);
|
|
50
|
+
if (limit) params.set('limit', limit.toString());
|
|
51
|
+
const qs = params.toString();
|
|
52
|
+
const data = await apiClient.get(`/intents${qs ? '?' + qs : ''}`);
|
|
53
|
+
return JSON.stringify(data, null, 2);
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
module.exports = { intentTools };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Performance Tools (DEC-2026-046)
|
|
3
|
+
* 1 tool for AI agent performance monitoring (scope: read)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const apiClient = require('../lib/api-client');
|
|
7
|
+
const { withLogging } = require('../lib/logger');
|
|
8
|
+
|
|
9
|
+
const performanceTools = [
|
|
10
|
+
{
|
|
11
|
+
name: 'get_strategy_performance',
|
|
12
|
+
description: 'Get performance metrics for a trading strategy: total return, max drawdown, vs HODL benchmark, fees paid/earned, and PnL snapshots time-series.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
strategy_id: { type: 'string', description: 'Strategy UUID' }
|
|
17
|
+
},
|
|
18
|
+
required: ['strategy_id']
|
|
19
|
+
},
|
|
20
|
+
handler: withLogging('get_strategy_performance', async ({ strategy_id }) => {
|
|
21
|
+
const [metrics, snapshots] = await Promise.all([
|
|
22
|
+
apiClient.get(`/performance/strategy/${strategy_id}`),
|
|
23
|
+
apiClient.get(`/performance/strategy/${strategy_id}/snapshots?limit=50`)
|
|
24
|
+
]);
|
|
25
|
+
return JSON.stringify({ metrics, snapshots }, null, 2);
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
module.exports = { performanceTools };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Strategy Tools (DEC-2026-046)
|
|
3
|
+
* 5 tools for AI agent strategy management (scope: strategy)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const apiClient = require('../lib/api-client');
|
|
7
|
+
const { withLogging } = require('../lib/logger');
|
|
8
|
+
|
|
9
|
+
function uid() {
|
|
10
|
+
return process.env.ECOCHAIN_USER_ID || 'me';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const strategyTools = [
|
|
14
|
+
{
|
|
15
|
+
name: 'list_strategies',
|
|
16
|
+
description: 'List all trading strategies for the user. Returns strategy name, type (lp_yield/dca/btc_hedge), status, mode, and PnL summary.',
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
status: { type: 'string', description: 'Filter by status', enum: ['draft', 'active', 'paused', 'stopped', 'error'] }
|
|
21
|
+
},
|
|
22
|
+
required: []
|
|
23
|
+
},
|
|
24
|
+
handler: withLogging('list_strategies', async ({ status }) => {
|
|
25
|
+
const params = status ? `?status=${status}` : '';
|
|
26
|
+
const data = await apiClient.get(`/strategies${params}`);
|
|
27
|
+
return JSON.stringify(data, null, 2);
|
|
28
|
+
})
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'get_strategy',
|
|
32
|
+
description: 'Get detailed info about a trading strategy: parameters, rules, latest PnL snapshot, and recent intents.',
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
strategy_id: { type: 'string', description: 'Strategy UUID' }
|
|
37
|
+
},
|
|
38
|
+
required: ['strategy_id']
|
|
39
|
+
},
|
|
40
|
+
handler: withLogging('get_strategy', async ({ strategy_id }) => {
|
|
41
|
+
const data = await apiClient.get(`/strategies/${strategy_id}`);
|
|
42
|
+
return JSON.stringify(data, null, 2);
|
|
43
|
+
})
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'create_strategy',
|
|
47
|
+
description: 'Create a new trading strategy (starts as draft). Types: lp_yield (LP optimization), dca (Dollar Cost Average), btc_hedge (BTC downside protection). Mode: auto (execute automatically) or watch (manual approval for all intents).',
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
name: { type: 'string', description: 'Strategy name (e.g. "Daily BTC DCA")' },
|
|
52
|
+
type: { type: 'string', description: 'Strategy type', enum: ['lp_yield', 'dca', 'btc_hedge'] },
|
|
53
|
+
parameters: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
description: 'Strategy parameters. DCA: {token_to_buy, spend_token, amount_per_interval, interval_hours, total_budget}. BTC Hedge: {btc_drop_threshold_percent, conversion_step_percent, cooldown_hours}. LP Yield: {pool_id, min_apr_threshold, rebalance_on_il_percent}.'
|
|
56
|
+
},
|
|
57
|
+
mode: { type: 'string', description: 'Execution mode', enum: ['auto', 'watch'] },
|
|
58
|
+
description: { type: 'string', description: 'Optional description' }
|
|
59
|
+
},
|
|
60
|
+
required: ['name', 'type', 'parameters']
|
|
61
|
+
},
|
|
62
|
+
handler: withLogging('create_strategy', async ({ name, type, parameters, mode, description }) => {
|
|
63
|
+
const body = { name, type, parameters };
|
|
64
|
+
if (mode) body.mode = mode;
|
|
65
|
+
if (description) body.description = description;
|
|
66
|
+
const data = await apiClient.post('/strategies', body);
|
|
67
|
+
return JSON.stringify(data, null, 2);
|
|
68
|
+
})
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'activate_strategy',
|
|
72
|
+
description: 'Activate a draft or paused strategy. Creates default policy rules if none exist and takes a start-of-day PnL snapshot.',
|
|
73
|
+
inputSchema: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
strategy_id: { type: 'string', description: 'Strategy UUID to activate' }
|
|
77
|
+
},
|
|
78
|
+
required: ['strategy_id']
|
|
79
|
+
},
|
|
80
|
+
handler: withLogging('activate_strategy', async ({ strategy_id }) => {
|
|
81
|
+
const data = await apiClient.post(`/strategies/${strategy_id}/activate`);
|
|
82
|
+
return JSON.stringify(data, null, 2);
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'pause_strategy',
|
|
87
|
+
description: 'Pause an active strategy. Cancels all pending/awaiting/approved intents. Can be resumed later with activate.',
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
strategy_id: { type: 'string', description: 'Strategy UUID to pause' }
|
|
92
|
+
},
|
|
93
|
+
required: ['strategy_id']
|
|
94
|
+
},
|
|
95
|
+
handler: withLogging('pause_strategy', async ({ strategy_id }) => {
|
|
96
|
+
const data = await apiClient.post(`/strategies/${strategy_id}/pause`);
|
|
97
|
+
return JSON.stringify(data, null, 2);
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
module.exports = { strategyTools };
|