@cyanheads/calculator-mcp-server 0.1.6

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/README.md ADDED
@@ -0,0 +1,177 @@
1
+ <div align="center">
2
+ <h1>@cyanheads/calculator-mcp-server</h1>
3
+ <p><b>A calculator MCP server that lets any LLM verify mathematical computations. Evaluate, simplify, and differentiate expressions via a single tool. Powered by math.js v15.</b></p>
4
+ <p><b>1 Tool · 1 Resource</b></p>
5
+ </div>
6
+
7
+ <div align="center">
8
+
9
+ [![Version](https://img.shields.io/badge/Version-0.1.6-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.28.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-6.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/)
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ ## Tools
16
+
17
+ One tool for all mathematical operations:
18
+
19
+ | Tool Name | Description |
20
+ |:----------|:------------|
21
+ | `calculate` | Evaluate math expressions, simplify algebraic expressions, or compute symbolic derivatives. |
22
+
23
+ ### `calculate`
24
+
25
+ A single tool covering 100% of the server's purpose. The `operation` parameter defaults to `evaluate`, so the common case is just `{ expression: "..." }`.
26
+
27
+ - **Evaluate** — arithmetic, trigonometry, logarithms, statistics, matrices, complex numbers, unit conversion, combinatorics
28
+ - **Simplify** — reduce algebraic expressions symbolically (e.g., `2x + 3x` -> `5 * x`). Supports algebraic and trigonometric identities
29
+ - **Derivative** — compute symbolic derivatives (e.g., `3x^2 + 2x + 1` -> `6 * x + 2`)
30
+ - Variable scope via `scope` parameter: `{ "x": 5, "y": 3 }`
31
+ - Configurable precision for numeric results
32
+
33
+ ---
34
+
35
+ ## Resources
36
+
37
+ | URI Pattern | Description |
38
+ |:------------|:------------|
39
+ | `calculator://help` | Available functions, operators, constants, and syntax reference. |
40
+
41
+ ---
42
+
43
+ ## Features
44
+
45
+ Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core):
46
+
47
+ - Declarative tool definitions — single file per tool, framework handles registration and validation
48
+ - Unified error handling across all tools
49
+ - Structured logging with optional OpenTelemetry tracing
50
+ - Runs locally (stdio/HTTP) or in Docker
51
+
52
+ Calculator-specific:
53
+
54
+ - Hardened math.js v15 instance — dangerous functions disabled, evaluation sandboxed via `vm.runInNewContext()` with timeout
55
+ - No auth required — all operations are read-only and stateless
56
+ - Input validation: expression length limits, expression separator rejection (semicolons and newlines), variable name regex enforcement
57
+ - Result validation: blocked result types (functions, parsers, result sets), configurable max result size
58
+ - Scope sanitization: numeric-only values, prototype pollution prevention (blocked `__proto__`, `constructor`, etc.)
59
+
60
+ ---
61
+
62
+ ## Getting Started
63
+
64
+ ### MCP Client Configuration
65
+
66
+ Add to your MCP client config (e.g., `claude_desktop_config.json`):
67
+
68
+ ```json
69
+ {
70
+ "mcpServers": {
71
+ "calculator": {
72
+ "type": "stdio",
73
+ "command": "bunx",
74
+ "args": ["@cyanheads/calculator-mcp-server@latest"]
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ### Prerequisites
81
+
82
+ - [Bun v1.2.0](https://bun.sh/) or higher
83
+
84
+ ### Installation
85
+
86
+ 1. **Clone the repository:**
87
+ ```sh
88
+ git clone https://github.com/cyanheads/calculator-mcp-server.git
89
+ ```
90
+
91
+ 2. **Navigate into the directory:**
92
+ ```sh
93
+ cd calculator-mcp-server
94
+ ```
95
+
96
+ 3. **Install dependencies:**
97
+ ```sh
98
+ bun install
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Configuration
104
+
105
+ | Variable | Description | Default |
106
+ |:---------|:------------|:--------|
107
+ | `CALC_MAX_EXPRESSION_LENGTH` | Maximum allowed expression string length (10–10,000). | `1000` |
108
+ | `CALC_EVALUATION_TIMEOUT_MS` | Maximum evaluation time in milliseconds (100–30,000). | `5000` |
109
+ | `CALC_MAX_RESULT_LENGTH` | Maximum result string length in characters (1,000–1,000,000). | `100000` |
110
+ | `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
111
+ | `MCP_HTTP_PORT` | Port for HTTP server. | `3010` |
112
+ | `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
113
+ | `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
114
+
115
+ ---
116
+
117
+ ## Running the Server
118
+
119
+ ### Local Development
120
+
121
+ - **Build and run the production version:**
122
+ ```sh
123
+ bun run build
124
+ bun run start:http # or start:stdio
125
+ ```
126
+
127
+ - **Run checks and tests:**
128
+ ```sh
129
+ bun run devcheck # Lints, formats, type-checks
130
+ bun run test # Runs test suite
131
+ ```
132
+
133
+ ### Docker
134
+
135
+ ```sh
136
+ docker build -t calculator-mcp-server .
137
+ docker run -p 3010:3010 calculator-mcp-server
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Project Structure
143
+
144
+ | Directory | Purpose |
145
+ |:----------|:--------|
146
+ | `src/mcp-server/tools/` | Tool definitions (`*.tool.ts`). |
147
+ | `src/mcp-server/resources/` | Resource definitions (`*.resource.ts`). |
148
+ | `src/services/` | Domain service integrations (MathService). |
149
+ | `src/config/` | Environment variable parsing and validation with Zod. |
150
+ | `docs/` | Generated directory tree. |
151
+
152
+ ---
153
+
154
+ ## Development Guide
155
+
156
+ See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
157
+
158
+ - Handlers throw, framework catches — no `try/catch` in tool logic
159
+ - Use `ctx.log` for logging
160
+ - Register new tools and resources in `src/index.ts`
161
+
162
+ ---
163
+
164
+ ## Contributing
165
+
166
+ Issues and pull requests are welcome. Run checks before submitting:
167
+
168
+ ```sh
169
+ bun run devcheck
170
+ bun run test
171
+ ```
172
+
173
+ ---
174
+
175
+ ## License
176
+
177
+ Apache-2.0 — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview Server-specific configuration for calculator-mcp-server.
3
+ * @module config/server-config
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ declare const ServerConfigSchema: z.ZodObject<{
7
+ maxExpressionLength: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
8
+ evaluationTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
9
+ maxResultLength: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
10
+ }, z.core.$strip>;
11
+ export type ServerConfig = z.infer<typeof ServerConfigSchema>;
12
+ /** Lazy-parsed server config from env vars. */
13
+ export declare function getServerConfig(): ServerConfig;
14
+ export {};
15
+ //# sourceMappingURL=server-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,QAAA,MAAM,kBAAkB;;;;iBAsBtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,+CAA+C;AAC/C,wBAAgB,eAAe,IAAI,YAAY,CAO9C"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview Server-specific configuration for calculator-mcp-server.
3
+ * @module config/server-config
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ const ServerConfigSchema = z.object({
7
+ maxExpressionLength: z.coerce
8
+ .number()
9
+ .int()
10
+ .min(10)
11
+ .max(10_000)
12
+ .default(1000)
13
+ .describe('Maximum allowed expression string length (10–10,000)'),
14
+ evaluationTimeoutMs: z.coerce
15
+ .number()
16
+ .int()
17
+ .min(100)
18
+ .max(30_000)
19
+ .default(5000)
20
+ .describe('Maximum evaluation time in milliseconds (100–30,000)'),
21
+ maxResultLength: z.coerce
22
+ .number()
23
+ .int()
24
+ .min(1_000)
25
+ .max(1_000_000)
26
+ .default(100_000)
27
+ .describe('Maximum result string length in characters (1,000–1,000,000)'),
28
+ });
29
+ let _config;
30
+ /** Lazy-parsed server config from env vars. */
31
+ export function getServerConfig() {
32
+ _config ??= ServerConfigSchema.parse({
33
+ maxExpressionLength: process.env.CALC_MAX_EXPRESSION_LENGTH,
34
+ evaluationTimeoutMs: process.env.CALC_EVALUATION_TIMEOUT_MS,
35
+ maxResultLength: process.env.CALC_MAX_RESULT_LENGTH,
36
+ });
37
+ return _config;
38
+ }
39
+ //# sourceMappingURL=server-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,MAAM;SAC1B,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,EAAE,CAAC;SACP,GAAG,CAAC,MAAM,CAAC;SACX,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,sDAAsD,CAAC;IACnE,mBAAmB,EAAE,CAAC,CAAC,MAAM;SAC1B,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,GAAG,CAAC;SACR,GAAG,CAAC,MAAM,CAAC;SACX,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,sDAAsD,CAAC;IACnE,eAAe,EAAE,CAAC,CAAC,MAAM;SACtB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,KAAK,CAAC;SACV,GAAG,CAAC,SAAS,CAAC;SACd,OAAO,CAAC,OAAO,CAAC;SAChB,QAAQ,CAAC,8DAA8D,CAAC;CAC5E,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,+CAA+C;AAC/C,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,kBAAkB,CAAC,KAAK,CAAC;QACnC,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;QAC3D,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;QAC3D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;KACpD,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview calculator-mcp-server entry point.
4
+ * @module index
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview calculator-mcp-server entry point.
4
+ * @module index
5
+ */
6
+ import { createApp } from '@cyanheads/mcp-ts-core';
7
+ import { getServerConfig } from './config/server-config.js';
8
+ import { helpResource } from './mcp-server/resources/definitions/help.resource.js';
9
+ import { calculateTool } from './mcp-server/tools/definitions/calculate.tool.js';
10
+ import { initMathService } from './services/math/math-service.js';
11
+ await createApp({
12
+ tools: [calculateTool],
13
+ resources: [helpResource],
14
+ setup() {
15
+ initMathService(getServerConfig());
16
+ },
17
+ });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qDAAqD,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,kDAAkD,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE,CAAC,aAAa,CAAC;IACtB,SAAS,EAAE,CAAC,YAAY,CAAC;IACzB,KAAK;QACH,eAAe,CAAC,eAAe,EAAE,CAAC,CAAC;IACrC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Help resource — static reference of available functions, operators, and syntax.
3
+ * @module mcp-server/resources/definitions/help.resource
4
+ */
5
+ export declare const helpResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<Readonly<{
6
+ [k: string]: import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>;
7
+ }>, import("zod/v4/core").$strip>, undefined>;
8
+ //# sourceMappingURL=help.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/help.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,MAAM,YAAY;;6CAOvB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview Help resource — static reference of available functions, operators, and syntax.
3
+ * @module mcp-server/resources/definitions/help.resource
4
+ */
5
+ import { resource } from '@cyanheads/mcp-ts-core';
6
+ import { getMathService } from '../../../services/math/math-service.js';
7
+ export const helpResource = resource('calculator://help', {
8
+ name: 'Calculator Help',
9
+ description: 'Available functions, operators, constants, and syntax reference.',
10
+ mimeType: 'text/markdown',
11
+ handler() {
12
+ return getMathService().getHelpContent();
13
+ },
14
+ });
15
+ //# sourceMappingURL=help.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/help.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC,mBAAmB,EAAE;IACxD,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,kEAAkE;IAC/E,QAAQ,EAAE,eAAe;IACzB,OAAO;QACL,OAAO,cAAc,EAAE,CAAC,cAAc,EAAE,CAAC;IAC3C,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview Calculate tool — evaluate, simplify, or differentiate math expressions.
3
+ * Single tool covering 100% of the server's purpose.
4
+ * @module mcp-server/tools/definitions/calculate.tool
5
+ */
6
+ import { z } from '@cyanheads/mcp-ts-core';
7
+ export declare const calculateTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ expression: z.ZodString;
9
+ operation: z.ZodDefault<z.ZodEnum<{
10
+ evaluate: "evaluate";
11
+ simplify: "simplify";
12
+ derivative: "derivative";
13
+ }>>;
14
+ variable: z.ZodOptional<z.ZodString>;
15
+ scope: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
16
+ precision: z.ZodOptional<z.ZodNumber>;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ result: z.ZodString;
19
+ resultType: z.ZodString;
20
+ expression: z.ZodString;
21
+ }, z.core.$strip>>;
22
+ //# sourceMappingURL=calculate.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculate.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/calculate.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAIjD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;kBA0GxB,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @fileoverview Calculate tool — evaluate, simplify, or differentiate math expressions.
3
+ * Single tool covering 100% of the server's purpose.
4
+ * @module mcp-server/tools/definitions/calculate.tool
5
+ */
6
+ import { tool, z } from '@cyanheads/mcp-ts-core';
7
+ import { invalidParams } from '@cyanheads/mcp-ts-core/errors';
8
+ import { getMathService } from '../../../services/math/math-service.js';
9
+ export const calculateTool = tool('calculate', {
10
+ description: 'Evaluate math expressions, simplify algebraic expressions, or compute symbolic derivatives. ' +
11
+ 'Supports arithmetic, trigonometry, statistics, matrices, complex numbers, units, and combinatorics. ' +
12
+ 'Powered by math.js — use calculator://help for the full function reference.',
13
+ annotations: {
14
+ readOnlyHint: true,
15
+ idempotentHint: true,
16
+ openWorldHint: false,
17
+ },
18
+ input: z.object({
19
+ expression: z
20
+ .string()
21
+ .min(1)
22
+ .describe('Mathematical expression to evaluate. Supports standard notation: ' +
23
+ 'arithmetic (+, -, *, /, ^, %), functions (sin, cos, sqrt, log, abs, round, etc.), ' +
24
+ 'constants (pi, e, phi, i), matrices ([1, 2; 3, 4]), units (5 kg to lbs), ' +
25
+ 'and variables (when scope is provided).'),
26
+ operation: z
27
+ .enum(['evaluate', 'simplify', 'derivative'])
28
+ .default('evaluate')
29
+ .describe('Operation to perform. ' +
30
+ '"evaluate" computes a numeric result (default). ' +
31
+ '"simplify" reduces an algebraic expression symbolically (e.g., "2x + 3x" -> "5 * x"). Supports algebraic and trigonometric identities. ' +
32
+ '"derivative" computes the symbolic derivative (requires variable parameter).'),
33
+ variable: z
34
+ .string()
35
+ .max(50)
36
+ .regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, 'Variable name must be alphanumeric (a-z, A-Z, 0-9, _).')
37
+ .optional()
38
+ .describe('Variable to differentiate with respect to. Required when operation is "derivative". Example: "x".'),
39
+ scope: z
40
+ .record(z.string(), z.number())
41
+ .optional()
42
+ .describe('Variable assignments for the expression. Example: { "x": 5, "y": 3 } makes "x + y" evaluate to 8.'),
43
+ precision: z
44
+ .number()
45
+ .int()
46
+ .min(1)
47
+ .max(16)
48
+ .optional()
49
+ .describe('Significant digits (1\u201316) for numeric results. Omit for full precision. Ignored for symbolic operations (simplify, derivative).'),
50
+ }),
51
+ output: z.object({
52
+ result: z.string().describe('The computed result as a string.'),
53
+ resultType: z
54
+ .string()
55
+ .describe('Type of result as reported by math.js: number, BigNumber, Complex, DenseMatrix, Unit, string, boolean. Symbolic operations return "string".'),
56
+ expression: z.string().describe('The original expression as received.'),
57
+ }),
58
+ handler(input, ctx) {
59
+ const math = getMathService();
60
+ switch (input.operation) {
61
+ case 'evaluate': {
62
+ const { result, resultType } = math.evaluateExpression(input.expression, input.scope, input.precision);
63
+ ctx.log.info('Evaluated expression', { expression: input.expression });
64
+ return { result, resultType, expression: input.expression };
65
+ }
66
+ case 'simplify': {
67
+ const { result, resultType } = math.simplifyExpression(input.expression);
68
+ ctx.log.info('Simplified expression', { expression: input.expression });
69
+ return { result, resultType, expression: input.expression };
70
+ }
71
+ case 'derivative': {
72
+ if (!input.variable) {
73
+ throw invalidParams("The 'variable' parameter is required when operation is 'derivative'.");
74
+ }
75
+ const { result, resultType } = math.differentiateExpression(input.expression, input.variable);
76
+ ctx.log.info('Differentiated expression', {
77
+ expression: input.expression,
78
+ variable: input.variable,
79
+ });
80
+ return { result, resultType, expression: input.expression };
81
+ }
82
+ }
83
+ },
84
+ format: (output) => [
85
+ {
86
+ type: 'text',
87
+ text: `**Expression:** \`${output.expression}\`\n**Result:** ${output.result}\n**Type:** ${output.resultType}`,
88
+ },
89
+ ],
90
+ });
91
+ //# sourceMappingURL=calculate.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculate.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/calculate.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview Hardened math.js wrapper for secure expression evaluation.
3
+ * Creates a restricted math.js instance with dangerous functions disabled in
4
+ * the expression scope, and wraps evaluation in a vm sandbox with timeout.
5
+ * @module services/math/math-service
6
+ */
7
+ import type { ServerConfig } from '../../config/server-config.js';
8
+ import type { MathResult } from './types.js';
9
+ export declare class MathService {
10
+ private readonly evaluate;
11
+ private readonly simplify;
12
+ private readonly derivative;
13
+ private readonly simplifyRules;
14
+ private readonly format;
15
+ private readonly typeOf;
16
+ private readonly config;
17
+ constructor(config: ServerConfig);
18
+ /** Evaluate a math expression with optional variable scope and precision. */
19
+ evaluateExpression(expression: string, scope?: Record<string, number>, precision?: number): MathResult;
20
+ /** Simplify an algebraic expression symbolically. */
21
+ simplifyExpression(expression: string): MathResult;
22
+ /** Compute the symbolic derivative of an expression with respect to a variable. */
23
+ differentiateExpression(expression: string, variable: string): MathResult;
24
+ /** Get formatted help content listing available functions, operators, and syntax. */
25
+ getHelpContent(): string;
26
+ private validateInput;
27
+ /** Reject scope keys that could pollute the object prototype chain. */
28
+ private sanitizeScope;
29
+ /** Reject result types that leak internals (functions, parsers, multi-expression ResultSets). */
30
+ private validateResultType;
31
+ /** Reject results that exceed the configured maximum size. */
32
+ private validateResultSize;
33
+ /** Runs a synchronous function inside a vm sandbox with timeout protection. */
34
+ private runWithTimeout;
35
+ }
36
+ /** Initialize the math service. Call once from createApp setup(). */
37
+ export declare function initMathService(config: ServerConfig): void;
38
+ /** Get the initialized math service instance. */
39
+ export declare function getMathService(): MathService;
40
+ //# sourceMappingURL=math-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math-service.d.ts","sourceRoot":"","sources":["../../../src/services/math/math-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAsG7C,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4D;IACrF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;IAC5F,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6D;IACxF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+D;IACtF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,YAAY;IA2BhC,6EAA6E;IAC7E,kBAAkB,CAChB,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,GACjB,UAAU;IAkBb,qDAAqD;IACrD,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;IAQlD,mFAAmF;IACnF,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAQzE,qFAAqF;IACrF,cAAc,IAAI,MAAM;IAIxB,OAAO,CAAC,aAAa;IAcrB,uEAAuE;IACvE,OAAO,CAAC,aAAa;IAWrB,iGAAiG;IACjG,OAAO,CAAC,kBAAkB;IAQ1B,8DAA8D;IAC9D,OAAO,CAAC,kBAAkB;IAQ1B,+EAA+E;IAC/E,OAAO,CAAC,cAAc;CAiBvB;AAMD,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE1D;AAED,iDAAiD;AACjD,wBAAgB,cAAc,IAAI,WAAW,CAG5C"}