@interstellar-tools/mcp 0.0.0-stage → 0.1.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/README.md +108 -2
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +37 -0
- package/dist/bin.js.map +1 -0
- package/dist/bodies.d.ts +38 -0
- package/dist/bodies.d.ts.map +1 -0
- package/dist/bodies.js +87 -0
- package/dist/bodies.js.map +1 -0
- package/dist/http.d.ts +23 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +51 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +32 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/anomalies.d.ts +3 -0
- package/dist/tools/anomalies.d.ts.map +1 -0
- package/dist/tools/anomalies.js +51 -0
- package/dist/tools/anomalies.js.map +1 -0
- package/dist/tools/manoeuvres.d.ts +3 -0
- package/dist/tools/manoeuvres.d.ts.map +1 -0
- package/dist/tools/manoeuvres.js +73 -0
- package/dist/tools/manoeuvres.js.map +1 -0
- package/dist/tools/orbits.d.ts +3 -0
- package/dist/tools/orbits.d.ts.map +1 -0
- package/dist/tools/orbits.js +100 -0
- package/dist/tools/orbits.js.map +1 -0
- package/dist/tools/shared.d.ts +39 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +40 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/time.d.ts +3 -0
- package/dist/tools/time.d.ts.map +1 -0
- package/dist/tools/time.js +24 -0
- package/dist/tools/time.js.map +1 -0
- package/package.json +74 -4
package/README.md
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @interstellar-tools/mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that
|
|
4
|
+
gives AI assistants deterministic, unit-explicit orbital mechanics calculations
|
|
5
|
+
and celestial body datasets, backed by `@interstellar-tools/equations`,
|
|
6
|
+
`@interstellar-tools/constants` and `@interstellar-tools/temporal`.
|
|
7
|
+
|
|
8
|
+
## Documentation
|
|
9
|
+
|
|
10
|
+
The full documentation lives at
|
|
11
|
+
**[phun-ky.net/interstellar-tools](https://phun-ky.net/interstellar-tools/)**:
|
|
12
|
+
|
|
13
|
+
- [Using the MCP server](https://phun-ky.net/interstellar-tools/guide/mcp/):
|
|
14
|
+
step-by-step setup for Claude, ChatGPT, Mistral Le Chat, Gemini, GitHub
|
|
15
|
+
Copilot, Cursor, JetBrains and more
|
|
16
|
+
- [API reference for `@interstellar-tools/mcp`](https://phun-ky.net/interstellar-tools/api/@interstellar-tools/mcp/)
|
|
17
|
+
- [API reference for the equations](https://phun-ky.net/interstellar-tools/api/@interstellar-tools/equations/)
|
|
18
|
+
that every tool wraps
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
- [Node.js](https://nodejs.org/) version 22.9.0 or higher
|
|
23
|
+
|
|
24
|
+
Add it to any MCP client that launches stdio servers, for example:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"interstellar-tools": {
|
|
30
|
+
"command": "npx",
|
|
31
|
+
"args": ["-y", "@interstellar-tools/mcp"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or with Claude Code:
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
claude mcp add interstellar-tools -- npx -y @interstellar-tools/mcp
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Remote (HTTP)
|
|
44
|
+
|
|
45
|
+
Web assistants such as claude.ai, ChatGPT and Mistral Le Chat connect to remote
|
|
46
|
+
servers only. Serve Streamable HTTP and put it behind HTTPS (a tunnel such as
|
|
47
|
+
`cloudflared tunnel --url http://localhost:3000` is enough for testing):
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
npx -y @interstellar-tools/mcp --http --port 3000
|
|
51
|
+
# → http://127.0.0.1:3000/mcp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The server is stateless and binds to `127.0.0.1` unless you pass
|
|
55
|
+
`--host 0.0.0.0`. Step-by-step setup for each assistant is in the
|
|
56
|
+
[MCP guide](https://phun-ky.net/interstellar-tools/guide/mcp/).
|
|
57
|
+
|
|
58
|
+
## Units
|
|
59
|
+
|
|
60
|
+
Every input and output field name ends with its unit: `r_m` (metres), `m0_kg`
|
|
61
|
+
(kilograms), `v_m_s` (m/s), `mu_m3_s2` (m³/s²), `T_s` / `T_d` (seconds / days).
|
|
62
|
+
Angles are passed as `{ "value": 28.5, "unit": "deg" }` (or `"rad"`) and
|
|
63
|
+
returned as `{ "rad": …, "deg": … }`.
|
|
64
|
+
|
|
65
|
+
## Tools
|
|
66
|
+
|
|
67
|
+
| Tool | What it computes |
|
|
68
|
+
| ---------------------------- | ---------------------------------------------------- |
|
|
69
|
+
| `gravitational_parameter` | μ = G·(M + m) from masses |
|
|
70
|
+
| `circular_speed` | Circular orbit speed at radius r |
|
|
71
|
+
| `escape_speed` | Escape speed at radius r |
|
|
72
|
+
| `vis_viva_speed` | Speed at radius r on an orbit with semi-major axis a |
|
|
73
|
+
| `kepler_period` | Orbital period from semi-major axis |
|
|
74
|
+
| `peri_apoapsis_radii` | Periapsis and apoapsis radii from a and e |
|
|
75
|
+
| `sphere_of_influence_radius` | Laplace sphere of influence |
|
|
76
|
+
| `hohmann_transfer` | Both burns, total Δv and transfer time |
|
|
77
|
+
| `rocket_delta_v` | Tsiolkovsky rocket equation from Isp and masses |
|
|
78
|
+
| `plane_change_delta_v` | Δv for a pure inclination change |
|
|
79
|
+
| `solve_kepler` | Eccentric anomaly from mean anomaly and eccentricity |
|
|
80
|
+
| `convert_anomaly` | Mean ↔ eccentric ↔ true anomaly (elliptic orbits) |
|
|
81
|
+
| `convert_time` | Duration between units, attoseconds to gigayears |
|
|
82
|
+
| `find_body` | Look up planets, moons, stars, comets, … by name |
|
|
83
|
+
|
|
84
|
+
All tools are pure and offline: no network access, no side effects.
|
|
85
|
+
|
|
86
|
+
## Resources
|
|
87
|
+
|
|
88
|
+
Each dataset in `@interstellar-tools/constants` is available as a JSON resource
|
|
89
|
+
at `interstellar://datasets/{name}`, where `name` is one of `planets`, `moons`,
|
|
90
|
+
`stars`, `comets`, `asteroids`, `asteroid-belts`, `galaxies` or `systems`.
|
|
91
|
+
|
|
92
|
+
> [!NOTE]
|
|
93
|
+
>
|
|
94
|
+
> The Alpha Centauri entries are left out of `stars` until their orbital model
|
|
95
|
+
> is corrected.
|
|
96
|
+
|
|
97
|
+
## Programmatic use
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
101
|
+
|
|
102
|
+
import { createServer, startHttpServer } from '@interstellar-tools/mcp';
|
|
103
|
+
|
|
104
|
+
// stdio
|
|
105
|
+
await createServer().connect(new StdioServerTransport());
|
|
106
|
+
|
|
107
|
+
// or Streamable HTTP on http://127.0.0.1:3000/mcp
|
|
108
|
+
await startHttpServer({ port: 3000 });
|
|
109
|
+
```
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { parseArgs } from 'node:util';
|
|
5
|
+
import { startHttpServer } from './http.js';
|
|
6
|
+
import { createServer } from './server.js';
|
|
7
|
+
const { values } = parseArgs({
|
|
8
|
+
options: {
|
|
9
|
+
http: { type: 'boolean', default: false },
|
|
10
|
+
port: { type: 'string', default: process.env.PORT ?? '3000' },
|
|
11
|
+
host: { type: 'string', default: '127.0.0.1' },
|
|
12
|
+
help: { type: 'boolean', short: 'h', default: false }
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
if (values.help) {
|
|
16
|
+
process.stdout
|
|
17
|
+
.write(`Usage: interstellar-tools-mcp [--http] [--port <n>] [--host <addr>]
|
|
18
|
+
|
|
19
|
+
(default) Serve over stdio, for clients that launch the server themselves
|
|
20
|
+
--http Serve Streamable HTTP at http://<host>:<port>/mcp
|
|
21
|
+
--port <n> HTTP port (default: $PORT or 3000)
|
|
22
|
+
--host <addr> HTTP bind address (default: 127.0.0.1)
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
else if (values.http) {
|
|
26
|
+
const http = await startHttpServer({
|
|
27
|
+
port: Number(values.port),
|
|
28
|
+
host: values.host
|
|
29
|
+
});
|
|
30
|
+
const { address, port } = http.address();
|
|
31
|
+
// stdout stays clean for stdio clients; logs go to stderr
|
|
32
|
+
process.stderr.write(`interstellar-tools MCP server listening on http://${address}:${port}/mcp\n`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
await createServer().connect(new StdioServerTransport());
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAGjF,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE;QACP,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;QACzC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE;QAC7D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE;QAC9C,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;KACtD;CACF,CAAC,CAAC;AAEH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IAChB,OAAO,CAAC,MAAM;SACX,KAAK,CAAC;;;;;;CAMV,CAAC,CAAC;AACH,CAAC;KAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC;QACjC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAC,CAAC;IACH,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,EAAiB,CAAC;IAExD,0DAA0D;IAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qDAAqD,OAAO,IAAI,IAAI,QAAQ,CAC7E,CAAC;AACJ,CAAC;KAAM,CAAC;IACN,MAAM,YAAY,EAAE,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/bodies.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
export declare const DATASETS: {
|
|
3
|
+
readonly planets: {
|
|
4
|
+
readonly description: "Planets and dwarf planets of the Solar System.";
|
|
5
|
+
readonly data: import("@interstellar-tools/types").PlanetsType;
|
|
6
|
+
};
|
|
7
|
+
readonly moons: {
|
|
8
|
+
readonly description: "Natural satellites.";
|
|
9
|
+
readonly data: import("@interstellar-tools/types").MoonsType;
|
|
10
|
+
};
|
|
11
|
+
readonly stars: {
|
|
12
|
+
readonly description: "Stars (Alpha Centauri entries omitted pending a fix).";
|
|
13
|
+
readonly data: import("@interstellar-tools/types").StarInterface[];
|
|
14
|
+
};
|
|
15
|
+
readonly comets: {
|
|
16
|
+
readonly description: "Comets.";
|
|
17
|
+
readonly data: import("@interstellar-tools/types").CometsType;
|
|
18
|
+
};
|
|
19
|
+
readonly asteroids: {
|
|
20
|
+
readonly description: "Asteroids.";
|
|
21
|
+
readonly data: import("@interstellar-tools/types").AsteroidsType;
|
|
22
|
+
};
|
|
23
|
+
readonly 'asteroid-belts': {
|
|
24
|
+
readonly description: "Asteroid belts.";
|
|
25
|
+
readonly data: import("@interstellar-tools/types").AsteroidBeltsType;
|
|
26
|
+
};
|
|
27
|
+
readonly galaxies: {
|
|
28
|
+
readonly description: "Galaxies.";
|
|
29
|
+
readonly data: import("@interstellar-tools/types").GalaxiesType;
|
|
30
|
+
};
|
|
31
|
+
readonly systems: {
|
|
32
|
+
readonly description: "Planetary and stellar systems.";
|
|
33
|
+
readonly data: import("@interstellar-tools/types").SystemsType;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export type DatasetNameType = keyof typeof DATASETS;
|
|
37
|
+
export declare const registerBodies: (server: McpServer) => void;
|
|
38
|
+
//# sourceMappingURL=bodies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bodies.d.ts","sourceRoot":"","sources":["../src/bodies.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,SAAS,EAEV,MAAM,yCAAyC,CAAC;AAkBjD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAeX,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,QAAQ,CAAC;AAUpD,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS,SAmE/C,CAAC"}
|
package/dist/bodies.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ASTEROID_BELTS, ASTEROIDS, COMETS, GALAXIES, MOONS, PLANETS, STARS, SYSTEMS } from '@interstellar-tools/constants';
|
|
2
|
+
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { PURE_TOOL, result } from './tools/shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* The Alpha Centauri entries in `STARS` currently carry the Sun's galactic
|
|
7
|
+
* orbit instead of the binary + Proxima system, so they are held back until
|
|
8
|
+
* that model lands.
|
|
9
|
+
*/
|
|
10
|
+
const isTrusted = (body) => !(typeof body.system === 'object' &&
|
|
11
|
+
body.system !== null &&
|
|
12
|
+
'name' in body.system &&
|
|
13
|
+
body.system.name === 'Alpha Centauri');
|
|
14
|
+
export const DATASETS = {
|
|
15
|
+
planets: {
|
|
16
|
+
description: 'Planets and dwarf planets of the Solar System.',
|
|
17
|
+
data: PLANETS
|
|
18
|
+
},
|
|
19
|
+
moons: { description: 'Natural satellites.', data: MOONS },
|
|
20
|
+
stars: {
|
|
21
|
+
description: 'Stars (Alpha Centauri entries omitted pending a fix).',
|
|
22
|
+
data: STARS.filter(isTrusted)
|
|
23
|
+
},
|
|
24
|
+
comets: { description: 'Comets.', data: COMETS },
|
|
25
|
+
asteroids: { description: 'Asteroids.', data: ASTEROIDS },
|
|
26
|
+
'asteroid-belts': { description: 'Asteroid belts.', data: ASTEROID_BELTS },
|
|
27
|
+
galaxies: { description: 'Galaxies.', data: GALAXIES },
|
|
28
|
+
systems: { description: 'Planetary and stellar systems.', data: SYSTEMS }
|
|
29
|
+
};
|
|
30
|
+
const DATASET_NAMES = Object.keys(DATASETS);
|
|
31
|
+
const uriFor = (name) => `interstellar://datasets/${name}`;
|
|
32
|
+
const UNITS_NOTE = 'Values carry their own units ({ value, unit }); `a` is usually in au, `period` in days (negative = integration direction), `radius` in km, `angle` in radians at J2000.';
|
|
33
|
+
export const registerBodies = (server) => {
|
|
34
|
+
server.registerResource('dataset', new ResourceTemplate('interstellar://datasets/{name}', {
|
|
35
|
+
list: () => ({
|
|
36
|
+
resources: DATASET_NAMES.map((name) => ({
|
|
37
|
+
name,
|
|
38
|
+
uri: uriFor(name),
|
|
39
|
+
description: DATASETS[name].description,
|
|
40
|
+
mimeType: 'application/json'
|
|
41
|
+
}))
|
|
42
|
+
}),
|
|
43
|
+
complete: {
|
|
44
|
+
name: (value) => DATASET_NAMES.filter((name) => name.startsWith(value))
|
|
45
|
+
}
|
|
46
|
+
}), {
|
|
47
|
+
title: 'Celestial body dataset',
|
|
48
|
+
description: `Celestial body datasets from @interstellar-tools/constants. ${UNITS_NOTE}`,
|
|
49
|
+
mimeType: 'application/json'
|
|
50
|
+
}, (uri, { name }) => {
|
|
51
|
+
const dataset = DATASETS[String(name)];
|
|
52
|
+
if (!dataset)
|
|
53
|
+
throw new Error(`Unknown dataset: ${String(name)}`);
|
|
54
|
+
return {
|
|
55
|
+
contents: [
|
|
56
|
+
{
|
|
57
|
+
uri: uri.href,
|
|
58
|
+
mimeType: 'application/json',
|
|
59
|
+
text: JSON.stringify(dataset.data, null, 2)
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
server.registerTool('find_body', {
|
|
65
|
+
title: 'Find celestial body',
|
|
66
|
+
description: `Look up celestial bodies by name (case-insensitive substring) across the bundled datasets. ${UNITS_NOTE} Bodies do not carry masses; use known μ values with the orbit tools.`,
|
|
67
|
+
inputSchema: {
|
|
68
|
+
query: z
|
|
69
|
+
.string()
|
|
70
|
+
.min(1)
|
|
71
|
+
.describe('Name or part of a name, e.g. "mars".'),
|
|
72
|
+
dataset: z
|
|
73
|
+
.enum(DATASET_NAMES)
|
|
74
|
+
.optional()
|
|
75
|
+
.describe('Restrict the search to one dataset.')
|
|
76
|
+
},
|
|
77
|
+
annotations: PURE_TOOL
|
|
78
|
+
}, ({ query, dataset }) => {
|
|
79
|
+
const needle = query.trim().toLowerCase();
|
|
80
|
+
const names = dataset ? [dataset] : DATASET_NAMES;
|
|
81
|
+
const matches = names.flatMap((name) => DATASETS[name].data
|
|
82
|
+
.filter((body) => body.name.toLowerCase().includes(needle))
|
|
83
|
+
.map((body) => ({ dataset: name, body })));
|
|
84
|
+
return result({ count: matches.length, matches });
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=bodies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bodies.js","sourceRoot":"","sources":["../src/bodies.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,SAAS,EACT,MAAM,EACN,QAAQ,EACR,KAAK,EACL,OAAO,EACP,KAAK,EACL,OAAO,EACR,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,SAAS,GAAG,CAAC,IAA0B,EAAE,EAAE,CAC/C,CAAC,CACC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;IAC/B,IAAI,CAAC,MAAM,KAAK,IAAI;IACpB,MAAM,IAAI,IAAI,CAAC,MAAM;IACrB,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,CACtC,CAAC;AAEJ,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE;QACP,WAAW,EAAE,gDAAgD;QAC7D,IAAI,EAAE,OAAO;KACd;IACD,KAAK,EAAE,EAAE,WAAW,EAAE,qBAAqB,EAAE,IAAI,EAAE,KAAK,EAAE;IAC1D,KAAK,EAAE;QACL,WAAW,EAAE,uDAAuD;QACpE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;KAC9B;IACD,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;IAChD,SAAS,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE;IACzD,gBAAgB,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,EAAE;IAC1E,QAAQ,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;IACtD,OAAO,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE,IAAI,EAAE,OAAO,EAAE;CACjE,CAAC;AAIX,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAGzC,CAAC;AACF,MAAM,MAAM,GAAG,CAAC,IAAqB,EAAE,EAAE,CAAC,2BAA2B,IAAI,EAAE,CAAC;AAC5E,MAAM,UAAU,GACd,yKAAyK,CAAC;AAE5K,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAiB,EAAE,EAAE;IAClD,MAAM,CAAC,gBAAgB,CACrB,SAAS,EACT,IAAI,gBAAgB,CAAC,gCAAgC,EAAE;QACrD,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACX,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtC,IAAI;gBACJ,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC;gBACjB,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW;gBACvC,QAAQ,EAAE,kBAAkB;aAC7B,CAAC,CAAC;SACJ,CAAC;QACF,QAAQ,EAAE;YACR,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SACxE;KACF,CAAC,EACF;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,+DAA+D,UAAU,EAAE;QACxF,QAAQ,EAAE,kBAAkB;KAC7B,EACD,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAChB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAoB,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAElE,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC5C;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,8FAA8F,UAAU,uEAAuE;QAC5L,WAAW,EAAE;YACX,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,sCAAsC,CAAC;YACnD,OAAO,EAAE,CAAC;iBACP,IAAI,CAAC,aAAa,CAAC;iBACnB,QAAQ,EAAE;iBACV,QAAQ,CAAC,qCAAqC,CAAC;SACnD;QACD,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACpC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAoC;aACjD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aAC1D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAC5C,CAAC;QAEF,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Server } from 'node:http';
|
|
2
|
+
export interface HttpServerOptionsInterface {
|
|
3
|
+
/** Port to listen on. Use 0 for a random free port. */
|
|
4
|
+
port: number;
|
|
5
|
+
/** Interface to bind to. Defaults to loopback only. */
|
|
6
|
+
host?: string;
|
|
7
|
+
/** Path that serves MCP requests. */
|
|
8
|
+
path?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Serve the MCP server over Streamable HTTP, for clients that only accept
|
|
12
|
+
* remote servers. Runs stateless: every request gets a fresh server, which is
|
|
13
|
+
* cheap because every tool is a pure calculation.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { startHttpServer } from '@interstellar-tools/mcp';
|
|
18
|
+
*
|
|
19
|
+
* await startHttpServer({ port: 3000 }); // http://127.0.0.1:3000/mcp
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const startHttpServer: ({ port, host, path }: HttpServerOptionsInterface) => Promise<Server>;
|
|
23
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAI1E,MAAM,WAAW,0BAA0B;IACzC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAAI,sBAI7B,0BAA0B,KAAG,OAAO,CAAC,MAAM,CAyC7C,CAAC"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
2
|
+
import { createServer as createHttpServer } from 'node:http';
|
|
3
|
+
import { createServer } from './server.js';
|
|
4
|
+
/**
|
|
5
|
+
* Serve the MCP server over Streamable HTTP, for clients that only accept
|
|
6
|
+
* remote servers. Runs stateless: every request gets a fresh server, which is
|
|
7
|
+
* cheap because every tool is a pure calculation.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { startHttpServer } from '@interstellar-tools/mcp';
|
|
12
|
+
*
|
|
13
|
+
* await startHttpServer({ port: 3000 }); // http://127.0.0.1:3000/mcp
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export const startHttpServer = ({ port, host = '127.0.0.1', path = '/mcp' }) => {
|
|
17
|
+
const http = createHttpServer(async (req, res) => {
|
|
18
|
+
const { pathname } = new URL(req.url ?? '/', 'http://localhost');
|
|
19
|
+
if (pathname !== path) {
|
|
20
|
+
res.writeHead(404, { 'content-type': 'text/plain' }).end('Not found');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const server = createServer();
|
|
24
|
+
const transport = new StreamableHTTPServerTransport({
|
|
25
|
+
sessionIdGenerator: undefined,
|
|
26
|
+
enableJsonResponse: true
|
|
27
|
+
});
|
|
28
|
+
res.on('close', () => {
|
|
29
|
+
void transport.close();
|
|
30
|
+
void server.close();
|
|
31
|
+
});
|
|
32
|
+
try {
|
|
33
|
+
await server.connect(transport);
|
|
34
|
+
await transport.handleRequest(req, res);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (!res.headersSent) {
|
|
38
|
+
res.writeHead(500, { 'content-type': 'application/json' }).end(JSON.stringify({
|
|
39
|
+
jsonrpc: '2.0',
|
|
40
|
+
error: { code: -32603, message: String(error) },
|
|
41
|
+
id: null
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
http.once('error', reject);
|
|
48
|
+
http.listen(port, host, () => resolve(http));
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAe,MAAM,WAAW,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAW3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,IAAI,EACJ,IAAI,GAAG,WAAW,EAClB,IAAI,GAAG,MAAM,EACc,EAAmB,EAAE;IAChD,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAEjE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAEtE,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;YAClD,kBAAkB,EAAE,SAAS;YAC7B,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAChC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAC5D,IAAI,CAAC,SAAS,CAAC;oBACb,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;oBAC/C,EAAE,EAAE,IAAI;iBACT,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,WAAW,CAAC;AAE1B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,WAAW,CAAC;AAE1B,cAAc,aAAa,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
export declare const SERVER_NAME = "interstellar-tools";
|
|
3
|
+
export declare const SERVER_VERSION = "0.0.0";
|
|
4
|
+
/**
|
|
5
|
+
* Create an MCP server with every interstellar-tools tool and resource
|
|
6
|
+
* registered. Connect it to a transport of your choice.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
|
+
* import { createServer } from '@interstellar-tools/mcp';
|
|
12
|
+
*
|
|
13
|
+
* await createServer().connect(new StdioServerTransport());
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare const createServer: () => McpServer;
|
|
17
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAEhD,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,QAAO,SAgB/B,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { registerBodies } from './bodies.js';
|
|
3
|
+
import { registerAnomalyTools } from './tools/anomalies.js';
|
|
4
|
+
import { registerManoeuvreTools } from './tools/manoeuvres.js';
|
|
5
|
+
import { registerOrbitTools } from './tools/orbits.js';
|
|
6
|
+
import { registerTimeTools } from './tools/time.js';
|
|
7
|
+
export const SERVER_NAME = 'interstellar-tools';
|
|
8
|
+
export const SERVER_VERSION = '0.0.0';
|
|
9
|
+
/**
|
|
10
|
+
* Create an MCP server with every interstellar-tools tool and resource
|
|
11
|
+
* registered. Connect it to a transport of your choice.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
16
|
+
* import { createServer } from '@interstellar-tools/mcp';
|
|
17
|
+
*
|
|
18
|
+
* await createServer().connect(new StdioServerTransport());
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const createServer = () => {
|
|
22
|
+
const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, {
|
|
23
|
+
instructions: 'Deterministic orbital mechanics calculations. All lengths are in metres, masses in kg, speeds in m/s and μ in m³/s² unless a field name says otherwise. Angles are given as { value, unit: "deg" | "rad" }. Prefer these tools over mental arithmetic.'
|
|
24
|
+
});
|
|
25
|
+
registerOrbitTools(server);
|
|
26
|
+
registerManoeuvreTools(server);
|
|
27
|
+
registerAnomalyTools(server);
|
|
28
|
+
registerTimeTools(server);
|
|
29
|
+
registerBodies(server);
|
|
30
|
+
return server;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEhD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAc,EAAE;IAC1C,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAC9C;QACE,YAAY,EACV,wPAAwP;KAC3P,CACF,CAAC;IAEF,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anomalies.d.ts","sourceRoot":"","sources":["../../src/tools/anomalies.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsCzE,eAAO,MAAM,oBAAoB,GAAI,QAAQ,SAAS,SAsCrD,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { eccentricToTrueAnomaly, norm2pi, solveKepler, trueToMeanAnomaly } from '@interstellar-tools/equations';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { angleOutput, angleOutputSchema, angleSchema, PURE_TOOL, result, toRadians } from './shared.js';
|
|
4
|
+
const ANOMALIES = ['mean', 'eccentric', 'true'];
|
|
5
|
+
const eccentricitySchema = z
|
|
6
|
+
.number()
|
|
7
|
+
.min(0)
|
|
8
|
+
.lt(1)
|
|
9
|
+
.describe('Eccentricity of an elliptic orbit, 0 ≤ e < 1.');
|
|
10
|
+
// Every conversion goes through the library: mean → eccentric via Kepler’s
|
|
11
|
+
// equation, eccentric → true directly, and true → mean directly.
|
|
12
|
+
const toMean = (kind, x, e) => {
|
|
13
|
+
if (kind === 'mean')
|
|
14
|
+
return x;
|
|
15
|
+
const nu = kind === 'true' ? x : eccentricToTrueAnomaly(x, e);
|
|
16
|
+
return trueToMeanAnomaly(nu, e);
|
|
17
|
+
};
|
|
18
|
+
const fromMean = (kind, M, e) => {
|
|
19
|
+
if (kind === 'mean')
|
|
20
|
+
return M;
|
|
21
|
+
const E = solveKepler(M, e);
|
|
22
|
+
return kind === 'eccentric' ? E : eccentricToTrueAnomaly(E, e);
|
|
23
|
+
};
|
|
24
|
+
export const registerAnomalyTools = (server) => {
|
|
25
|
+
server.registerTool('solve_kepler', {
|
|
26
|
+
title: 'Solve Kepler’s equation',
|
|
27
|
+
description: 'Solve Kepler’s equation M = E − e·sin(E) for the eccentric anomaly E, given mean anomaly M and eccentricity e (elliptic orbits). Robust up to e → 1.',
|
|
28
|
+
inputSchema: { M: angleSchema, e: eccentricitySchema },
|
|
29
|
+
outputSchema: { E: angleOutputSchema },
|
|
30
|
+
annotations: PURE_TOOL
|
|
31
|
+
}, ({ M, e }) => result({ E: angleOutput(solveKepler(toRadians(M), e)) }));
|
|
32
|
+
server.registerTool('convert_anomaly', {
|
|
33
|
+
title: 'Convert orbital anomaly',
|
|
34
|
+
description: 'Convert between mean, eccentric and true anomaly for an elliptic orbit. Results are normalised to [0, 2π).',
|
|
35
|
+
inputSchema: {
|
|
36
|
+
from: z.enum(ANOMALIES).describe('Kind of the input anomaly.'),
|
|
37
|
+
to: z.enum(ANOMALIES).describe('Kind of anomaly to return.'),
|
|
38
|
+
angle: angleSchema,
|
|
39
|
+
e: eccentricitySchema
|
|
40
|
+
},
|
|
41
|
+
outputSchema: { kind: z.enum(ANOMALIES), angle: angleOutputSchema },
|
|
42
|
+
annotations: PURE_TOOL
|
|
43
|
+
}, ({ from, to, angle, e }) => {
|
|
44
|
+
const M = toMean(from, toRadians(angle), e);
|
|
45
|
+
return result({
|
|
46
|
+
kind: to,
|
|
47
|
+
angle: angleOutput(norm2pi(fromMean(to, M, e)))
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=anomalies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anomalies.js","sourceRoot":"","sources":["../../src/tools/anomalies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manoeuvres.d.ts","sourceRoot":"","sources":["../../src/tools/manoeuvres.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,eAAO,MAAM,sBAAsB,GAAI,QAAQ,SAAS,SA8FvD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SECONDS_PER_DAY } from '@interstellar-tools/constants';
|
|
2
|
+
import { hohmannTransfer, planeChangeDeltaV, rocketDeltaVFromIsp } from '@interstellar-tools/equations';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { angleSchema, muSchema, PURE_TOOL, result, toRadians } from './shared.js';
|
|
5
|
+
const directionSchema = z.enum(['prograde', 'retrograde', 'none']);
|
|
6
|
+
export const registerManoeuvreTools = (server) => {
|
|
7
|
+
server.registerTool('hohmann_transfer', {
|
|
8
|
+
title: 'Hohmann transfer',
|
|
9
|
+
description: 'Two-impulse Hohmann transfer between coplanar circular orbits of radius r1 and r2 around the same body. Returns both burns, total Δv and transfer time.',
|
|
10
|
+
inputSchema: {
|
|
11
|
+
r1_m: z
|
|
12
|
+
.number()
|
|
13
|
+
.positive()
|
|
14
|
+
.describe('Initial circular orbit radius from body centre, in metres.'),
|
|
15
|
+
r2_m: z
|
|
16
|
+
.number()
|
|
17
|
+
.positive()
|
|
18
|
+
.describe('Target circular orbit radius from body centre, in metres.'),
|
|
19
|
+
mu_m3_s2: muSchema
|
|
20
|
+
},
|
|
21
|
+
outputSchema: {
|
|
22
|
+
a_transfer_m: z.number(),
|
|
23
|
+
dv1_m_s: z.number(),
|
|
24
|
+
dv2_m_s: z.number(),
|
|
25
|
+
dv_total_m_s: z.number(),
|
|
26
|
+
t_transfer_s: z.number(),
|
|
27
|
+
t_transfer_d: z.number(),
|
|
28
|
+
burn1_direction: directionSchema,
|
|
29
|
+
burn2_direction: directionSchema
|
|
30
|
+
},
|
|
31
|
+
annotations: PURE_TOOL
|
|
32
|
+
}, ({ r1_m, r2_m, mu_m3_s2 }) => {
|
|
33
|
+
const { at, dv1, dv2, dvTotal, tTransfer, dir1, dir2 } = hohmannTransfer(r1_m, r2_m, mu_m3_s2);
|
|
34
|
+
return result({
|
|
35
|
+
a_transfer_m: at,
|
|
36
|
+
dv1_m_s: dv1,
|
|
37
|
+
dv2_m_s: dv2,
|
|
38
|
+
dv_total_m_s: dvTotal,
|
|
39
|
+
t_transfer_s: tTransfer,
|
|
40
|
+
t_transfer_d: tTransfer / SECONDS_PER_DAY,
|
|
41
|
+
burn1_direction: dir1,
|
|
42
|
+
burn2_direction: dir2
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
server.registerTool('rocket_delta_v', {
|
|
46
|
+
title: 'Rocket equation Δv',
|
|
47
|
+
description: 'Tsiolkovsky rocket equation from specific impulse: Δv = g0·Isp·ln(m0/mf).',
|
|
48
|
+
inputSchema: {
|
|
49
|
+
isp_s: z.number().positive().describe('Specific impulse, in seconds.'),
|
|
50
|
+
m0_kg: z.number().positive().describe('Initial (wet) mass, in kg.'),
|
|
51
|
+
mf_kg: z
|
|
52
|
+
.number()
|
|
53
|
+
.positive()
|
|
54
|
+
.describe('Final (dry) mass, in kg. Must be less than m0_kg.')
|
|
55
|
+
},
|
|
56
|
+
outputSchema: { dv_m_s: z.number() },
|
|
57
|
+
annotations: PURE_TOOL
|
|
58
|
+
}, ({ isp_s, m0_kg, mf_kg }) => result({ dv_m_s: rocketDeltaVFromIsp(isp_s, m0_kg, mf_kg) }));
|
|
59
|
+
server.registerTool('plane_change_delta_v', {
|
|
60
|
+
title: 'Plane change Δv',
|
|
61
|
+
description: 'Δv for a pure inclination change at constant speed: Δv = 2v·sin(Δi/2). Δi must be within [0°, 180°].',
|
|
62
|
+
inputSchema: {
|
|
63
|
+
v_m_s: z
|
|
64
|
+
.number()
|
|
65
|
+
.nonnegative()
|
|
66
|
+
.describe('Orbital speed at the burn point, in m/s.'),
|
|
67
|
+
delta_i: angleSchema
|
|
68
|
+
},
|
|
69
|
+
outputSchema: { dv_m_s: z.number() },
|
|
70
|
+
annotations: PURE_TOOL
|
|
71
|
+
}, ({ v_m_s, delta_i }) => result({ dv_m_s: planeChangeDeltaV(v_m_s, toRadians(delta_i)) }));
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=manoeuvres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manoeuvres.js","sourceRoot":"","sources":["../../src/tools/manoeuvres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orbits.d.ts","sourceRoot":"","sources":["../../src/tools/orbits.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUzE,eAAO,MAAM,kBAAkB,GAAI,QAAQ,SAAS,SA2InD,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { SECONDS_PER_DAY } from '@interstellar-tools/constants';
|
|
2
|
+
import { circularSpeed, escapeSpeed, gravitationalParameter, keplerPeriod, periApoapsisRadii, sphereOfInfluenceRadius, visVivaSpeed } from '@interstellar-tools/equations';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { muSchema, PURE_TOOL, result } from './shared.js';
|
|
5
|
+
const radiusSchema = z
|
|
6
|
+
.number()
|
|
7
|
+
.positive()
|
|
8
|
+
.describe('Distance from the centre of the central body, in metres (m).');
|
|
9
|
+
export const registerOrbitTools = (server) => {
|
|
10
|
+
server.registerTool('gravitational_parameter', {
|
|
11
|
+
title: 'Gravitational parameter',
|
|
12
|
+
description: 'Compute the standard gravitational parameter μ = G·(M + m) from masses. Use this to get μ for the other orbit tools.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
M_kg: z.number().nonnegative().describe('Primary mass, in kg.'),
|
|
15
|
+
m_kg: z
|
|
16
|
+
.number()
|
|
17
|
+
.nonnegative()
|
|
18
|
+
.default(0)
|
|
19
|
+
.describe('Secondary mass, in kg. Omit for a test particle.')
|
|
20
|
+
},
|
|
21
|
+
outputSchema: { mu_m3_s2: z.number() },
|
|
22
|
+
annotations: PURE_TOOL
|
|
23
|
+
}, ({ M_kg, m_kg }) => result({ mu_m3_s2: gravitationalParameter(M_kg, m_kg) }));
|
|
24
|
+
server.registerTool('circular_speed', {
|
|
25
|
+
title: 'Circular orbit speed',
|
|
26
|
+
description: 'Speed of a circular orbit at radius r: v = √(μ/r).',
|
|
27
|
+
inputSchema: { r_m: radiusSchema, mu_m3_s2: muSchema },
|
|
28
|
+
outputSchema: { v_m_s: z.number() },
|
|
29
|
+
annotations: PURE_TOOL
|
|
30
|
+
}, ({ r_m, mu_m3_s2 }) => result({ v_m_s: circularSpeed(r_m, mu_m3_s2) }));
|
|
31
|
+
server.registerTool('escape_speed', {
|
|
32
|
+
title: 'Escape speed',
|
|
33
|
+
description: 'Escape speed at radius r: v = √(2μ/r).',
|
|
34
|
+
inputSchema: { r_m: radiusSchema, mu_m3_s2: muSchema },
|
|
35
|
+
outputSchema: { v_m_s: z.number() },
|
|
36
|
+
annotations: PURE_TOOL
|
|
37
|
+
}, ({ r_m, mu_m3_s2 }) => result({ v_m_s: escapeSpeed(r_m, mu_m3_s2) }));
|
|
38
|
+
server.registerTool('vis_viva_speed', {
|
|
39
|
+
title: 'Vis-viva speed',
|
|
40
|
+
description: 'Orbital speed at radius r on an orbit with semi-major axis a: v = √(μ(2/r − 1/a)). Use a > 0 for elliptic orbits and a < 0 for hyperbolic orbits.',
|
|
41
|
+
inputSchema: {
|
|
42
|
+
r_m: radiusSchema,
|
|
43
|
+
a_m: z
|
|
44
|
+
.number()
|
|
45
|
+
.finite()
|
|
46
|
+
.refine((a) => a !== 0, 'a must be non-zero')
|
|
47
|
+
.describe('Semi-major axis, in metres. Positive for elliptic, negative for hyperbolic.'),
|
|
48
|
+
mu_m3_s2: muSchema
|
|
49
|
+
},
|
|
50
|
+
outputSchema: { v_m_s: z.number() },
|
|
51
|
+
annotations: PURE_TOOL
|
|
52
|
+
}, ({ r_m, a_m, mu_m3_s2 }) => result({ v_m_s: visVivaSpeed(r_m, a_m, mu_m3_s2) }));
|
|
53
|
+
server.registerTool('kepler_period', {
|
|
54
|
+
title: 'Orbital period',
|
|
55
|
+
description: 'Orbital period of an elliptic orbit from Kepler’s third law: T = 2π√(a³/μ).',
|
|
56
|
+
inputSchema: {
|
|
57
|
+
a_m: z.number().positive().describe('Semi-major axis, in metres.'),
|
|
58
|
+
mu_m3_s2: muSchema
|
|
59
|
+
},
|
|
60
|
+
outputSchema: { T_s: z.number(), T_d: z.number() },
|
|
61
|
+
annotations: PURE_TOOL
|
|
62
|
+
}, ({ a_m, mu_m3_s2 }) => {
|
|
63
|
+
const T_s = keplerPeriod(a_m, mu_m3_s2);
|
|
64
|
+
return result({ T_s, T_d: T_s / SECONDS_PER_DAY });
|
|
65
|
+
});
|
|
66
|
+
server.registerTool('peri_apoapsis_radii', {
|
|
67
|
+
title: 'Periapsis and apoapsis radii',
|
|
68
|
+
description: 'Periapsis rp = a(1 − e) and apoapsis ra = a(1 + e). For hyperbolic orbits (a < 0, e > 1) ra is null.',
|
|
69
|
+
inputSchema: {
|
|
70
|
+
a_m: z
|
|
71
|
+
.number()
|
|
72
|
+
.finite()
|
|
73
|
+
.describe('Semi-major axis, in metres. Negative for hyperbolic orbits.'),
|
|
74
|
+
e: z.number().nonnegative().describe('Eccentricity (dimensionless).')
|
|
75
|
+
},
|
|
76
|
+
outputSchema: { rp_m: z.number(), ra_m: z.number().nullable() },
|
|
77
|
+
annotations: PURE_TOOL
|
|
78
|
+
}, ({ a_m, e }) => {
|
|
79
|
+
const { rp, ra } = periApoapsisRadii(a_m, e);
|
|
80
|
+
return result({ rp_m: rp, ra_m: ra });
|
|
81
|
+
});
|
|
82
|
+
server.registerTool('sphere_of_influence_radius', {
|
|
83
|
+
title: 'Sphere of influence',
|
|
84
|
+
description: 'Laplace sphere-of-influence radius of a secondary body orbiting a primary: r_SOI = a·(m/M)^(2/5).',
|
|
85
|
+
inputSchema: {
|
|
86
|
+
a_m: z
|
|
87
|
+
.number()
|
|
88
|
+
.positive()
|
|
89
|
+
.describe('Semi-major axis of the secondary around the primary, in metres.'),
|
|
90
|
+
m_kg: z
|
|
91
|
+
.number()
|
|
92
|
+
.positive()
|
|
93
|
+
.describe('Secondary (smaller) mass, in kg.'),
|
|
94
|
+
M_kg: z.number().positive().describe('Primary (larger) mass, in kg.')
|
|
95
|
+
},
|
|
96
|
+
outputSchema: { r_soi_m: z.number() },
|
|
97
|
+
annotations: PURE_TOOL
|
|
98
|
+
}, ({ a_m, m_kg, M_kg }) => result({ r_soi_m: sphereOfInfluenceRadius(a_m, m_kg, M_kg) }));
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=orbits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orbits.js","sourceRoot":"","sources":["../../src/tools/orbits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EACL,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACb,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CAAC,8DAA8D,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAiB,EAAE,EAAE;IACtD,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,sHAAsH;QACxH,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAC/D,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,WAAW,EAAE;iBACb,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CAAC,kDAAkD,CAAC;SAChE;QACD,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QACtC,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAC7E,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,oDAAoD;QACjE,WAAW,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE;QACtD,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QACnC,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CACvE,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,wCAAwC;QACrD,WAAW,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE;QACtD,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QACnC,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CACrE,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,mJAAmJ;QACrJ,WAAW,EAAE;YACX,GAAG,EAAE,YAAY;YACjB,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,MAAM,EAAE;iBACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,oBAAoB,CAAC;iBAC5C,QAAQ,CACP,6EAA6E,CAC9E;YACH,QAAQ,EAAE,QAAQ;SACnB;QACD,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QACnC,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CACzB,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CACtD,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,6EAA6E;QAC/E,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAClE,QAAQ,EAAE,QAAQ;SACnB;QACD,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QAClD,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;QACpB,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAExC,OAAO,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,eAAe,EAAE,CAAC,CAAC;IACrD,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EACT,sGAAsG;QACxG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,MAAM,EAAE;iBACR,QAAQ,CACP,6DAA6D,CAC9D;YACH,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;SACtE;QACD,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC/D,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE;QACb,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAE7C,OAAO,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,4BAA4B,EAC5B;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,mGAAmG;QACrG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,iEAAiE,CAClE;YACH,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;YAC/C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;SACtE;QACD,YAAY,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CACtB,MAAM,CAAC,EAAE,OAAO,EAAE,uBAAuB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAChE,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Radians } from '@interstellar-tools/types';
|
|
2
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
/** Standard gravitational parameter input, shared by most orbit tools. */
|
|
5
|
+
export declare const muSchema: z.ZodNumber;
|
|
6
|
+
/** Angle input that accepts either degrees or radians. */
|
|
7
|
+
export declare const angleSchema: z.ZodObject<{
|
|
8
|
+
value: z.ZodNumber;
|
|
9
|
+
unit: z.ZodEnum<{
|
|
10
|
+
deg: "deg";
|
|
11
|
+
rad: "rad";
|
|
12
|
+
}>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type AngleInputType = z.infer<typeof angleSchema>;
|
|
15
|
+
/** Angle output carrying both radians and degrees. */
|
|
16
|
+
export declare const angleOutputSchema: z.ZodObject<{
|
|
17
|
+
rad: z.ZodNumber;
|
|
18
|
+
deg: z.ZodNumber;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const toRadians: ({ value, unit }: AngleInputType) => Radians;
|
|
21
|
+
export declare const angleOutput: (rad: number) => {
|
|
22
|
+
rad: number;
|
|
23
|
+
deg: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Wraps a structured result so clients get both machine-readable
|
|
27
|
+
* `structuredContent` and a JSON text block for models that only read text.
|
|
28
|
+
*/
|
|
29
|
+
export declare const result: <T extends Record<string, unknown>>(data: T) => CallToolResult & {
|
|
30
|
+
structuredContent: T;
|
|
31
|
+
};
|
|
32
|
+
/** Tool annotations shared by every calculation tool: pure, offline, deterministic. */
|
|
33
|
+
export declare const PURE_TOOL: {
|
|
34
|
+
readonly readOnlyHint: true;
|
|
35
|
+
readonly destructiveHint: false;
|
|
36
|
+
readonly idempotentHint: true;
|
|
37
|
+
readonly openWorldHint: false;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,aAKlB,CAAC;AAEJ,0DAA0D;AAC1D,eAAO,MAAM,WAAW;;;;;;iBAKuD,CAAC;AAEhF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEzD,sDAAsD;AACtD,eAAO,MAAM,iBAAiB;;;iBAG5B,CAAC;AAEH,eAAO,MAAM,SAAS,GAAI,iBAAiB,cAAc,KAAG,OACR,CAAC;AAErD,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM;;;CAGrC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtD,MAAM,CAAC,KACN,cAAc,GAAG;IAAE,iBAAiB,EAAE,CAAC,CAAA;CAGxC,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,SAAS;;;;;CAKZ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { toRad } from '@interstellar-tools/equations';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/** Standard gravitational parameter input, shared by most orbit tools. */
|
|
4
|
+
export const muSchema = z
|
|
5
|
+
.number()
|
|
6
|
+
.positive()
|
|
7
|
+
.describe('Standard gravitational parameter μ = G·M of the central body, in m³/s². Earth ≈ 3.986004418e14, Sun ≈ 1.32712440018e20.');
|
|
8
|
+
/** Angle input that accepts either degrees or radians. */
|
|
9
|
+
export const angleSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
value: z.number().finite(),
|
|
12
|
+
unit: z.enum(['deg', 'rad'])
|
|
13
|
+
})
|
|
14
|
+
.describe('Angle with explicit unit, e.g. { "value": 28.5, "unit": "deg" }.');
|
|
15
|
+
/** Angle output carrying both radians and degrees. */
|
|
16
|
+
export const angleOutputSchema = z.object({
|
|
17
|
+
rad: z.number(),
|
|
18
|
+
deg: z.number()
|
|
19
|
+
});
|
|
20
|
+
export const toRadians = ({ value, unit }) => unit === 'deg' ? toRad(value) : value;
|
|
21
|
+
export const angleOutput = (rad) => ({
|
|
22
|
+
rad,
|
|
23
|
+
deg: (rad * 180) / Math.PI
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Wraps a structured result so clients get both machine-readable
|
|
27
|
+
* `structuredContent` and a JSON text block for models that only read text.
|
|
28
|
+
*/
|
|
29
|
+
export const result = (data) => ({
|
|
30
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
31
|
+
structuredContent: data
|
|
32
|
+
});
|
|
33
|
+
/** Tool annotations shared by every calculation tool: pure, offline, deterministic. */
|
|
34
|
+
export const PURE_TOOL = {
|
|
35
|
+
readOnlyHint: true,
|
|
36
|
+
destructiveHint: false,
|
|
37
|
+
idempotentHint: true,
|
|
38
|
+
openWorldHint: false
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAGtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,0EAA0E;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC;KACtB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CACP,yHAAyH,CAC1H,CAAC;AAEJ,0DAA0D;AAC1D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE;IAC1B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;CAC7B,CAAC;KACD,QAAQ,CAAC,kEAAkE,CAAC,CAAC;AAIhF,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;CAChB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAkB,EAAW,EAAE,CACpE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAiB,CAAC;AAErD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC;IAC3C,GAAG;IACH,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,IAAO,EACoC,EAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAChE,iBAAiB,EAAE,IAAI;CACxB,CAAC,CAAC;AAEH,uFAAuF;AACvF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,KAAK;IACtB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;CACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/tools/time.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE,eAAO,MAAM,iBAAiB,GAAI,QAAQ,SAAS,SAwBlD,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { convertTemporalUnit, normalizeTemporalUnit } from '@interstellar-tools/temporal';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { PURE_TOOL, result } from './shared.js';
|
|
4
|
+
const unitSchema = z
|
|
5
|
+
.string()
|
|
6
|
+
.min(1)
|
|
7
|
+
.describe('Time unit: s, ms, μs (or us), ns, ps, fs, as, zs, ys, min, h, d, yr, kyr, Myr, Gyr, or a long form such as "days" or "megayears". Years are Julian years (365.25 d).');
|
|
8
|
+
export const registerTimeTools = (server) => {
|
|
9
|
+
server.registerTool('convert_time', {
|
|
10
|
+
title: 'Convert time unit',
|
|
11
|
+
description: 'Convert a duration between time units, from attoseconds to gigayears.',
|
|
12
|
+
inputSchema: {
|
|
13
|
+
value: z.number().finite().describe('Duration in the `from` unit.'),
|
|
14
|
+
from: unitSchema,
|
|
15
|
+
to: unitSchema
|
|
16
|
+
},
|
|
17
|
+
outputSchema: { value: z.number(), unit: z.string() },
|
|
18
|
+
annotations: PURE_TOOL
|
|
19
|
+
}, ({ value, from, to }) => {
|
|
20
|
+
const { value: converted, unit } = convertTemporalUnit({ value, unit: normalizeTemporalUnit(from) }, normalizeTemporalUnit(to));
|
|
21
|
+
return result({ value: converted, unit });
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/tools/time.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,QAAQ,CACP,sKAAsK,CACvK,CAAC;AAEJ,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAiB,EAAE,EAAE;IACrD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,uEAAuE;QACzE,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;YACnE,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,UAAU;SACf;QACD,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QACrD,WAAW,EAAE,SAAS;KACvB,EACD,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE;QACtB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,mBAAmB,CACpD,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAC5C,qBAAqB,CAAC,EAAE,CAAC,CAC1B,CAAC;QAEF,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,76 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interstellar-tools/mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Model Context Protocol (MCP) server exposing interstellar-tools orbital mechanics equations and celestial body datasets to AI assistants.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"mcp-server",
|
|
9
|
+
"interstellar",
|
|
10
|
+
"tools",
|
|
11
|
+
"astrodynamics",
|
|
12
|
+
"orbital-mechanics",
|
|
13
|
+
"celestial-mechanics",
|
|
14
|
+
"kepler",
|
|
15
|
+
"hohmann-transfer",
|
|
16
|
+
"delta-v",
|
|
17
|
+
"vis-viva",
|
|
18
|
+
"planets",
|
|
19
|
+
"moons",
|
|
20
|
+
"interstellar-tools"
|
|
21
|
+
],
|
|
22
|
+
"homepage": "https://phun-ky.net/projects/interstellar-tools",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/phun-ky/interstellar-tools/issues"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/phun-ky/interstellar-tools.git"
|
|
29
|
+
},
|
|
30
|
+
"funding": "https://github.com/phun-ky/interstellar-tools?sponsor=1",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"author": "Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>",
|
|
33
|
+
"type": "module",
|
|
34
|
+
"main": "./dist/index.js",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"bin": {
|
|
37
|
+
"interstellar-tools-mcp": "dist/bin.js"
|
|
38
|
+
},
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"default": "./dist/index.js"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
50
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
51
|
+
"release": "release-it",
|
|
52
|
+
"start": "node dist/bin.js",
|
|
53
|
+
"test": "tsx --test **/__tests__/**/*.spec.ts",
|
|
54
|
+
"pretest:ci": "rm -rf coverage && mkdir -p coverage",
|
|
55
|
+
"test:ci": "glob-bin -c \"node --import tsx --test --no-warnings --experimental-test-coverage --test-reporter=cobertura --test-reporter-destination=coverage/cobertura-coverage.xml --test-reporter=spec --test-reporter-destination=stdout\" \"**/__tests__/**/*.spec.ts\""
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@interstellar-tools/constants": "^0.60.0",
|
|
59
|
+
"@interstellar-tools/equations": "^0.60.1",
|
|
60
|
+
"@interstellar-tools/temporal": "^0.60.0",
|
|
61
|
+
"@interstellar-tools/types": "^0.60.0",
|
|
62
|
+
"@modelcontextprotocol/sdk": "1.31.0",
|
|
63
|
+
"zod": "4.6.5"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/node": "^24.19.2",
|
|
67
|
+
"prettier": "^3.9.10",
|
|
68
|
+
"typescript": "^6.0.3"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=22.9.0"
|
|
72
|
+
},
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"access": "public"
|
|
75
|
+
}
|
|
76
|
+
}
|