dsh-baton-mcp 0.5.6 → 0.5.7
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/host/package.json +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/server.mjs +18 -0
package/host/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-baton-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "DeepSeek Harness plugin for dsh-baton: adding it is the whole install. Switched on, it registers the dsh-baton MCP server for Claude Code and Codex, then takes the baton over a local, owner-only control socket, runs it in a specific session through the host's own session controller, and hands the result back when the turn is done.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"LICENSE"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"dsh-baton-mcp": "0.5.
|
|
23
|
+
"dsh-baton-mcp": "0.5.7"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dsh": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-baton-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"mcpName": "io.github.JialaoLiu/dsh-baton",
|
|
5
5
|
"description": "Pass the baton from Claude Code, Codex or any MCP client to a local DeepSeek Harness: an MCP server that hands off tasks, continues a specific session, shows the run live in Harness and hands the result back when it is done.",
|
|
6
6
|
"type": "module",
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/JialaoLiu/dsh-baton",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.5.
|
|
10
|
+
"version": "0.5.7",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "dsh-baton-mcp",
|
|
15
|
-
"version": "0.5.
|
|
15
|
+
"version": "0.5.7",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
}
|
package/src/server.mjs
CHANGED
|
@@ -70,33 +70,44 @@ async function waitInChunks({ run_id }, progress) {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// MCP tool annotations. Every tool only talks to the local Harness (no open world).
|
|
74
|
+
const hints = (readOnlyHint, destructiveHint, idempotentHint) => ({ readOnlyHint, destructiveHint, idempotentHint, openWorldHint: false })
|
|
75
|
+
const READ = hints(true, false, true)
|
|
76
|
+
const EDIT = hints(false, false, true) // changes something, and the same call again changes nothing more
|
|
77
|
+
const annotations = (title, h = READ) => ({ title, ...h })
|
|
78
|
+
|
|
73
79
|
const TOOLS = [
|
|
74
80
|
{
|
|
75
81
|
name: 'dsh_list_workspaces',
|
|
82
|
+
annotations: annotations('List workspaces'),
|
|
76
83
|
description: 'List the workspaces (project folders) in the DeepSeek Harness sidebar; dsh_list_sessions lists the sessions inside them and dsh_create_workspace adds one. Returns id, path, title and session_count for each; the id is the workspace_id for dsh_send and dsh_rename_workspace. Read-only. Needs the dsh-baton-host plugin.',
|
|
77
84
|
inputSchema: { type: 'object', properties: {} },
|
|
78
85
|
run: () => core.api.workspaces(),
|
|
79
86
|
},
|
|
80
87
|
{
|
|
81
88
|
name: 'dsh_create_workspace',
|
|
89
|
+
annotations: annotations('Create workspace', EDIT),
|
|
82
90
|
description: 'Add a folder to the DeepSeek Harness sidebar as a workspace without starting a session; dsh_list_workspaces only lists existing ones, and dsh_send with a cwd registers the folder by itself. Creates the folder unless create_dir is false. Idempotent: an already registered folder returns its existing workspace. Returns id, path, title and created (false when it already existed). Needs the dsh-baton-host plugin.',
|
|
83
91
|
inputSchema: { type: 'object', required: ['path'], properties: { path: str('Absolute folder path (~ allowed)'), title: str('Sidebar title; defaults to the folder name'), create_dir: { type: 'boolean', description: 'Create the folder if missing', default: true } } },
|
|
84
92
|
run: (a) => core.api.create_workspace(a),
|
|
85
93
|
},
|
|
86
94
|
{
|
|
87
95
|
name: 'dsh_list_sessions',
|
|
96
|
+
annotations: annotations('List sessions'),
|
|
88
97
|
description: `List saved DeepSeek Harness sessions (conversations), newest first, to find a session_id; dsh_list_runs lists only the messages sent through dsh_send. Returns session_id, title, cwd, updated_at, running and bridge_runs (active dsh-baton run ids) for each. There is no paging: the list stops at limit, so to see older sessions raise limit or narrow it with cwd or query. Read-only. ${ARCHIVED}`,
|
|
89
98
|
inputSchema: { type: 'object', properties: { cwd: str('Only sessions of this workspace folder'), query: str('Case-insensitive text to match in title, folder or session id'), limit: int('Max sessions returned', 20), include_subagents: { type: 'boolean', description: 'Also list sub-agent sessions', default: false } } },
|
|
90
99
|
run: (a) => core.api.list_sessions(a),
|
|
91
100
|
},
|
|
92
101
|
{
|
|
93
102
|
name: 'dsh_read_session',
|
|
103
|
+
annotations: annotations('Read session'),
|
|
94
104
|
description: 'Read what was said in one session (its past messages), to catch up before continuing it; dsh_session_activity shows what it is doing now and dsh_status follows one run. Returns title, cwd, total_messages and the last messages, each with role (user or assistant), time, text and the names of tools the assistant called (tool output is not included). Read-only.',
|
|
95
105
|
inputSchema: { type: 'object', required: ['session_id'], properties: { session_id: str('Session id from dsh_list_sessions, e.g. session-…'), last: int('How many of the most recent messages to return; total_messages tells how many there are', 10) } },
|
|
96
106
|
run: (a) => core.api.read_session(a),
|
|
97
107
|
},
|
|
98
108
|
{
|
|
99
109
|
name: 'dsh_send',
|
|
110
|
+
annotations: annotations('Send message', hints(false, false, false)),
|
|
100
111
|
description: 'Send a message to a DeepSeek Harness session and return at once with a run_id, without waiting for the reply; dsh_wait then waits for it. With session_id it continues that existing session (same context, no new session); with cwd or workspace_id it starts a new session there (a cwd that is not a workspace yet is registered in the sidebar first). The turn runs in the background. If the session is already working, mode followup (default) queues the message after the current turn and steer adds it to the running turn; each message gets its own run_id. The message is delivered verbatim as a user message, with no prefix or label added: write it in the language the user works in, self-contained (Harness does not see this conversation), and say who is asking only if it matters. Then wait for the reply with dsh_wait (or the wait_command it returns, where offered).',
|
|
101
112
|
inputSchema: { type: 'object', required: ['message'], properties: { message: str('The task or reply to send'), session_id: str('Existing session to continue'), cwd: str('Workspace folder for a new session'), workspace_id: str('Harness workspace for a new session (from dsh_list_workspaces)'), mode: { type: 'string', enum: ['followup', 'steer'], description: 'followup queues after the current turn (default); steer injects into a running turn', default: 'followup' } } },
|
|
102
113
|
run: async (a) => {
|
|
@@ -113,42 +124,49 @@ const TOOLS = [
|
|
|
113
124
|
},
|
|
114
125
|
{
|
|
115
126
|
name: 'dsh_status',
|
|
127
|
+
annotations: annotations('Run status'),
|
|
116
128
|
description: 'Look once at one run sent with dsh_send, without waiting; dsh_wait waits for it to end and dsh_session_activity covers the whole session. Returns state (queued/running/waiting/completed/failed/cancelled, or interrupted when a Harness restart cut it short), session_id, recent events (text, tool calls), final reply, waiting_on when the turn is over but sub-agents or background jobs are still working, and human_interjections when someone typed in the Harness UI during the run (its result then reflects that input too). A one-off look, never a way to wait: to wait for the reply use dsh_wait, and if dsh_wait timed out, call dsh_wait again.',
|
|
117
129
|
inputSchema: { type: 'object', required: ['run_id'], properties: { run_id: str('Run id from dsh_send'), tail: int('How many recent events', 20) } },
|
|
118
130
|
run: (a) => core.api.status(a),
|
|
119
131
|
},
|
|
120
132
|
{
|
|
121
133
|
name: 'dsh_wait',
|
|
134
|
+
annotations: annotations('Wait for run'),
|
|
122
135
|
description: () => `Wait for a run sent with dsh_send to end and return its final status and reply; dsh_status only looks once.${isCodex() ? '' : ' Prefer the background wait_command from dsh_send when your client can run background shell commands and wake you when they exit: it costs no turns while waiting.'} Each call waits up to ${waitSeconds()} s (set by the server to stay under this client's tool timeout); if the run is still going it returns timed_out: true with just the state: then call dsh_wait again with the same run_id, without summarising progress.${isCodex() ? ` ${NO_POLL} ${codeModeYield()}` : ''} Sends progress notifications while waiting when the client asks for them.`,
|
|
123
136
|
inputSchema: { type: 'object', required: ['run_id'], properties: { run_id: str('Run id from dsh_send') } },
|
|
124
137
|
run: (a, { progress }) => waitInChunks(a, progress),
|
|
125
138
|
},
|
|
126
139
|
{
|
|
127
140
|
name: 'dsh_rename_session',
|
|
141
|
+
annotations: annotations('Rename session', EDIT),
|
|
128
142
|
description: 'Set the title of one DeepSeek Harness session (a conversation); dsh_rename_workspace renames a workspace (project folder) instead. Only the title changes; the conversation and any running turn are untouched. Can be called again at any time to change it back or to something else. Returns session_id and the saved title.',
|
|
129
143
|
inputSchema: { type: 'object', required: ['session_id', 'title'], properties: { session_id: str('Session id from dsh_list_sessions'), title: str('New title; surrounding spaces are trimmed and it must not be empty') } },
|
|
130
144
|
run: (a) => core.api.rename_session(a),
|
|
131
145
|
},
|
|
132
146
|
{
|
|
133
147
|
name: 'dsh_rename_workspace',
|
|
148
|
+
annotations: annotations('Rename workspace', EDIT),
|
|
134
149
|
description: 'Set the sidebar title of a DeepSeek Harness workspace (project folder); dsh_rename_session renames a single session instead. The folder on disk is not moved or renamed. Identify it by workspace_id or path. Can be called again to change it back. Returns id, path and the saved title.',
|
|
135
150
|
inputSchema: { type: 'object', required: ['title'], properties: { workspace_id: str('Workspace id from dsh_list_workspaces'), path: str('Workspace folder, used when workspace_id is not given'), title: str('New title; surrounding spaces are trimmed and it must not be empty') } },
|
|
136
151
|
run: (a) => core.api.rename_workspace(a),
|
|
137
152
|
},
|
|
138
153
|
{
|
|
139
154
|
name: 'dsh_session_activity',
|
|
155
|
+
annotations: annotations('Session activity'),
|
|
140
156
|
description: 'Show what one session is doing right now, across all its work; dsh_status follows a single run and dsh_read_session shows past messages. Returns busy, activity (its running turn, sub-agents at any depth, background jobs and reminders) and bridge_runs (active dsh-baton runs). Read-only. Check it before dsh_send to a session that might be busy, or before dsh_cancel.',
|
|
141
157
|
inputSchema: { type: 'object', required: ['session_id'], properties: { session_id: str('Session id from dsh_list_sessions') } },
|
|
142
158
|
run: (a) => core.api.activity(a),
|
|
143
159
|
},
|
|
144
160
|
{
|
|
145
161
|
name: 'dsh_cancel',
|
|
162
|
+
annotations: annotations('Cancel session work', hints(false, true, true)),
|
|
146
163
|
description: 'Stop everything a session is doing (running turn, sub-agents, background jobs, reminders), by run_id or session_id; the session itself is kept, and this is the only tool that stops work. It retries a few times until the session is quiet, then returns session_id, run (when run_id was given), attempts, still_busy, activity (whatever is still going) and queued_runs. Messages still waiting in the queue are not removed. Safe to repeat: on an idle session it does nothing and returns still_busy: false. Use dsh_session_activity first to see what would be stopped.',
|
|
147
164
|
inputSchema: { type: 'object', properties: { run_id: str('Run id from dsh_send; stops the session that run belongs to'), session_id: str('Session id, to stop work dsh-baton did not start') } },
|
|
148
165
|
run: (a) => core.api.cancel(a),
|
|
149
166
|
},
|
|
150
167
|
{
|
|
151
168
|
name: 'dsh_list_runs',
|
|
169
|
+
annotations: annotations('List runs'),
|
|
152
170
|
description: 'List the runs sent through dsh_send (the latest 100 are kept), newest first, to recover a lost run_id or review past hand-overs; dsh_list_sessions lists Harness sessions instead. Returns run_id, session_id, state, started_at, ended_at, message_preview, final_text and error for each; dsh_status shows one run in detail. Read-only.',
|
|
153
171
|
inputSchema: { type: 'object', properties: { limit: int('Max runs returned', 10) } },
|
|
154
172
|
run: (a) => core.api.list_runs(a),
|