@vantagestack/mcp-server 0.1.59 → 0.1.63

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.
Files changed (115) hide show
  1. package/dist/client.d.ts +25 -0
  2. package/dist/client.js +172 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.js +1424 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/tools/account-deletion.d.ts +6 -0
  8. package/dist/tools/account-deletion.js +92 -0
  9. package/dist/tools/account-deletion.js.map +1 -0
  10. package/dist/tools/account-health.d.ts +21 -0
  11. package/dist/tools/account-health.js +84 -0
  12. package/dist/tools/account-health.js.map +1 -0
  13. package/dist/tools/account.d.ts +19 -0
  14. package/dist/tools/account.js +291 -0
  15. package/dist/tools/account.js.map +1 -0
  16. package/dist/tools/account.test.d.ts +1 -0
  17. package/dist/tools/account.test.js +213 -0
  18. package/dist/tools/account.test.js.map +1 -0
  19. package/dist/tools/admin-test.d.ts +18 -0
  20. package/dist/tools/admin-test.js +108 -0
  21. package/dist/tools/admin-test.js.map +1 -0
  22. package/dist/tools/calendar.d.ts +4 -0
  23. package/dist/tools/calendar.js +85 -0
  24. package/dist/tools/calendar.js.map +1 -0
  25. package/dist/tools/calendar.test.d.ts +1 -0
  26. package/dist/tools/calendar.test.js +62 -0
  27. package/dist/tools/calendar.test.js.map +1 -0
  28. package/dist/tools/canary.d.ts +4 -0
  29. package/dist/tools/canary.js +25 -0
  30. package/dist/tools/canary.js.map +1 -0
  31. package/dist/tools/canary.test.d.ts +1 -0
  32. package/dist/tools/canary.test.js +46 -0
  33. package/dist/tools/canary.test.js.map +1 -0
  34. package/dist/tools/contract-configs.d.ts +9 -0
  35. package/dist/tools/contract-configs.js +187 -0
  36. package/dist/tools/contract-configs.js.map +1 -0
  37. package/dist/tools/contract-configs.test.d.ts +1 -0
  38. package/dist/tools/contract-configs.test.js +245 -0
  39. package/dist/tools/contract-configs.test.js.map +1 -0
  40. package/dist/tools/copier.d.ts +11 -0
  41. package/dist/tools/copier.js +52 -0
  42. package/dist/tools/copier.js.map +1 -0
  43. package/dist/tools/copier.test.d.ts +1 -0
  44. package/dist/tools/copier.test.js +75 -0
  45. package/dist/tools/copier.test.js.map +1 -0
  46. package/dist/tools/groups.d.ts +14 -0
  47. package/dist/tools/groups.js +44 -0
  48. package/dist/tools/groups.js.map +1 -0
  49. package/dist/tools/groups.test.d.ts +1 -0
  50. package/dist/tools/groups.test.js +72 -0
  51. package/dist/tools/groups.test.js.map +1 -0
  52. package/dist/tools/ip-allowlist.d.ts +6 -0
  53. package/dist/tools/ip-allowlist.js +69 -0
  54. package/dist/tools/ip-allowlist.js.map +1 -0
  55. package/dist/tools/journal.d.ts +6 -0
  56. package/dist/tools/journal.js +110 -0
  57. package/dist/tools/journal.js.map +1 -0
  58. package/dist/tools/journal.test.d.ts +1 -0
  59. package/dist/tools/journal.test.js +100 -0
  60. package/dist/tools/journal.test.js.map +1 -0
  61. package/dist/tools/latency.d.ts +3 -0
  62. package/dist/tools/latency.js +54 -0
  63. package/dist/tools/latency.js.map +1 -0
  64. package/dist/tools/market-history.d.ts +4 -0
  65. package/dist/tools/market-history.js +50 -0
  66. package/dist/tools/market-history.js.map +1 -0
  67. package/dist/tools/market-hours.d.ts +3 -0
  68. package/dist/tools/market-hours.js +19 -0
  69. package/dist/tools/market-hours.js.map +1 -0
  70. package/dist/tools/paper-trading.d.ts +12 -0
  71. package/dist/tools/paper-trading.js +284 -0
  72. package/dist/tools/paper-trading.js.map +1 -0
  73. package/dist/tools/paper-trading.test.d.ts +1 -0
  74. package/dist/tools/paper-trading.test.js +153 -0
  75. package/dist/tools/paper-trading.test.js.map +1 -0
  76. package/dist/tools/ping.d.ts +8 -0
  77. package/dist/tools/ping.js +22 -0
  78. package/dist/tools/ping.js.map +1 -0
  79. package/dist/tools/ping.test.d.ts +1 -0
  80. package/dist/tools/ping.test.js +25 -0
  81. package/dist/tools/ping.test.js.map +1 -0
  82. package/dist/tools/qc.d.ts +18 -0
  83. package/dist/tools/qc.js +418 -0
  84. package/dist/tools/qc.js.map +1 -0
  85. package/dist/tools/qc.test.d.ts +1 -0
  86. package/dist/tools/qc.test.js +218 -0
  87. package/dist/tools/qc.test.js.map +1 -0
  88. package/dist/tools/read.d.ts +7 -0
  89. package/dist/tools/read.js +154 -0
  90. package/dist/tools/read.js.map +1 -0
  91. package/dist/tools/read.test.d.ts +1 -0
  92. package/dist/tools/read.test.js +102 -0
  93. package/dist/tools/read.test.js.map +1 -0
  94. package/dist/tools/risk.d.ts +7 -0
  95. package/dist/tools/risk.js +108 -0
  96. package/dist/tools/risk.js.map +1 -0
  97. package/dist/tools/signal-templates.d.ts +6 -0
  98. package/dist/tools/signal-templates.js +90 -0
  99. package/dist/tools/signal-templates.js.map +1 -0
  100. package/dist/tools/signals.d.ts +8 -0
  101. package/dist/tools/signals.js +318 -0
  102. package/dist/tools/signals.js.map +1 -0
  103. package/dist/tools/signals.test.d.ts +1 -0
  104. package/dist/tools/signals.test.js +92 -0
  105. package/dist/tools/signals.test.js.map +1 -0
  106. package/dist/tools/sync-accounts.d.ts +18 -0
  107. package/dist/tools/sync-accounts.js +68 -0
  108. package/dist/tools/sync-accounts.js.map +1 -0
  109. package/dist/tools/trade.d.ts +3 -0
  110. package/dist/tools/trade.js +49 -0
  111. package/dist/tools/trade.js.map +1 -0
  112. package/dist/user.d.ts +19 -0
  113. package/dist/user.js +21 -0
  114. package/dist/user.js.map +1 -0
  115. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canary.js","sourceRoot":"","sources":["../../src/tools/canary.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,eAAe,EAAc,MAAM,YAAY,CAAC;AAUvE,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAqB,EACrB,SAAuB,EACvB,MAA+B;IAE/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAe,mBAAmB,CAAC,CAAC;QAEhE,MAAM,KAAK,GAAG;YACZ,kBAAkB;YAClB,kBAAkB,GAAG,CAAC,OAAO,EAAE;YAC/B,wBAAwB,GAAG,CAAC,aAAa,EAAE;YAC3C,0BAA0B,GAAG,CAAC,eAAe,EAAE;YAC/C,oBAAoB,GAAG,CAAC,SAAS,EAAE;YACnC,0BAA0B,GAAG,CAAC,eAAe,IAAI,GAAG,EAAE;SACvD,CAAC;QAEF,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACxC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACrD;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { getCanaryConfig } from "./canary.js";
