angel-one-mcp 1.0.7 → 1.0.8
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/build/config.d.ts +4 -0
- package/build/config.js +41 -14
- package/build/index.js +67 -16
- package/package.json +1 -1
package/build/config.d.ts
CHANGED
|
@@ -12,4 +12,8 @@ export interface Credentials {
|
|
|
12
12
|
}
|
|
13
13
|
export interface Config extends Credentials, SafetyConfig {
|
|
14
14
|
}
|
|
15
|
+
export declare const REQUIRED_ENV_VARS: readonly ["ANGEL_API_KEY", "ANGEL_CLIENT_ID", "ANGEL_PASSWORD", "ANGEL_TOTP_SECRET"];
|
|
16
|
+
export declare class ConfigError extends Error {
|
|
17
|
+
constructor(message: string);
|
|
18
|
+
}
|
|
15
19
|
export declare function loadConfig(): Config;
|
package/build/config.js
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
1
|
+
export const REQUIRED_ENV_VARS = [
|
|
2
|
+
"ANGEL_API_KEY",
|
|
3
|
+
"ANGEL_CLIENT_ID",
|
|
4
|
+
"ANGEL_PASSWORD",
|
|
5
|
+
"ANGEL_TOTP_SECRET",
|
|
6
|
+
];
|
|
7
|
+
export class ConfigError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ConfigError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function formatMissingEnvMessage(missing) {
|
|
14
|
+
return [
|
|
15
|
+
"Missing required environment variables:",
|
|
16
|
+
...missing.map((name) => `- ${name}`),
|
|
17
|
+
"",
|
|
18
|
+
"Set them in your MCP client config or a local .env file before starting the server.",
|
|
19
|
+
"Example:",
|
|
20
|
+
"ANGEL_API_KEY=your_smartapi_key",
|
|
21
|
+
"ANGEL_CLIENT_ID=your_client_id",
|
|
22
|
+
"ANGEL_PASSWORD=your_mpin",
|
|
23
|
+
"ANGEL_TOTP_SECRET=your_base32_totp_secret",
|
|
24
|
+
].join("\n");
|
|
25
|
+
}
|
|
26
|
+
function requireEnv(name) {
|
|
27
|
+
const value = process.env[name];
|
|
28
|
+
if (!value) {
|
|
29
|
+
throw new ConfigError(formatMissingEnvMessage([name]));
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
1
33
|
export function loadConfig() {
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const totpSecret = process.env.ANGEL_TOTP_SECRET;
|
|
6
|
-
if (!apiKey || !clientId || !password || !totpSecret) {
|
|
7
|
-
const missing = [
|
|
8
|
-
!apiKey && "ANGEL_API_KEY",
|
|
9
|
-
!clientId && "ANGEL_CLIENT_ID",
|
|
10
|
-
!password && "ANGEL_PASSWORD",
|
|
11
|
-
!totpSecret && "ANGEL_TOTP_SECRET",
|
|
12
|
-
].filter(Boolean);
|
|
13
|
-
throw new Error(`Missing required env vars: ${missing.join(", ")}`);
|
|
34
|
+
const missing = REQUIRED_ENV_VARS.filter((name) => !process.env[name]);
|
|
35
|
+
if (missing.length > 0) {
|
|
36
|
+
throw new ConfigError(formatMissingEnvMessage(missing));
|
|
14
37
|
}
|
|
38
|
+
const apiKey = requireEnv("ANGEL_API_KEY");
|
|
39
|
+
const clientId = requireEnv("ANGEL_CLIENT_ID");
|
|
40
|
+
const password = requireEnv("ANGEL_PASSWORD");
|
|
41
|
+
const totpSecret = requireEnv("ANGEL_TOTP_SECRET");
|
|
15
42
|
const parseIntSafe = (name, val, fallback) => {
|
|
16
43
|
if (!val)
|
|
17
44
|
return fallback;
|
|
@@ -33,10 +60,10 @@ export function loadConfig() {
|
|
|
33
60
|
hardMaxOrderValue: parseIntSafe("HARD_MAX_ORDER_VALUE", process.env.HARD_MAX_ORDER_VALUE, 100000),
|
|
34
61
|
};
|
|
35
62
|
if (config.softMaxOrderQty > config.hardMaxOrderQty) {
|
|
36
|
-
throw new
|
|
63
|
+
throw new ConfigError(`SOFT_MAX_ORDER_QTY (${config.softMaxOrderQty}) must be ≤ HARD_MAX_ORDER_QTY (${config.hardMaxOrderQty})`);
|
|
37
64
|
}
|
|
38
65
|
if (config.softMaxOrderValue > config.hardMaxOrderValue) {
|
|
39
|
-
throw new
|
|
66
|
+
throw new ConfigError(`SOFT_MAX_ORDER_VALUE (${config.softMaxOrderValue}) must be ≤ HARD_MAX_ORDER_VALUE (${config.hardMaxOrderValue})`);
|
|
40
67
|
}
|
|
41
68
|
return config;
|
|
42
69
|
}
|
package/build/index.js
CHANGED
|
@@ -4,21 +4,72 @@ import { readFileSync } from "node:fs";
|
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
import { AngelOneAPI } from "./api.js";
|
|
7
|
-
import { loadConfig } from "./config.js";
|
|
7
|
+
import { ConfigError, REQUIRED_ENV_VARS, loadConfig } from "./config.js";
|
|
8
8
|
import { registerAllTools } from "./tools/index.js";
|
|
9
9
|
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
const HELP_TEXT = `angel-one-mcp v${pkg.version}
|
|
11
|
+
|
|
12
|
+
MCP stdio server for Angel One SmartAPI.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
npx -y angel-one-mcp
|
|
16
|
+
|
|
17
|
+
Required environment variables:
|
|
18
|
+
${REQUIRED_ENV_VARS.map((name) => ` - ${name}`).join("\n")}
|
|
19
|
+
|
|
20
|
+
Optional safety limits:
|
|
21
|
+
- SOFT_MAX_ORDER_QTY (default: 25)
|
|
22
|
+
- HARD_MAX_ORDER_QTY (default: 100)
|
|
23
|
+
- SOFT_MAX_ORDER_VALUE (default: 10000)
|
|
24
|
+
- HARD_MAX_ORDER_VALUE (default: 100000)
|
|
25
|
+
|
|
26
|
+
Example MCP client config:
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"angel-one": {
|
|
30
|
+
"command": "npx",
|
|
31
|
+
"args": ["-y", "angel-one-mcp"],
|
|
32
|
+
"env": {
|
|
33
|
+
"ANGEL_API_KEY": "your_smartapi_key",
|
|
34
|
+
"ANGEL_CLIENT_ID": "your_client_id",
|
|
35
|
+
"ANGEL_PASSWORD": "your_mpin",
|
|
36
|
+
"ANGEL_TOTP_SECRET": "your_base32_totp_secret"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
function wantsHelp(args) {
|
|
43
|
+
return args.includes("--help") || args.includes("-h");
|
|
44
|
+
}
|
|
45
|
+
async function main() {
|
|
46
|
+
if (wantsHelp(process.argv.slice(2))) {
|
|
47
|
+
process.stdout.write(HELP_TEXT);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const config = loadConfig();
|
|
51
|
+
const api = new AngelOneAPI(config);
|
|
52
|
+
const safetyConfig = {
|
|
53
|
+
softMaxOrderQty: config.softMaxOrderQty,
|
|
54
|
+
hardMaxOrderQty: config.hardMaxOrderQty,
|
|
55
|
+
softMaxOrderValue: config.softMaxOrderValue,
|
|
56
|
+
hardMaxOrderValue: config.hardMaxOrderValue,
|
|
57
|
+
};
|
|
58
|
+
const server = new McpServer({
|
|
59
|
+
name: "angel-one",
|
|
60
|
+
version: pkg.version,
|
|
61
|
+
});
|
|
62
|
+
registerAllTools(server, api, safetyConfig);
|
|
63
|
+
const transport = new StdioServerTransport();
|
|
64
|
+
await server.connect(transport);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
await main();
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof ConfigError) {
|
|
71
|
+
process.stderr.write(`${error.message}\n`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "angel-one-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "MCP server for Angel One SmartAPI — trade stocks, track portfolio, analyze markets & manage orders via LLM clients like Claude, Cursor & Copilot",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|