@hanna84/mcp-writing 1.11.5 → 1.11.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/index.js +11 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,21 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [v1.11.6](https://github.com/hannasdev/mcp-writing.git
|
|
8
|
+
/compare/v1.11.5...v1.11.6)
|
|
9
|
+
|
|
10
|
+
- fix: improve MCP discoverability hints and tool guidance [`#65`](https://github.com/hannasdev/mcp-writing.git
|
|
11
|
+
/pull/65)
|
|
12
|
+
|
|
7
13
|
#### [v1.11.5](https://github.com/hannasdev/mcp-writing.git
|
|
8
14
|
/compare/v1.11.4...v1.11.5)
|
|
9
15
|
|
|
16
|
+
> 24 April 2026
|
|
17
|
+
|
|
10
18
|
- Add Copilot instructions and contribution workflow [`#64`](https://github.com/hannasdev/mcp-writing.git
|
|
11
19
|
/pull/64)
|
|
20
|
+
- Release 1.11.5 [`9b72b8b`](https://github.com/hannasdev/mcp-writing.git
|
|
21
|
+
/commit/9b72b8b827ccc7b9ab7532fbb355ab5894b56a59)
|
|
12
22
|
|
|
13
23
|
#### [v1.11.4](https://github.com/hannasdev/mcp-writing.git
|
|
14
24
|
/compare/v1.11.3...v1.11.4)
|
package/index.js
CHANGED
|
@@ -1296,7 +1296,7 @@ function createMcpServer() {
|
|
|
1296
1296
|
|
|
1297
1297
|
s.tool(
|
|
1298
1298
|
"get_async_job_status",
|
|
1299
|
-
"Get status and result for an asynchronous job started by async tools such as import_scrivener_sync_async, merge_scrivener_project_beta_async, or enrich_scene_characters_batch.",
|
|
1299
|
+
"Get status and result for an asynchronous job started by async tools such as import_scrivener_sync_async, merge_scrivener_project_beta_async, or enrich_scene_characters_batch. Use this to poll job progress after receiving a job_id. Common next step: if status is still running, call this tool again; if completed, inspect result and optionally run sync().",
|
|
1300
1300
|
{
|
|
1301
1301
|
job_id: z.string().describe("Job ID returned by an async start tool."),
|
|
1302
1302
|
include_result: z.boolean().optional().describe("If true (default), includes completed result payload when available."),
|
|
@@ -1305,7 +1305,7 @@ function createMcpServer() {
|
|
|
1305
1305
|
pruneAsyncJobs();
|
|
1306
1306
|
const job = asyncJobs.get(job_id);
|
|
1307
1307
|
if (!job) {
|
|
1308
|
-
return errorResponse("NOT_FOUND", `Async job '${job_id}' was not found. It may have expired.`);
|
|
1308
|
+
return errorResponse("NOT_FOUND", `Async job '${job_id}' was not found. It may have expired. Hint: call list_async_jobs to see currently tracked job IDs.`);
|
|
1309
1309
|
}
|
|
1310
1310
|
return jsonResponse({ ok: true, async: true, job: toPublicJob(job, include_result) });
|
|
1311
1311
|
}
|
|
@@ -1313,7 +1313,7 @@ function createMcpServer() {
|
|
|
1313
1313
|
|
|
1314
1314
|
s.tool(
|
|
1315
1315
|
"list_async_jobs",
|
|
1316
|
-
"List asynchronous jobs currently known to this server.",
|
|
1316
|
+
"List asynchronous jobs currently known to this server. Use this when you lost a job_id or need a dashboard view of running/completed jobs. Returns an object envelope containing a jobs array of job objects sorted by newest first.",
|
|
1317
1317
|
{
|
|
1318
1318
|
include_results: z.boolean().optional().describe("If true, includes completed result payloads."),
|
|
1319
1319
|
},
|
|
@@ -1328,7 +1328,7 @@ function createMcpServer() {
|
|
|
1328
1328
|
|
|
1329
1329
|
s.tool(
|
|
1330
1330
|
"cancel_async_job",
|
|
1331
|
-
"Cancel a running asynchronous job.",
|
|
1331
|
+
"Cancel a running asynchronous job. Use this when an import/merge/batch run was started with overly broad scope or is no longer needed. Returns the updated job state; cancellation is cooperative and may transition through 'cancelling' before 'cancelled'.",
|
|
1332
1332
|
{
|
|
1333
1333
|
job_id: z.string().describe("Job ID returned by an async start tool."),
|
|
1334
1334
|
},
|
|
@@ -1336,7 +1336,7 @@ function createMcpServer() {
|
|
|
1336
1336
|
pruneAsyncJobs();
|
|
1337
1337
|
const job = asyncJobs.get(job_id);
|
|
1338
1338
|
if (!job) {
|
|
1339
|
-
return errorResponse("NOT_FOUND", `Async job '${job_id}' was not found. It may have expired.`);
|
|
1339
|
+
return errorResponse("NOT_FOUND", `Async job '${job_id}' was not found. It may have expired. Hint: call list_async_jobs to find active IDs.`);
|
|
1340
1340
|
}
|
|
1341
1341
|
|
|
1342
1342
|
if (job.status !== "running") {
|
|
@@ -1461,7 +1461,7 @@ function createMcpServer() {
|
|
|
1461
1461
|
|
|
1462
1462
|
const rows = db.prepare(query).all(...params);
|
|
1463
1463
|
if (rows.length === 0) {
|
|
1464
|
-
return errorResponse("NO_RESULTS", "No scenes match the given filters.");
|
|
1464
|
+
return errorResponse("NO_RESULTS", "No scenes match the given filters. Hint: broaden filters or call search_metadata with a keyword first.");
|
|
1465
1465
|
}
|
|
1466
1466
|
|
|
1467
1467
|
const staleCount = rows.filter(r => r.metadata_stale).length;
|
|
@@ -1909,7 +1909,7 @@ function createMcpServer() {
|
|
|
1909
1909
|
// ---- list_threads --------------------------------------------------------
|
|
1910
1910
|
s.tool(
|
|
1911
1911
|
"list_threads",
|
|
1912
|
-
"List all subplot/storyline threads for a project. Returns a structured JSON envelope with results and total_count. Supports pagination via page/page_size.",
|
|
1912
|
+
"List all subplot/storyline threads for a project. Returns a structured JSON envelope with results and total_count. Use this to discover valid thread_id values before calling get_thread_arc or upsert_thread_link. Supports pagination via page/page_size.",
|
|
1913
1913
|
{
|
|
1914
1914
|
project_id: z.string().describe("Project ID."),
|
|
1915
1915
|
page: z.number().int().min(1).optional().describe("Optional page number for paginated responses (1-based)."),
|
|
@@ -1937,7 +1937,7 @@ function createMcpServer() {
|
|
|
1937
1937
|
// ---- get_thread_arc ------------------------------------------------------
|
|
1938
1938
|
s.tool(
|
|
1939
1939
|
"get_thread_arc",
|
|
1940
|
-
"Get ordered scene metadata for all scenes belonging to a thread, including the per-thread beat. Returns a structured JSON envelope with thread metadata, results, and total_count. Supports pagination via page/page_size.",
|
|
1940
|
+
"Get ordered scene metadata for all scenes belonging to a thread, including the per-thread beat. Returns a structured JSON envelope with thread metadata, results, and total_count. Use list_threads first to find a valid thread_id, then call get_scene_prose for close reading of specific scenes. Supports pagination via page/page_size.",
|
|
1941
1941
|
{
|
|
1942
1942
|
thread_id: z.string().describe("Thread ID."),
|
|
1943
1943
|
page: z.number().int().min(1).optional().describe("Optional page number for paginated responses (1-based)."),
|
|
@@ -1946,7 +1946,7 @@ function createMcpServer() {
|
|
|
1946
1946
|
async ({ thread_id, page, page_size }) => {
|
|
1947
1947
|
const thread = db.prepare(`SELECT * FROM threads WHERE thread_id = ?`).get(thread_id);
|
|
1948
1948
|
if (!thread) {
|
|
1949
|
-
return errorResponse("NOT_FOUND", `Thread '${thread_id}' not found.`);
|
|
1949
|
+
return errorResponse("NOT_FOUND", `Thread '${thread_id}' not found. Hint: call list_threads with project_id to get valid thread IDs.`);
|
|
1950
1950
|
}
|
|
1951
1951
|
|
|
1952
1952
|
const rows = db.prepare(`
|
|
@@ -2326,7 +2326,7 @@ function createMcpServer() {
|
|
|
2326
2326
|
|
|
2327
2327
|
const scene = db.prepare(`SELECT file_path FROM scenes WHERE scene_id = ?`).get(scene_id);
|
|
2328
2328
|
if (!scene) {
|
|
2329
|
-
return errorResponse("NOT_FOUND", `Scene '${scene_id}' not found.`);
|
|
2329
|
+
return errorResponse("NOT_FOUND", `Scene '${scene_id}' not found. Hint: call find_scenes to get valid scene IDs.`);
|
|
2330
2330
|
}
|
|
2331
2331
|
|
|
2332
2332
|
try {
|
|
@@ -2397,7 +2397,7 @@ function createMcpServer() {
|
|
|
2397
2397
|
|
|
2398
2398
|
const proposal = pendingProposals.get(proposal_id);
|
|
2399
2399
|
if (!proposal) {
|
|
2400
|
-
return errorResponse("PROPOSAL_NOT_FOUND", `Proposal '${proposal_id}' not found or has expired.`);
|
|
2400
|
+
return errorResponse("PROPOSAL_NOT_FOUND", `Proposal '${proposal_id}' not found or has expired. Hint: call propose_edit again to create a fresh proposal_id.`);
|
|
2401
2401
|
}
|
|
2402
2402
|
|
|
2403
2403
|
if (proposal.scene_id !== scene_id) {
|