3
+ const makeClient = (getImpl) => ({ get: getImpl });
4
+ const resolver = {};
5
+ describe("get_canary_config", () => {
6
+ it("returns formatted config when API responds", async () => {
7
+ const payload = {
8
+ enabled: true,
9
+ periodMinutes: 5,
10
+ skipClosedHours: true,
11
+ updatedAt: "2026-05-19T20:00:00Z",
12
+ updatedByUserId: 42,
13
+ };
14
+ const client = makeClient(() => Promise.resolve(payload));
15
+ const result = await getCanaryConfig(client, resolver, {});
16
+ expect(result.isError).toBeUndefined();
17
+ const text = result.content[0].text;
18
+ expect(text).toContain("enabled");
19
+ expect(text).toContain("periodMinutes");
20
+ expect(text).toContain("skipClosedHours");
21
+ // second content block is the raw JSON
22
+ const json = JSON.parse(result.content[1].text);
23
+ expect(json.enabled).toBe(true);
24
+ expect(json.periodMinutes).toBe(5);
25
+ });
26
+ it("returns formatted config with null updatedByUserId", async () => {
27
+ const payload = {
28
+ enabled: false,
29
+ periodMinutes: 15,
30
+ skipClosedHours: false,
31
+ updatedAt: "2026-05-19T20:00:00Z",
32
+ updatedByUserId: null,
33
+ };
34
+ const client = makeClient(() => Promise.resolve(payload));
35
+ const result = await getCanaryConfig(client, resolver, {});
36
+ expect(result.isError).toBeUndefined();
37
+ expect(result.content[0].text).toContain("—");
38
+ });
39
+ it("returns isError true when API call throws", async () => {
40
+ const client = makeClient(() => Promise.reject(new Error("forbidden")));
41
+ const result = await getCanaryConfig(client, resolver, {});
42
+ expect(result.isError).toBe(true);
43
+ expect(result.content[0].text).toContain("forbidden");
44
+ });
45
+ });
46
+ //# sourceMappingURL=canary.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canary.test.js","sourceRoot":"","sources":["../../src/tools/canary.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { VantageClient } from "../client.js";
2
+ import { UserResolver, ToolResult } from "../user.js";
3
+ export declare function listContractConfigs(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
4
+ export declare function createContractConfig(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
5
+ export declare function updateContractConfig(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
6
+ export declare function deleteContractConfig(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
7
+ export declare function rollContractConfig(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
8
+ export declare function setContractConfigLeader(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
9
+ export declare function updateContractConfigFollower(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
@@ -0,0 +1,187 @@
1
+ import { makeErrorResult } from "../user.js";
2
+ // CTPC-05-S1 — MCP tools for per-contract config CRUD + roll + leader/follower.
3
+ // All tools call /api/account/{userId}/groups/{groupId}/contract-configs[/...].
4
+ // The backend CRUD is CTPC-03-S1 (D); roll is CTPC-03-S3 (C).
5
+ function requireGroupId(input) {
6
+ const groupId = Number(input.groupId);
7
+ if (!Number.isFinite(groupId) || groupId <= 0)
8
+ return new Error("groupId is required and must be a positive integer");
9
+ return groupId;
10
+ }
11
+ function requireConfigId(input) {
12
+ const configId = Number(input.configId);
13
+ if (!Number.isFinite(configId) || configId <= 0)
14
+ return new Error("configId is required and must be a positive integer");
15
+ return configId;
16
+ }
17
+ export async function listContractConfigs(client, resolver, input) {
18
+ try {
19
+ const groupId = requireGroupId(input);
20
+ if (groupId instanceof Error)
21
+ return makeErrorResult(groupId);
22
+ const userId = await resolver.resolve(client);
23
+ const res = await client.get(`/api/account/${userId}/groups/${groupId}/contract-configs`);
24
+ const configs = Array.isArray(res) ? res : [];
25
+ const lines = [`### Contract configs for group #${groupId}`, `${configs.length} config(s)\n`];
26
+ for (const cfg of configs) {
27
+ lines.push(`- **#${cfg.id}** \`${cfg.symbolRoot}\`${cfg.isDeleted ? " *(deleted)*" : ""}`);
28
+ }
29
+ return {
30
+ content: [
31
+ { type: "text", text: lines.join("\n") },
32
+ { type: "text", text: JSON.stringify(res, null, 2) },
33
+ ],
34
+ };
35
+ }
36
+ catch (e) {
37
+ return makeErrorResult(e);
38
+ }
39
+ }
40
+ export async function createContractConfig(client, resolver, input) {
41
+ try {
42
+ const groupId = requireGroupId(input);
43
+ if (groupId instanceof Error)
44
+ return makeErrorResult(groupId);
45
+ const symbolRoot = String(input.symbolRoot ?? "").trim().toUpperCase();
46
+ if (!symbolRoot)
47
+ return makeErrorResult(new Error("symbolRoot is required (e.g. 'MES', 'MNQ')"));
48
+ const userId = await resolver.resolve(client);
49
+ const res = await client.post(`/api/account/${userId}/groups/${groupId}/contract-configs`, { symbolRoot });
50
+ return {
51
+ content: [
52
+ { type: "text", text: `### Contract config created\nGroup #${groupId} → config #${res?.id} (\`${symbolRoot}\`)` },
53
+ { type: "text", text: JSON.stringify(res, null, 2) },
54
+ ],
55
+ };
56
+ }
57
+ catch (e) {
58
+ return makeErrorResult(e);
59
+ }
60
+ }
61
+ export async function updateContractConfig(client, resolver, input) {
62
+ try {
63
+ const groupId = requireGroupId(input);
64
+ if (groupId instanceof Error)
65
+ return makeErrorResult(groupId);
66
+ const configId = requireConfigId(input);
67
+ if (configId instanceof Error)
68
+ return makeErrorResult(configId);
69
+ const body = {};
70
+ if ("symbolRoot" in input)
71
+ body.symbolRoot = String(input.symbolRoot).trim().toUpperCase();
72
+ if (Object.keys(body).length === 0)
73
+ return makeErrorResult(new Error("At least one updatable field (symbolRoot) must be supplied"));
74
+ const userId = await resolver.resolve(client);
75
+ const res = await client.patch(`/api/account/${userId}/groups/${groupId}/contract-configs/${configId}`, body);
76
+ return {
77
+ content: [
78
+ { type: "text", text: `### Contract config updated\nConfig #${configId} in group #${groupId}` },
79
+ { type: "text", text: JSON.stringify(res, null, 2) },
80
+ ],
81
+ };
82
+ }
83
+ catch (e) {
84
+ return makeErrorResult(e);
85
+ }
86
+ }
87
+ export async function deleteContractConfig(client, resolver, input) {
88
+ try {
89
+ const groupId = requireGroupId(input);
90
+ if (groupId instanceof Error)
91
+ return makeErrorResult(groupId);
92
+ const configId = requireConfigId(input);
93
+ if (configId instanceof Error)
94
+ return makeErrorResult(configId);
95
+ const userId = await resolver.resolve(client);
96
+ await client.delete(`/api/account/${userId}/groups/${groupId}/contract-configs/${configId}`);
97
+ return {
98
+ content: [{ type: "text", text: `### Contract config deleted\nConfig #${configId} soft-deleted from group #${groupId}.` }],
99
+ };
100
+ }
101
+ catch (e) {
102
+ return makeErrorResult(e);
103
+ }
104
+ }
105
+ export async function rollContractConfig(client, resolver, input) {
106
+ try {
107
+ const groupId = requireGroupId(input);
108
+ if (groupId instanceof Error)
109
+ return makeErrorResult(groupId);
110
+ const configId = requireConfigId(input);
111
+ if (configId instanceof Error)
112
+ return makeErrorResult(configId);
113
+ const newSymbol = String(input.newSymbol ?? "").trim().toUpperCase();
114
+ if (!newSymbol)
115
+ return makeErrorResult(new Error("newSymbol is required (e.g. 'MESM6')"));
116
+ const body = { newSymbol };
117
+ if ("expectedCurrentSymbol" in input)
118
+ body.expectedCurrentSymbol = String(input.expectedCurrentSymbol).trim().toUpperCase();
119
+ const userId = await resolver.resolve(client);
120
+ const res = await client.post(`/api/account/${userId}/groups/${groupId}/contract-configs/${configId}/roll`, body);
121
+ return {
122
+ content: [
123
+ { type: "text", text: `### Contract rolled\nConfig #${configId} → \`${newSymbol}\`` },
124
+ { type: "text", text: JSON.stringify(res, null, 2) },
125
+ ],
126
+ };
127
+ }
128
+ catch (e) {
129
+ return makeErrorResult(e);
130
+ }
131
+ }
132
+ export async function setContractConfigLeader(client, resolver, input) {
133
+ try {
134
+ const groupId = requireGroupId(input);
135
+ if (groupId instanceof Error)
136
+ return makeErrorResult(groupId);
137
+ const configId = requireConfigId(input);
138
+ if (configId instanceof Error)
139
+ return makeErrorResult(configId);
140
+ const accountId = Number(input.accountId);
141
+ if (!Number.isFinite(accountId) || accountId <= 0)
142
+ return makeErrorResult(new Error("accountId is required and must be a positive integer"));
143
+ const userId = await resolver.resolve(client);
144
+ const res = await client.patch(`/api/account/${userId}/groups/${groupId}/contract-configs/${configId}/accounts/${accountId}`, { isCopySource: true });
145
+ return {
146
+ content: [
147
+ { type: "text", text: `### Leader set\nAccount #${accountId} promoted to leader in config #${configId} (group #${groupId}). Prior leader in this config auto-demoted; other configs unaffected.` },
148
+ { type: "text", text: JSON.stringify(res, null, 2) },
149
+ ],
150
+ };
151
+ }
152
+ catch (e) {
153
+ return makeErrorResult(e);
154
+ }
155
+ }
156
+ export async function updateContractConfigFollower(client, resolver, input) {
157
+ try {
158
+ const groupId = requireGroupId(input);
159
+ if (groupId instanceof Error)
160
+ return makeErrorResult(groupId);
161
+ const configId = requireConfigId(input);
162
+ if (configId instanceof Error)
163
+ return makeErrorResult(configId);
164
+ const accountId = Number(input.accountId);
165
+ if (!Number.isFinite(accountId) || accountId <= 0)
166
+ return makeErrorResult(new Error("accountId is required and must be a positive integer"));
167
+ const body = {};
168
+ for (const key of ["quantityMultiplier", "respectAccountHalt"]) {
169
+ if (key in input)
170
+ body[key] = input[key];
171
+ }
172
+ if (Object.keys(body).length === 0)
173
+ return makeErrorResult(new Error("At least one field (quantityMultiplier, respectAccountHalt) must be supplied"));
174
+ const userId = await resolver.resolve(client);
175
+ const res = await client.patch(`/api/account/${userId}/groups/${groupId}/contract-configs/${configId}/accounts/${accountId}`, body);
176
+ return {
177
+ content: [
178
+ { type: "text", text: `### Follower settings updated\nAccount #${accountId} in config #${configId} (group #${groupId})` },
179
+ { type: "text", text: JSON.stringify(res, null, 2) },
180
+ ],
181
+ };
182
+ }
183
+ catch (e) {
184
+ return makeErrorResult(e);
185
+ }
186
+ }
187
+ //# sourceMappingURL=contract-configs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-configs.js","sourceRoot":"","sources":["../../src/tools/contract-configs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,245 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { listContractConfigs, createContractConfig, updateContractConfig, deleteContractConfig, rollContractConfig, setContractConfigLeader, updateContractConfigFollower, } from "./contract-configs.js";
3
+ const makeResolver = (userId = 7) => ({ resolve: async () => userId });
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ const makeClient = (overrides) => overrides;
6
+ // ── list_contract_configs ─────────────────────────────────────────────────────
7
+ describe("list_contract_configs", () => {
8
+ it("GETs the contract-configs endpoint and summarises results", async () => {
9
+ let calledPath = "";
10
+ const client = makeClient({
11
+ get: (path) => {
12
+ calledPath = path;
13
+ return Promise.resolve([
14
+ { id: 1, symbolRoot: "MES", isDeleted: false },
15
+ { id: 2, symbolRoot: "MNQ", isDeleted: false },
16
+ ]);
17
+ },
18
+ });
19
+ const result = await listContractConfigs(client, makeResolver(7), { groupId: 3 });
20
+ expect(result.isError).toBeUndefined();
21
+ expect(calledPath).toBe("/api/account/7/groups/3/contract-configs");
22
+ expect(result.content[0].text).toContain("group #3");
23
+ expect(result.content[0].text).toContain("2 config(s)");
24
+ });
25
+ it("returns isError when groupId is missing or invalid", async () => {
26
+ const client = makeClient({ get: () => Promise.reject(new Error("no")) });
27
+ expect((await listContractConfigs(client, makeResolver(), {})).isError).toBe(true);
28
+ expect((await listContractConfigs(client, makeResolver(), { groupId: 0 })).isError).toBe(true);
29
+ expect((await listContractConfigs(client, makeResolver(), { groupId: -1 })).isError).toBe(true);
30
+ });
31
+ it("surfaces API errors as isError", async () => {
32
+ const client = makeClient({ get: () => Promise.reject(new Error("403 forbidden")) });
33
+ const result = await listContractConfigs(client, makeResolver(), { groupId: 1 });
34
+ expect(result.isError).toBe(true);
35
+ expect(result.content[0].text).toContain("403");
36
+ });
37
+ });
38
+ // ── create_contract_config ────────────────────────────────────────────────────
39
+ describe("create_contract_config", () => {
40
+ it("POSTs symbolRoot uppercased and returns created config", async () => {
41
+ let capturedPath = "";
42
+ let capturedBody;
43
+ const client = makeClient({
44
+ post: (path, body) => {
45
+ capturedPath = path;
46
+ capturedBody = body;
47
+ return Promise.resolve({ id: 10, symbolRoot: "MES" });
48
+ },
49
+ });
50
+ const result = await createContractConfig(client, makeResolver(7), {
51
+ groupId: 3,
52
+ symbolRoot: "mes",
53
+ });
54
+ expect(result.isError).toBeUndefined();
55
+ expect(capturedPath).toBe("/api/account/7/groups/3/contract-configs");
56
+ expect(capturedBody).toEqual({ symbolRoot: "MES" });
57
+ expect(result.content[0].text).toContain("config #10");
58
+ expect(result.content[0].text).toContain("MES");
59
+ });
60
+ it("returns isError when symbolRoot is missing", async () => {
61
+ const client = makeClient({ post: () => Promise.reject(new Error("no")) });
62
+ const result = await createContractConfig(client, makeResolver(), { groupId: 1 });
63
+ expect(result.isError).toBe(true);
64
+ expect(result.content[0].text).toContain("symbolRoot");
65
+ });
66
+ it("returns isError when groupId is invalid", async () => {
67
+ const client = makeClient({ post: () => Promise.reject(new Error("no")) });
68
+ expect((await createContractConfig(client, makeResolver(), { symbolRoot: "MES" })).isError).toBe(true);
69
+ });
70
+ });
71
+ // ── update_contract_config ────────────────────────────────────────────────────
72
+ describe("update_contract_config", () => {
73
+ it("PATCHes only the supplied fields and uppercases symbolRoot", async () => {
74
+ let capturedBody;
75
+ const client = makeClient({
76
+ patch: (_path, body) => {
77
+ capturedBody = body;
78
+ return Promise.resolve({ id: 5, symbolRoot: "MNQ" });
79
+ },
80
+ });
81
+ const result = await updateContractConfig(client, makeResolver(), {
82
+ groupId: 3,
83
+ configId: 5,
84
+ symbolRoot: "mnq",
85
+ });
86
+ expect(result.isError).toBeUndefined();
87
+ expect(capturedBody).toEqual({ symbolRoot: "MNQ" });
88
+ expect(result.content[0].text).toContain("Config #5");
89
+ });
90
+ it("returns isError when no updatable field supplied", async () => {
91
+ const client = makeClient({ patch: () => Promise.reject(new Error("no")) });
92
+ const result = await updateContractConfig(client, makeResolver(), { groupId: 1, configId: 2 });
93
+ expect(result.isError).toBe(true);
94
+ expect(result.content[0].text).toContain("symbolRoot");
95
+ });
96
+ it("returns isError when groupId or configId is missing", async () => {
97
+ const client = makeClient({ patch: () => Promise.reject(new Error("no")) });
98
+ expect((await updateContractConfig(client, makeResolver(), { configId: 1, symbolRoot: "MES" })).isError).toBe(true);
99
+ expect((await updateContractConfig(client, makeResolver(), { groupId: 1, symbolRoot: "MES" })).isError).toBe(true);
100
+ });
101
+ });
102
+ // ── delete_contract_config ────────────────────────────────────────────────────
103
+ describe("delete_contract_config", () => {
104
+ it("calls DELETE on the correct path", async () => {
105
+ let calledPath = "";
106
+ const client = makeClient({
107
+ delete: (path) => {
108
+ calledPath = path;
109
+ return Promise.resolve(undefined);
110
+ },
111
+ });
112
+ const result = await deleteContractConfig(client, makeResolver(7), { groupId: 3, configId: 9 });
113
+ expect(result.isError).toBeUndefined();
114
+ expect(calledPath).toBe("/api/account/7/groups/3/contract-configs/9");
115
+ expect(result.content[0].text).toContain("Config #9");
116
+ expect(result.content[0].text).toContain("group #3");
117
+ });
118
+ it("returns isError when groupId or configId is invalid", async () => {
119
+ const client = makeClient({ delete: () => Promise.reject(new Error("no")) });
120
+ expect((await deleteContractConfig(client, makeResolver(), { configId: 1 })).isError).toBe(true);
121
+ expect((await deleteContractConfig(client, makeResolver(), { groupId: 1 })).isError).toBe(true);
122
+ });
123
+ });
124
+ // ── roll_contract_config ──────────────────────────────────────────────────────
125
+ describe("roll_contract_config", () => {
126
+ it("POSTs roll with newSymbol uppercased and optional expectedCurrentSymbol", async () => {
127
+ let capturedPath = "";
128
+ let capturedBody;
129
+ const client = makeClient({
130
+ post: (path, body) => {
131
+ capturedPath = path;
132
+ capturedBody = body;
133
+ return Promise.resolve({ id: 5, currentSymbol: "MESM6" });
134
+ },
135
+ });
136
+ const result = await rollContractConfig(client, makeResolver(7), {
137
+ groupId: 3,
138
+ configId: 5,
139
+ newSymbol: "mesu6",
140
+ expectedCurrentSymbol: "mesm6",
141
+ });
142
+ expect(result.isError).toBeUndefined();
143
+ expect(capturedPath).toBe("/api/account/7/groups/3/contract-configs/5/roll");
144
+ expect(capturedBody).toEqual({ newSymbol: "MESU6", expectedCurrentSymbol: "MESM6" });
145
+ expect(result.content[0].text).toContain("MESU6");
146
+ });
147
+ it("omits expectedCurrentSymbol when not supplied", async () => {
148
+ let capturedBody;
149
+ const client = makeClient({
150
+ post: (_path, body) => {
151
+ capturedBody = body;
152
+ return Promise.resolve({});
153
+ },
154
+ });
155
+ await rollContractConfig(client, makeResolver(), { groupId: 1, configId: 2, newSymbol: "MESZ6" });
156
+ expect(capturedBody).toEqual({ newSymbol: "MESZ6" });
157
+ });
158
+ it("returns isError when newSymbol is missing", async () => {
159
+ const client = makeClient({ post: () => Promise.reject(new Error("no")) });
160
+ const result = await rollContractConfig(client, makeResolver(), { groupId: 1, configId: 2 });
161
+ expect(result.isError).toBe(true);
162
+ expect(result.content[0].text).toContain("newSymbol");
163
+ });
164
+ });
165
+ // ── set_contract_config_leader ────────────────────────────────────────────────
166
+ describe("set_contract_config_leader", () => {
167
+ it("PATCHes isCopySource=true on the account subresource", async () => {
168
+ let capturedPath = "";
169
+ let capturedBody;
170
+ const client = makeClient({
171
+ patch: (path, body) => {
172
+ capturedPath = path;
173
+ capturedBody = body;
174
+ return Promise.resolve({ accountId: 42, isCopySource: true });
175
+ },
176
+ });
177
+ const result = await setContractConfigLeader(client, makeResolver(7), {
178
+ groupId: 3,
179
+ configId: 5,
180
+ accountId: 42,
181
+ });
182
+ expect(result.isError).toBeUndefined();
183
+ expect(capturedPath).toBe("/api/account/7/groups/3/contract-configs/5/accounts/42");
184
+ expect(capturedBody).toEqual({ isCopySource: true });
185
+ expect(result.content[0].text).toContain("Account #42");
186
+ expect(result.content[0].text).toContain("leader");
187
+ });
188
+ it("returns isError when accountId is missing or invalid", async () => {
189
+ const client = makeClient({ patch: () => Promise.reject(new Error("no")) });
190
+ expect((await setContractConfigLeader(client, makeResolver(), { groupId: 1, configId: 2 })).isError).toBe(true);
191
+ expect((await setContractConfigLeader(client, makeResolver(), { groupId: 1, configId: 2, accountId: 0 })).isError).toBe(true);
192
+ });
193
+ });
194
+ // ── update_contract_config_follower ───────────────────────────────────────────
195
+ describe("update_contract_config_follower", () => {
196
+ it("PATCHes quantityMultiplier and respectAccountHalt when both supplied", async () => {
197
+ let capturedBody;
198
+ const client = makeClient({
199
+ patch: (_path, body) => {
200
+ capturedBody = body;
201
+ return Promise.resolve({ quantityMultiplier: 2, respectAccountHalt: true });
202
+ },
203
+ });
204
+ const result = await updateContractConfigFollower(client, makeResolver(), {
205
+ groupId: 3,
206
+ configId: 5,
207
+ accountId: 42,
208
+ quantityMultiplier: 2,
209
+ respectAccountHalt: true,
210
+ });
211
+ expect(result.isError).toBeUndefined();
212
+ expect(capturedBody).toEqual({ quantityMultiplier: 2, respectAccountHalt: true });
213
+ expect(result.content[0].text).toContain("Account #42");
214
+ });
215
+ it("forwards only the supplied field when just one is provided", async () => {
216
+ let capturedBody;
217
+ const client = makeClient({
218
+ patch: (_path, body) => {
219
+ capturedBody = body;
220
+ return Promise.resolve({ quantityMultiplier: 3 });
221
+ },
222
+ });
223
+ await updateContractConfigFollower(client, makeResolver(), {
224
+ groupId: 1, configId: 2, accountId: 5, quantityMultiplier: 3,
225
+ });
226
+ expect(capturedBody).toEqual({ quantityMultiplier: 3 });
227
+ });
228
+ it("returns isError when no updatable field is supplied", async () => {
229
+ const client = makeClient({ patch: () => Promise.reject(new Error("no")) });
230
+ const result = await updateContractConfigFollower(client, makeResolver(), {
231
+ groupId: 1, configId: 2, accountId: 5,
232
+ });
233
+ expect(result.isError).toBe(true);
234
+ expect(result.content[0].text).toContain("quantityMultiplier");
235
+ });
236
+ it("surfaces API errors as isError", async () => {
237
+ const client = makeClient({ patch: () => Promise.reject(new Error("409 conflict")) });
238
+ const result = await updateContractConfigFollower(client, makeResolver(), {
239
+ groupId: 1, configId: 2, accountId: 5, quantityMultiplier: 1,
240
+ });
241
+ expect(result.isError).toBe(true);
242
+ expect(result.content[0].text).toContain("409");
243
+ });
244
+ });
245
+ //# sourceMappingURL=contract-configs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-configs.test.js","sourceRoot":"","sources":["../../src/tools/contract-configs.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { VantageClient } from "../client.js";
2
+ import { UserResolver, ToolResult } from "../user.js";
3
+ /**
4
+ * CT-01-S5 — set per-account copy-trading settings on a signal group.
5
+ * Wraps `PATCH /api/account/{userId}/groups/{groupId}/accounts/{accountId}/copier`.
6
+ * All seven copier fields are optional; only fields you supply are updated.
7
+ * The endpoint enforces the at-most-one-copy-source-per-group invariant
8
+ * (partial unique index `ux_signal_group_accounts_copy_source_per_group`)
9
+ * and surfaces a 409 Conflict if a second account is set as the source.
10
+ */
11
+ export declare function setCopierSettings(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
@@ -0,0 +1,52 @@
1
+ import { makeErrorResult } from "../user.js";
2
+ /**
3
+ * CT-01-S5 — set per-account copy-trading settings on a signal group.
4
+ * Wraps `PATCH /api/account/{userId}/groups/{groupId}/accounts/{accountId}/copier`.
5
+ * All seven copier fields are optional; only fields you supply are updated.
6
+ * The endpoint enforces the at-most-one-copy-source-per-group invariant
7
+ * (partial unique index `ux_signal_group_accounts_copy_source_per_group`)
8
+ * and surfaces a 409 Conflict if a second account is set as the source.
9
+ */
10
+ export async function setCopierSettings(client, resolver, input) {
11
+ try {
12
+ const groupId = Number(input.groupId);
13
+ const accountId = Number(input.accountId);
14
+ if (!Number.isFinite(groupId) || groupId <= 0)
15
+ return makeErrorResult(new Error("groupId is required and must be a positive integer"));
16
+ if (!Number.isFinite(accountId) || accountId <= 0)
17
+ return makeErrorResult(new Error("accountId is required and must be a positive integer"));
18
+ // Build the partial-PATCH body — only forward fields the caller supplied.
19
+ // GMODE-07: `ordersModeEnabled` is a per-follower CT-Orders opt-out
20
+ // (persisted); `syncExistingWorkingOrders` is a write-only side-effect
21
+ // flag — when true the server fires `CopierWorkingOrderReplay` for the
22
+ // freshly-promoted leader's open broker orders.
23
+ const body = {};
24
+ for (const key of [
25
+ "isCopySource", "copierEnabled", "contractTypeOverride", "floorQtyAtOne",
26
+ "fadeMode", "longOnly", "shortOnly",
27
+ "ordersModeEnabled", "syncExistingWorkingOrders",
28
+ ]) {
29
+ if (key in input)
30
+ body[key] = input[key];
31
+ }
32
+ if (Object.keys(body).length === 0)
33
+ return makeErrorResult(new Error("At least one copier field must be supplied"));
34
+ const userId = await resolver.resolve(client);
35
+ const res = await client.patch(`/api/account/${userId}/groups/${groupId}/accounts/${accountId}/copier`, body);
36
+ const summary = [`### Copier settings updated`,
37
+ `Group #${groupId} → account row #${accountId}\n`];
38
+ for (const k of [
39
+ "isCopySource", "copierEnabled", "contractTypeOverride", "floorQtyAtOne",
40
+ "fadeMode", "longOnly", "shortOnly",
41
+ "ordersModeEnabled", "syncExistingWorkingOrders",
42
+ ]) {
43
+ if (res?.[k] !== undefined)
44
+ summary.push(`- **${k}:** ${String(res[k])}`);
45
+ }
46
+ return { content: [{ type: "text", text: summary.join("\n") }] };
47
+ }
48
+ catch (e) {
49
+ return makeErrorResult(e);
50
+ }
51
+ }
52
+ //# sourceMappingURL=copier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copier.js","sourceRoot":"","sources":["../../src/tools/copier.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,eAAe,EAAc,MAAM,YAAY,CAAC;AAEvE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAqB,EACrB,QAAsB,EACtB,KAA8B;IAE9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,SAAS,GAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;YAC3C,OAAO,eAAe,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC1F,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;YAC/C,OAAO,eAAe,CAAC,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC,CAAC;QAE5F,0EAA0E;QAC1E,oEAAoE;QACpE,uEAAuE;QACvE,uEAAuE;QACvE,gDAAgD;QAChD,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI;YAChB,cAAc,EAAE,eAAe,EAAE,sBAAsB,EAAE,eAAe;YACxE,UAAU,EAAE,UAAU,EAAE,WAAW;YACnC,mBAAmB,EAAE,2BAA2B;SACjD,EAAE,CAAC;YACF,IAAI,GAAG,IAAI,KAAK;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAChC,OAAO,eAAe,CAAC,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC,CAAC;QAElF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAC5B,gBAAgB,MAAM,WAAW,OAAO,aAAa,SAAS,SAAS,EAAE,IAAI,CAAC,CAAC;QAEjF,MAAM,OAAO,GAAa,CAAC,6BAA6B;YACtD,UAAU,OAAO,mBAAmB,SAAS,IAAI,CAAC,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI;YACd,cAAc,EAAE,eAAe,EAAE,sBAAsB,EAAE,eAAe;YACxE,UAAU,EAAE,UAAU,EAAE,WAAW;YACnC,mBAAmB,EAAE,2BAA2B;SACjD,EAAE,CAAC;YACF,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACnE,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};