@dzbot/dzstudio-mcp 0.0.0-stage → 0.1.1
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/LICENSE +661 -0
- package/README.md +162 -2
- package/dist/config/config.js +172 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/sessions.js +67 -0
- package/dist/config/sessions.js.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/agent.js +1148 -0
- package/dist/mcp/agent.js.map +1 -0
- package/dist/mcp/server.js +263 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/protocol/client.js +134 -0
- package/dist/protocol/client.js.map +1 -0
- package/dist/protocol/session.js +837 -0
- package/dist/protocol/session.js.map +1 -0
- package/dist/protocol/transport.js +66 -0
- package/dist/protocol/transport.js.map +1 -0
- package/dist/scene/chunks.js +30 -0
- package/dist/scene/chunks.js.map +1 -0
- package/dist/scene/edits.js +183 -0
- package/dist/scene/edits.js.map +1 -0
- package/dist/scene/float32.js +167 -0
- package/dist/scene/float32.js.map +1 -0
- package/dist/scene/ids.js +43 -0
- package/dist/scene/ids.js.map +1 -0
- package/dist/scene/index.js +9 -0
- package/dist/scene/index.js.map +1 -0
- package/dist/scene/json.js +294 -0
- package/dist/scene/json.js.map +1 -0
- package/dist/scene/projectload.js +663 -0
- package/dist/scene/projectload.js.map +1 -0
- package/dist/scene/scene.js +506 -0
- package/dist/scene/scene.js.map +1 -0
- package/dist/scene/srcjson.js +297 -0
- package/dist/scene/srcjson.js.map +1 -0
- package/dist/scene/textform.js +257 -0
- package/dist/scene/textform.js.map +1 -0
- package/dist/scene/types.js +35 -0
- package/dist/scene/types.js.map +1 -0
- package/dist/world/data.js +604 -0
- package/dist/world/data.js.map +1 -0
- package/dist/world/format.js +205 -0
- package/dist/world/format.js.map +1 -0
- package/dist/world/source.js +267 -0
- package/dist/world/source.js.map +1 -0
- package/dist/world/tools.js +530 -0
- package/dist/world/tools.js.map +1 -0
- package/package.json +48 -4
package/README.md
CHANGED
|
@@ -1,3 +1,163 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dzstudio-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An MCP server that lets an AI agent build in **dzStudio**, the in-game object editor for DayZ, together with people.
|
|
4
|
+
The agent joins a dzStudio collaboration session as a participant without the game: it speaks the open collaboration
|
|
5
|
+
protocol **dzcollab 1** (see `PROTOCOL.md` of the dzStudio collaboration server), keeps the project state on your
|
|
6
|
+
machine and applies every operation exactly like the editor does. Everyone in the session sees it as "‹you›'s agent",
|
|
7
|
+
with a status line saying what it is working on.
|
|
8
|
+
|
|
9
|
+
The agent works on data, not on screenshots. It never saves: when it is done it asks for review, and a person in the
|
|
10
|
+
session saves or discards.
|
|
11
|
+
|
|
12
|
+
## Setup (once)
|
|
13
|
+
|
|
14
|
+
Requires Node.js 22 or newer. Add it to your MCP client, for example in Claude Code:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
claude mcp add dzstudio -e DZSTUDIO_MCP_SERVERS=dzbot=https://collab.dzbot.de/dzcollab/ -e DZSTUDIO_MCP_AGENT_NAME=Scout -- npx -y @dzbot/dzstudio-mcp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
or in a client's JSON configuration (Claude Desktop, Cursor and others):
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"dzstudio": {
|
|
26
|
+
"command": "npx",
|
|
27
|
+
"args": ["-y", "@dzbot/dzstudio-mcp"],
|
|
28
|
+
"env": { "DZSTUDIO_MCP_SERVERS": "dzbot=https://collab.dzbot.de/dzcollab/", "DZSTUDIO_MCP_AGENT_NAME": "Scout" }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use your own server's address instead of dzbot's if you run the collaboration server yourself. To run it from a
|
|
35
|
+
checkout instead: `npm install && npm run build`, then `node /path/to/dzstudio-mcp/dist/index.js` as the command.
|
|
36
|
+
|
|
37
|
+
That is all the configuration there is. From then on you work in the conversation:
|
|
38
|
+
|
|
39
|
+
1. **Servers** — the agent adds a server with `add_server` (a name of your choice and the server's base address), or
|
|
40
|
+
you name them once in `DZSTUDIO_MCP_SERVERS` (`name=url`, comma-separated).
|
|
41
|
+
2. **Login** — `login` gives you an address and a code; confirm it in the browser and the agent finishes the login.
|
|
42
|
+
The token is stored on your machine and kept across restarts.
|
|
43
|
+
3. **Sessions** — the agent lists projects and sessions, joins one (by id, by opening a project that has a running
|
|
44
|
+
session, or with an invitation code), and can be in several sessions at once.
|
|
45
|
+
|
|
46
|
+
Settings and tokens live in `~/.config/dzstudio-mcp/` (or `$XDG_CONFIG_HOME/dzstudio-mcp`, `%APPDATA%\dzstudio-mcp` on
|
|
47
|
+
Windows, or the directory in `DZSTUDIO_MCP_CONFIG_DIR`). `credentials.json` is readable only by you; no tool ever
|
|
48
|
+
returns a token to the agent.
|
|
49
|
+
|
|
50
|
+
| Variable | Meaning |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `DZSTUDIO_MCP_SERVERS` | Servers added on start if missing: `name=url,name=url` |
|
|
53
|
+
| `DZSTUDIO_MCP_AGENT_NAME` | Short name of the agent (default `Agent`) |
|
|
54
|
+
| `DZSTUDIO_MCP_CONFIG_DIR` | Where settings and tokens are kept |
|
|
55
|
+
| `DZSTUDIO_MCP_CACHE_LIMIT_MB` | Size limit of the map data cache in MB (default 2048) |
|
|
56
|
+
| `DZSTUDIO_MCP_WORLD_DATA` | Class and map data: a folder or a `file://`/`https://` base address (overrides `worldData.base`) |
|
|
57
|
+
| `DZSTUDIO_MCP_WORLD_DATA_POINTER` | Pointer to the current revisions for a base address (overrides `worldData.pointer`) |
|
|
58
|
+
|
|
59
|
+
### Class and map data
|
|
60
|
+
|
|
61
|
+
The world tools compute on static data: per world 256 m tiles with terrain heights, surface, walkable surfaces and
|
|
62
|
+
static objects, and one class index with boxes, dimensions and shape rasters. By default they come from dzbot
|
|
63
|
+
(`https://uploads.dzbot.de/world-data/`, current revisions from `https://dzbot.de/api/public/world-data`). Another
|
|
64
|
+
source is set once in `config.json`:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "worldData": { "base": "file:///srv/world-data/" } }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
or a mirror with its own pointer:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{ "worldData": { "base": "https://mirror.example.org/world-data/", "pointer": "https://mirror.example.org/world-data.json" } }
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A local folder has the published layout (`classes/<revision>/…`, `worlds/<world>/<revision>/…`); its newest revisions
|
|
77
|
+
are used and the map key comes from each manifest. Downloaded files are kept in `cache/` of the config directory below
|
|
78
|
+
their revision and never requested again; every tile and raster is checked against size and SHA-256 from the manifest,
|
|
79
|
+
a changed file in the cache is loaded once more, and a file that stays wrong is reported as "map data corrupt". The
|
|
80
|
+
session's map key (e.g. `chernarus`) picks the world; the revision stays the same for the whole session. Missing data
|
|
81
|
+
are "unknown", never zero: a class without data has "box unknown", a map without data gives "No map data for ‹map› —
|
|
82
|
+
project objects only", and a tile that cannot be loaded is named in the answer.
|
|
83
|
+
|
|
84
|
+
The cache holds at most 2 GB. Above that, the least recently used tiles and rasters are deleted (and downloaded again
|
|
85
|
+
when a question needs them); nothing of a revision that a session the agent is in works on is ever deleted. Another
|
|
86
|
+
limit is set in MB with `worldData.cacheLimitMb` in `config.json` or `DZSTUDIO_MCP_CACHE_LIMIT_MB`:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{ "worldData": { "cacheLimitMb": 512 } }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Tools
|
|
93
|
+
|
|
94
|
+
| Tool | What it does |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `list_servers`, `add_server`, `login` | Servers, whether you are signed in, whether they admit agents |
|
|
97
|
+
| `list_projects`, `open_project`, `join_session` | Projects and sessions you may join; join one, or open a project on the server that nobody has open |
|
|
98
|
+
| `list_sessions`, `switch_session`, `leave_session` | The sessions the agent is in; the current one is used when a tool names none |
|
|
99
|
+
| `session_info`, `session_events` | Participants with phase and status, rights, save state; what happened since the last call |
|
|
100
|
+
| `read_scene`, `query_objects` | Groups and objects of the project, by id, group, class, circle or rectangle |
|
|
101
|
+
| `create_objects`, `modify_objects`, `delete_objects` | Each call is one step for everyone; objects are locked first |
|
|
102
|
+
| `release` | Let others edit objects the agent holds |
|
|
103
|
+
| `set_status`, `request_review` | Phase (waiting for work, working, waiting for review) and the status line everyone sees |
|
|
104
|
+
| `world_info` | World, data revisions, game version and export date for the session's map; place names near a point or by text |
|
|
105
|
+
| `world_objects` | Static map objects and project objects whose box touches a circle or rectangle, with transform, distance and size or "box unknown" |
|
|
106
|
+
| `ground_at` | Terrain height, material, water, roads and building floors at up to 1000 points; the highest surface below a height |
|
|
107
|
+
| `object_ground` | How project objects or a hypothetical placement stand: "floats ‹x› m", "‹x› m in the ground", or the corner distances |
|
|
108
|
+
| `check_overlap` | Which map and project objects intersect, as rotated boxes with penetration depth; with `precise`, the collision rasters confirm each intersection (pairs without a raster are compared as boxes and say so); objects without a known box are named |
|
|
109
|
+
| `class_info` | Size, clipping and collision box, radius, flags and raster of classes or models |
|
|
110
|
+
|
|
111
|
+
Some rules the MCP keeps for the agent: it joins only servers that announce the `agents` capability, so nobody sees it
|
|
112
|
+
as a human; it changes an existing object only while holding its lock; it never saves, invites, removes anyone or
|
|
113
|
+
ends a session; it does not edit loot (loot entries pass through unchanged); after 30 minutes without work it leaves
|
|
114
|
+
a session and joins again on the next task.
|
|
115
|
+
|
|
116
|
+
**Restarts.** The MCP keeps every session it is in, with its place in the session log and the project state there, in
|
|
117
|
+
`sessions/` of the config directory. When it stops it does not leave; when it starts again it returns to each session
|
|
118
|
+
as the same participant and continues from that place, with what others did in the meantime. If the server cannot take
|
|
119
|
+
it back that way (it was away too long, or the server no longer has the log from there), it joins anew. A session it
|
|
120
|
+
would have left while idle meanwhile, or one that ended, is forgotten.
|
|
121
|
+
|
|
122
|
+
**Opening a project nobody has open.** When no session is running for a project on the server, `open_project` loads
|
|
123
|
+
its files and builds the project state exactly as dzStudio does when it opens them — the same groups, objects, ids form,
|
|
124
|
+
companion data and order, byte for byte — then starts the session with it, as the only participant. This needs the right
|
|
125
|
+
to save the project (the server checks it) and the class data (for each object, dzStudio notes whether the game knows its
|
|
126
|
+
class; the class data stand in for the game). Where dzStudio's result depends on the running game and not on the files,
|
|
127
|
+
the MCP refuses instead of opening a different state: a group file that places a model by its path (the game places the
|
|
128
|
+
model to learn its origin), or a project with loot turned on. A person then opens it in dzStudio, and the agent joins
|
|
129
|
+
that session. Agents never create a new project.
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm test # unit tests, plus an integration test against the reference collaboration server if Go is installed
|
|
135
|
+
npm run typecheck
|
|
136
|
+
npm run format
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The integration tests build the reference server from `../collab-server` (or `DZCOLLAB_SOURCE`), or use the binary in
|
|
140
|
+
`DZCOLLAB_SERVER`, and run it on a free port on 127.0.0.1. One of them drives the whole agent flow through an MCP
|
|
141
|
+
client: login with a code, joining a person's session, status, a step, review, leaving. Without Go and without a binary
|
|
142
|
+
they are skipped.
|
|
143
|
+
|
|
144
|
+
The world tools are tested on a tiny world in `test/fixtures/world-data`, made with the reference converter. An opt-in
|
|
145
|
+
test compares every answer with the converter's JavaScript reader on a full converted world: it runs when
|
|
146
|
+
`DZSTUDIO_MCP_WORLD_DATA_REFERENCE` (default `/tmp/world-data-out`) holds one and `DZSTUDIO_MCP_WORLD_DATA_READER` points
|
|
147
|
+
to `world_data_read.js`; `DZSTUDIO_MCP_WORLD_DATA_WORLD` picks the world (default `chernarusplus`).
|
|
148
|
+
|
|
149
|
+
| Directory | Content |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `src/scene` | The project state outside the game: text form, numbers, chunks, ids, applying operations, building new ones, opening a project from its files |
|
|
152
|
+
| `src/protocol` | The dzcollab 1 client: requests, the session with its poll and send channel |
|
|
153
|
+
| `src/config` | Servers, agent name, tokens and the world data source, configured once |
|
|
154
|
+
| `src/world` | Class and map data: file formats, loading and cache, and the geometry behind the world tools |
|
|
155
|
+
| `src/mcp` | The tools and the MCP wiring |
|
|
156
|
+
|
|
157
|
+
## Contributing
|
|
158
|
+
|
|
159
|
+
Issues and pull requests are welcome, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
AGPL-3.0, see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { randomToken } from '../scene/ids.js';
|
|
6
|
+
export const DEFAULT_AGENT_NAME = 'Agent';
|
|
7
|
+
const NAME_FORM = /^[A-Za-z0-9][A-Za-z0-9 ._-]{0,63}$/;
|
|
8
|
+
export function defaultConfigDir(env = process.env) {
|
|
9
|
+
if (env.DZSTUDIO_MCP_CONFIG_DIR)
|
|
10
|
+
return env.DZSTUDIO_MCP_CONFIG_DIR;
|
|
11
|
+
if (process.platform === 'win32' && env.APPDATA)
|
|
12
|
+
return join(env.APPDATA, 'dzstudio-mcp');
|
|
13
|
+
return join(env.XDG_CONFIG_HOME || join(homedir(), '.config'), 'dzstudio-mcp');
|
|
14
|
+
}
|
|
15
|
+
/** `DZSTUDIO_MCP_SERVERS="local=http://127.0.0.1:8080/dzcollab/,dzbot=https://…"` */
|
|
16
|
+
export function parseServerList(text) {
|
|
17
|
+
return text
|
|
18
|
+
.split(',')
|
|
19
|
+
.map((s) => s.trim())
|
|
20
|
+
.filter(Boolean)
|
|
21
|
+
.map((s) => {
|
|
22
|
+
const i = s.indexOf('=');
|
|
23
|
+
if (i <= 0)
|
|
24
|
+
throw new Error(`server entry needs name=url: ${s}`);
|
|
25
|
+
return { name: s.slice(0, i).trim(), url: s.slice(i + 1).trim() };
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function validateServerName(name) {
|
|
29
|
+
if (!NAME_FORM.test(name))
|
|
30
|
+
throw new Error('A server name has 1 to 64 characters: letters, digits, space, dot, _ and -');
|
|
31
|
+
}
|
|
32
|
+
export function validateServerUrl(url) {
|
|
33
|
+
let u;
|
|
34
|
+
try {
|
|
35
|
+
u = new URL(url);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new Error(`Not a URL: ${url}`);
|
|
39
|
+
}
|
|
40
|
+
if (u.protocol !== 'https:' && u.protocol !== 'http:')
|
|
41
|
+
throw new Error('The base address must be http or https');
|
|
42
|
+
return u.href.endsWith('/') ? u.href : u.href + '/';
|
|
43
|
+
}
|
|
44
|
+
export class ConfigStore {
|
|
45
|
+
env;
|
|
46
|
+
dir;
|
|
47
|
+
config;
|
|
48
|
+
credentials;
|
|
49
|
+
constructor(dir, env = process.env) {
|
|
50
|
+
this.env = env;
|
|
51
|
+
this.dir = dir ?? defaultConfigDir(env);
|
|
52
|
+
}
|
|
53
|
+
path(name) {
|
|
54
|
+
return join(this.dir, name);
|
|
55
|
+
}
|
|
56
|
+
ensureDir() {
|
|
57
|
+
if (!existsSync(this.dir))
|
|
58
|
+
mkdirSync(this.dir, { recursive: true, mode: 0o700 });
|
|
59
|
+
}
|
|
60
|
+
readJson(name) {
|
|
61
|
+
const p = this.path(name);
|
|
62
|
+
if (!existsSync(p))
|
|
63
|
+
return undefined;
|
|
64
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
65
|
+
}
|
|
66
|
+
writeJson(name, value, mode) {
|
|
67
|
+
this.ensureDir();
|
|
68
|
+
const p = this.path(name);
|
|
69
|
+
const tmp = p + '.tmp';
|
|
70
|
+
writeFileSync(tmp, JSON.stringify(value, null, 2) + '\n', { mode });
|
|
71
|
+
chmodSync(tmp, mode);
|
|
72
|
+
renameSync(tmp, p);
|
|
73
|
+
}
|
|
74
|
+
load() {
|
|
75
|
+
if (this.config)
|
|
76
|
+
return this.config;
|
|
77
|
+
const stored = this.readJson('config.json') ?? {};
|
|
78
|
+
let dirty = !existsSync(this.path('config.json'));
|
|
79
|
+
const config = {
|
|
80
|
+
agentName: stored.agentName || DEFAULT_AGENT_NAME,
|
|
81
|
+
installationId: /^[0-9a-z]{16}$/.test(stored.installationId ?? '') ? stored.installationId : randomToken(16),
|
|
82
|
+
servers: Array.isArray(stored.servers)
|
|
83
|
+
? stored.servers.filter((s) => s && typeof s.name === 'string' && typeof s.url === 'string')
|
|
84
|
+
: [],
|
|
85
|
+
};
|
|
86
|
+
if (stored.worldData && typeof stored.worldData === 'object')
|
|
87
|
+
config.worldData = stored.worldData;
|
|
88
|
+
if (config.installationId !== stored.installationId)
|
|
89
|
+
dirty = true;
|
|
90
|
+
if (this.env.DZSTUDIO_MCP_AGENT_NAME && config.agentName !== this.env.DZSTUDIO_MCP_AGENT_NAME) {
|
|
91
|
+
config.agentName = this.env.DZSTUDIO_MCP_AGENT_NAME;
|
|
92
|
+
dirty = true;
|
|
93
|
+
}
|
|
94
|
+
if (this.env.DZSTUDIO_MCP_SERVERS) {
|
|
95
|
+
for (const s of parseServerList(this.env.DZSTUDIO_MCP_SERVERS)) {
|
|
96
|
+
if (!config.servers.some((x) => x.name === s.name)) {
|
|
97
|
+
validateServerName(s.name);
|
|
98
|
+
config.servers.push({ name: s.name, url: validateServerUrl(s.url) });
|
|
99
|
+
dirty = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.config = config;
|
|
104
|
+
if (dirty)
|
|
105
|
+
this.save();
|
|
106
|
+
return config;
|
|
107
|
+
}
|
|
108
|
+
/** World data settings: `DZSTUDIO_MCP_WORLD_DATA` (and `…_POINTER`) win over config.json, without being stored. */
|
|
109
|
+
worldData() {
|
|
110
|
+
const out = {
|
|
111
|
+
...this.load().worldData,
|
|
112
|
+
cacheDir: join(this.dir, 'cache'),
|
|
113
|
+
};
|
|
114
|
+
const base = this.env.DZSTUDIO_MCP_WORLD_DATA;
|
|
115
|
+
if (base) {
|
|
116
|
+
out.base = /^[a-z]+:\/\//.test(base) ? base : pathToFileURL(resolve(base)).href;
|
|
117
|
+
delete out.pointer;
|
|
118
|
+
}
|
|
119
|
+
if (this.env.DZSTUDIO_MCP_WORLD_DATA_POINTER)
|
|
120
|
+
out.pointer = this.env.DZSTUDIO_MCP_WORLD_DATA_POINTER;
|
|
121
|
+
const mb = Number(this.env.DZSTUDIO_MCP_CACHE_LIMIT_MB ?? out.cacheLimitMb);
|
|
122
|
+
if (Number.isFinite(mb) && mb > 0)
|
|
123
|
+
out.cacheLimit = Math.round(mb * 1024 * 1024);
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
save() {
|
|
127
|
+
if (this.config)
|
|
128
|
+
this.writeJson('config.json', this.config, 0o600);
|
|
129
|
+
}
|
|
130
|
+
server(name) {
|
|
131
|
+
const servers = this.load().servers;
|
|
132
|
+
if (!servers.length)
|
|
133
|
+
throw new Error('No server configured — call add_server');
|
|
134
|
+
if (name === undefined)
|
|
135
|
+
return servers[0];
|
|
136
|
+
const s = servers.find((x) => x.name === name);
|
|
137
|
+
if (!s)
|
|
138
|
+
throw new Error(`No server named ${name} — call list_servers`);
|
|
139
|
+
return s;
|
|
140
|
+
}
|
|
141
|
+
addServer(name, url) {
|
|
142
|
+
validateServerName(name);
|
|
143
|
+
const entry = { name, url: validateServerUrl(url) };
|
|
144
|
+
const config = this.load();
|
|
145
|
+
if (config.servers.some((s) => s.name === name))
|
|
146
|
+
throw new Error(`A server named ${name} already exists`);
|
|
147
|
+
config.servers.push(entry);
|
|
148
|
+
this.save();
|
|
149
|
+
return entry;
|
|
150
|
+
}
|
|
151
|
+
creds() {
|
|
152
|
+
this.credentials ??= this.readJson('credentials.json') ?? {};
|
|
153
|
+
return this.credentials;
|
|
154
|
+
}
|
|
155
|
+
credential(server) {
|
|
156
|
+
const c = this.creds()[server];
|
|
157
|
+
if (!c)
|
|
158
|
+
return undefined;
|
|
159
|
+
if (c.expiresAt !== undefined && c.expiresAt <= Date.now())
|
|
160
|
+
return undefined;
|
|
161
|
+
return c;
|
|
162
|
+
}
|
|
163
|
+
setCredential(server, c) {
|
|
164
|
+
const all = this.creds();
|
|
165
|
+
if (c)
|
|
166
|
+
all[server] = c;
|
|
167
|
+
else
|
|
168
|
+
delete all[server];
|
|
169
|
+
this.writeJson('credentials.json', all, 0o600);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* The sessions the agent is in, kept in `sessions/` of the config directory: per session a small file with the
|
|
6
|
+
* participation and a file with the project state at a sequence number (the cursor `resume` continues from).
|
|
7
|
+
*/
|
|
8
|
+
export class SessionStore {
|
|
9
|
+
dir;
|
|
10
|
+
constructor(dir) {
|
|
11
|
+
this.dir = dir;
|
|
12
|
+
}
|
|
13
|
+
base(server, sessionId) {
|
|
14
|
+
return join(this.dir, createHash('sha256').update(`${server}\u0000${sessionId}`).digest('hex').slice(0, 24));
|
|
15
|
+
}
|
|
16
|
+
write(path, data) {
|
|
17
|
+
if (!existsSync(this.dir))
|
|
18
|
+
mkdirSync(this.dir, { recursive: true, mode: 0o700 });
|
|
19
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
20
|
+
writeFileSync(tmp, data, { mode: 0o600 });
|
|
21
|
+
renameSync(tmp, path);
|
|
22
|
+
}
|
|
23
|
+
list() {
|
|
24
|
+
if (!existsSync(this.dir))
|
|
25
|
+
return [];
|
|
26
|
+
const out = [];
|
|
27
|
+
for (const f of readdirSync(this.dir)) {
|
|
28
|
+
if (!f.endsWith('.json'))
|
|
29
|
+
continue;
|
|
30
|
+
try {
|
|
31
|
+
const s = JSON.parse(readFileSync(join(this.dir, f), 'utf8'));
|
|
32
|
+
if (typeof s.sessionId === 'string' && typeof s.participantId === 'string')
|
|
33
|
+
out.push(s);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// a broken file is no session to return to
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
save(s) {
|
|
42
|
+
this.write(`${this.base(s.server, s.sessionId)}.json`, JSON.stringify(s) + '\n');
|
|
43
|
+
}
|
|
44
|
+
/** The project state after sequence number `seq`, as its text form. */
|
|
45
|
+
saveState(server, sessionId, seq, text) {
|
|
46
|
+
this.write(`${this.base(server, sessionId)}.state`, `${seq}\n${text}`);
|
|
47
|
+
}
|
|
48
|
+
state(server, sessionId) {
|
|
49
|
+
try {
|
|
50
|
+
const raw = readFileSync(`${this.base(server, sessionId)}.state`, 'utf8');
|
|
51
|
+
const nl = raw.indexOf('\n');
|
|
52
|
+
const seq = Number(raw.slice(0, nl));
|
|
53
|
+
if (nl < 0 || !Number.isSafeInteger(seq) || seq < 0)
|
|
54
|
+
return undefined;
|
|
55
|
+
return { seq, text: raw.slice(nl + 1) };
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
remove(server, sessionId) {
|
|
62
|
+
const b = this.base(server, sessionId);
|
|
63
|
+
rmSync(`${b}.json`, { force: true });
|
|
64
|
+
rmSync(`${b}.state`, { force: true });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/config/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { ConfigStore } from './config/config.js';
|
|
4
|
+
import { Agent } from './mcp/agent.js';
|
|
5
|
+
import { createServer } from './mcp/server.js';
|
|
6
|
+
const agent = new Agent({ store: new ConfigStore() });
|
|
7
|
+
const server = createServer(agent);
|
|
8
|
+
async function shutdown() {
|
|
9
|
+
await agent.shutdown().catch(() => undefined);
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
process.on('SIGINT', () => void shutdown());
|
|
13
|
+
process.on('SIGTERM', () => void shutdown());
|
|
14
|
+
process.stdin.on('close', () => void shutdown());
|
|
15
|
+
await server.connect(new StdioServerTransport());
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,WAAW,EAAE,EAAE,CAAC,CAAC;AACtD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAEnC,KAAK,UAAU,QAAQ;IACrB,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAC7C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAEjD,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC"}
|