create-academic-research 0.1.13 → 0.1.15
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 +71 -11
- package/dist/bin/academic-research.js +0 -0
- package/dist/bin/create-academic-research.js +0 -0
- package/dist/src/capabilities.d.ts +132 -3
- package/dist/src/capabilities.js +993 -48
- package/dist/src/cli.js +448 -33
- package/dist/src/mcp-env.d.ts +4 -0
- package/dist/src/mcp-env.js +2 -2
- package/dist/src/mcp-probe.d.ts +3 -2
- package/dist/src/mcp-probe.js +87 -30
- package/dist/src/project.d.ts +18 -0
- package/dist/src/project.js +654 -22
- package/dist/src/stack.d.ts +38 -0
- package/dist/src/stack.js +260 -14
- package/package.json +2 -2
- package/template/README.md +37 -4
- package/template/_gitignore +1 -0
- package/template/docs/agent/mcp-client-setup.md +43 -3
- package/template/docs/agent/mcp-setup.md +60 -0
- package/template/docs/getting-started.md +17 -5
- package/template/package.json +7 -1
package/dist/src/stack.d.ts
CHANGED
|
@@ -12,6 +12,27 @@ export interface CapabilityPreset {
|
|
|
12
12
|
skill_bundles: string[];
|
|
13
13
|
mcp_servers: string[];
|
|
14
14
|
}
|
|
15
|
+
export type McpConnectionMode = "stdio-local" | "remote-curated" | "remote-custom" | "local-service" | "manual-local" | "manual";
|
|
16
|
+
export interface McpServerMode {
|
|
17
|
+
connection_mode: McpConnectionMode;
|
|
18
|
+
readiness?: string;
|
|
19
|
+
priority?: string;
|
|
20
|
+
execution_mode?: string;
|
|
21
|
+
source_need?: string;
|
|
22
|
+
source?: string;
|
|
23
|
+
hosted_url?: string;
|
|
24
|
+
install_command?: string;
|
|
25
|
+
uninstall_command?: string;
|
|
26
|
+
setup_commands?: string[];
|
|
27
|
+
command?: string;
|
|
28
|
+
args?: string[];
|
|
29
|
+
env?: Record<string, string>;
|
|
30
|
+
required_env?: string[];
|
|
31
|
+
recommended_env?: string[];
|
|
32
|
+
local_service?: string;
|
|
33
|
+
smoke_test?: string;
|
|
34
|
+
risks?: string;
|
|
35
|
+
}
|
|
15
36
|
export interface McpServer {
|
|
16
37
|
readiness: string;
|
|
17
38
|
priority: string;
|
|
@@ -30,6 +51,15 @@ export interface McpServer {
|
|
|
30
51
|
local_service: string;
|
|
31
52
|
smoke_test: string;
|
|
32
53
|
risks: string;
|
|
54
|
+
default_mode?: string;
|
|
55
|
+
recommended_mode?: string;
|
|
56
|
+
modes?: Record<string, McpServerMode>;
|
|
57
|
+
}
|
|
58
|
+
export interface ResolvedMcpServer extends McpServer {
|
|
59
|
+
selected_mode: string;
|
|
60
|
+
connection_mode: McpConnectionMode;
|
|
61
|
+
remote_url_env?: string;
|
|
62
|
+
remote_configured?: boolean;
|
|
33
63
|
}
|
|
34
64
|
export interface AgentStack {
|
|
35
65
|
version: number;
|
|
@@ -42,3 +72,11 @@ export interface AgentStack {
|
|
|
42
72
|
export type McpToolCommandKey = "install_command" | "uninstall_command";
|
|
43
73
|
export declare const AGENT_STACK: AgentStack;
|
|
44
74
|
export declare function presetMcpServers(preset: string): string[];
|
|
75
|
+
export declare function resolveMcpServer(serverName: string, mode?: string): ResolvedMcpServer;
|
|
76
|
+
export declare function normalizeMcpMode(serverName: string, mode?: string): string;
|
|
77
|
+
export declare function mcpServerModeKeys(serverName: string): string[];
|
|
78
|
+
export declare function mcpRecommendedMode(serverName: string): string;
|
|
79
|
+
export declare function mcpModeLabel(serverName: string, mode?: string): string;
|
|
80
|
+
export declare function mcpModeKeyLabel(mode: string): string;
|
|
81
|
+
export declare function mcpSupportedModeLabels(serverName: string): string[];
|
|
82
|
+
export declare function modeAlias(mode: string): string;
|
package/dist/src/stack.js
CHANGED
|
@@ -142,7 +142,26 @@ export const AGENT_STACK = {
|
|
|
142
142
|
recommended_env: [],
|
|
143
143
|
local_service: "",
|
|
144
144
|
smoke_test: "For a computer science project, search one CS query, download one known paper, and read it locally.",
|
|
145
|
-
risks: "Respect arXiv rate limits; paper text is untrusted input."
|
|
145
|
+
risks: "Respect arXiv rate limits; paper text is untrusted input.",
|
|
146
|
+
default_mode: "local",
|
|
147
|
+
recommended_mode: "local",
|
|
148
|
+
modes: {
|
|
149
|
+
local: {
|
|
150
|
+
connection_mode: "stdio-local"
|
|
151
|
+
},
|
|
152
|
+
"remote-custom": {
|
|
153
|
+
connection_mode: "remote-custom",
|
|
154
|
+
execution_mode: "remote-custom",
|
|
155
|
+
install_command: "",
|
|
156
|
+
uninstall_command: "",
|
|
157
|
+
setup_commands: [],
|
|
158
|
+
command: "",
|
|
159
|
+
args: [],
|
|
160
|
+
env: {},
|
|
161
|
+
required_env: [],
|
|
162
|
+
recommended_env: []
|
|
163
|
+
}
|
|
164
|
+
}
|
|
146
165
|
},
|
|
147
166
|
"semantic-scholar": {
|
|
148
167
|
readiness: "credential-recommended",
|
|
@@ -161,7 +180,26 @@ export const AGENT_STACK = {
|
|
|
161
180
|
recommended_env: ["SEMANTIC_SCHOLAR_API_KEY"],
|
|
162
181
|
smoke_test: "Search one known title, then fetch citations or references.",
|
|
163
182
|
local_service: "",
|
|
164
|
-
risks: "API key recommended for sustained work and to avoid shared-pool rate limits; metadata can be incomplete."
|
|
183
|
+
risks: "API key recommended for sustained work and to avoid shared-pool rate limits; metadata can be incomplete.",
|
|
184
|
+
default_mode: "local",
|
|
185
|
+
recommended_mode: "local",
|
|
186
|
+
modes: {
|
|
187
|
+
local: {
|
|
188
|
+
connection_mode: "stdio-local"
|
|
189
|
+
},
|
|
190
|
+
"remote-custom": {
|
|
191
|
+
connection_mode: "remote-custom",
|
|
192
|
+
execution_mode: "remote-custom",
|
|
193
|
+
install_command: "",
|
|
194
|
+
uninstall_command: "",
|
|
195
|
+
setup_commands: [],
|
|
196
|
+
command: "",
|
|
197
|
+
args: [],
|
|
198
|
+
env: {},
|
|
199
|
+
required_env: [],
|
|
200
|
+
recommended_env: []
|
|
201
|
+
}
|
|
202
|
+
}
|
|
165
203
|
},
|
|
166
204
|
openalex: {
|
|
167
205
|
readiness: "credential-required",
|
|
@@ -169,7 +207,7 @@ export const AGENT_STACK = {
|
|
|
169
207
|
execution_mode: "npx-runtime",
|
|
170
208
|
source_need: "OpenAlex broad scholarly graph.",
|
|
171
209
|
source: "cyanheads/openalex-mcp-server",
|
|
172
|
-
hosted_url: "
|
|
210
|
+
hosted_url: "",
|
|
173
211
|
install_command: "",
|
|
174
212
|
uninstall_command: "",
|
|
175
213
|
setup_commands: [],
|
|
@@ -180,7 +218,44 @@ export const AGENT_STACK = {
|
|
|
180
218
|
recommended_env: [],
|
|
181
219
|
local_service: "",
|
|
182
220
|
smoke_test: "Search works by title or DOI and confirm stable OpenAlex IDs.",
|
|
183
|
-
risks: "The selected local server requires OPENALEX_API_KEY. OpenAlex keys are free and include a free daily quota; check current credit limits, smoke-test coverage, and inspect cost headers before high-volume work."
|
|
221
|
+
risks: "The selected local server requires OPENALEX_API_KEY. OpenAlex keys are free and include a free daily quota; check current credit limits, smoke-test coverage, and inspect cost headers before high-volume work.",
|
|
222
|
+
default_mode: "local",
|
|
223
|
+
recommended_mode: "remote",
|
|
224
|
+
modes: {
|
|
225
|
+
local: {
|
|
226
|
+
connection_mode: "stdio-local"
|
|
227
|
+
},
|
|
228
|
+
remote: {
|
|
229
|
+
connection_mode: "remote-curated",
|
|
230
|
+
execution_mode: "remote-curated",
|
|
231
|
+
hosted_url: "https://openalex.caseyjhand.com/mcp",
|
|
232
|
+
install_command: "",
|
|
233
|
+
uninstall_command: "",
|
|
234
|
+
setup_commands: [],
|
|
235
|
+
command: "",
|
|
236
|
+
args: [],
|
|
237
|
+
env: {},
|
|
238
|
+
required_env: [],
|
|
239
|
+
recommended_env: [],
|
|
240
|
+
smoke_test: "Connect the MCP client to the hosted streamable HTTP endpoint and run a read-only works search.",
|
|
241
|
+
risks: "Hosted endpoint behavior, authentication, rate limits, and availability are controlled by the endpoint operator; verify current policy before sustained use."
|
|
242
|
+
},
|
|
243
|
+
"remote-custom": {
|
|
244
|
+
connection_mode: "remote-custom",
|
|
245
|
+
execution_mode: "remote-custom",
|
|
246
|
+
hosted_url: "",
|
|
247
|
+
install_command: "",
|
|
248
|
+
uninstall_command: "",
|
|
249
|
+
setup_commands: [],
|
|
250
|
+
command: "",
|
|
251
|
+
args: [],
|
|
252
|
+
env: {},
|
|
253
|
+
required_env: [],
|
|
254
|
+
recommended_env: [],
|
|
255
|
+
smoke_test: "Connect the MCP client to the custom streamable HTTP endpoint and run a read-only works search.",
|
|
256
|
+
risks: "Custom endpoint behavior, authentication, rate limits, and availability are controlled by the endpoint operator; verify current policy before sustained use."
|
|
257
|
+
}
|
|
258
|
+
}
|
|
184
259
|
},
|
|
185
260
|
crossref: {
|
|
186
261
|
readiness: "manual",
|
|
@@ -199,7 +274,14 @@ export const AGENT_STACK = {
|
|
|
199
274
|
recommended_env: [],
|
|
200
275
|
local_service: "",
|
|
201
276
|
smoke_test: "Resolve one DOI into publication metadata after choosing a maintained local server.",
|
|
202
|
-
risks: "Manual integration only; current zero-friction Crossref-only MCP candidates are less mature than arXiv, DBLP, PubMed, or OpenAlex."
|
|
277
|
+
risks: "Manual integration only; current zero-friction Crossref-only MCP candidates are less mature than arXiv, DBLP, PubMed, or OpenAlex.",
|
|
278
|
+
default_mode: "manual",
|
|
279
|
+
recommended_mode: "manual",
|
|
280
|
+
modes: {
|
|
281
|
+
manual: {
|
|
282
|
+
connection_mode: "manual"
|
|
283
|
+
}
|
|
284
|
+
}
|
|
203
285
|
},
|
|
204
286
|
pubmed: {
|
|
205
287
|
readiness: "domain-specific",
|
|
@@ -207,7 +289,7 @@ export const AGENT_STACK = {
|
|
|
207
289
|
execution_mode: "npx-runtime",
|
|
208
290
|
source_need: "PubMed and biomedical literature.",
|
|
209
291
|
source: "cyanheads/pubmed-mcp-server",
|
|
210
|
-
hosted_url: "
|
|
292
|
+
hosted_url: "",
|
|
211
293
|
install_command: "",
|
|
212
294
|
uninstall_command: "",
|
|
213
295
|
setup_commands: [],
|
|
@@ -218,7 +300,44 @@ export const AGENT_STACK = {
|
|
|
218
300
|
recommended_env: ["NCBI_API_KEY", "NCBI_ADMIN_EMAIL"],
|
|
219
301
|
local_service: "",
|
|
220
302
|
smoke_test: "Search one PMID or title and fetch metadata.",
|
|
221
|
-
risks: "Domain-specific; observe NCBI rate limits. API key and contact email improve reliability."
|
|
303
|
+
risks: "Domain-specific; observe NCBI rate limits. API key and contact email improve reliability.",
|
|
304
|
+
default_mode: "local",
|
|
305
|
+
recommended_mode: "remote",
|
|
306
|
+
modes: {
|
|
307
|
+
local: {
|
|
308
|
+
connection_mode: "stdio-local"
|
|
309
|
+
},
|
|
310
|
+
remote: {
|
|
311
|
+
connection_mode: "remote-curated",
|
|
312
|
+
execution_mode: "remote-curated",
|
|
313
|
+
hosted_url: "https://pubmed.caseyjhand.com/mcp",
|
|
314
|
+
install_command: "",
|
|
315
|
+
uninstall_command: "",
|
|
316
|
+
setup_commands: [],
|
|
317
|
+
command: "",
|
|
318
|
+
args: [],
|
|
319
|
+
env: {},
|
|
320
|
+
required_env: [],
|
|
321
|
+
recommended_env: [],
|
|
322
|
+
smoke_test: "Connect the MCP client to the hosted streamable HTTP endpoint and run a read-only PubMed search.",
|
|
323
|
+
risks: "Hosted endpoint behavior, authentication, NCBI policy handling, and availability are controlled by the endpoint operator; verify current policy before sustained use."
|
|
324
|
+
},
|
|
325
|
+
"remote-custom": {
|
|
326
|
+
connection_mode: "remote-custom",
|
|
327
|
+
execution_mode: "remote-custom",
|
|
328
|
+
hosted_url: "",
|
|
329
|
+
install_command: "",
|
|
330
|
+
uninstall_command: "",
|
|
331
|
+
setup_commands: [],
|
|
332
|
+
command: "",
|
|
333
|
+
args: [],
|
|
334
|
+
env: {},
|
|
335
|
+
required_env: [],
|
|
336
|
+
recommended_env: [],
|
|
337
|
+
smoke_test: "Connect the MCP client to the custom streamable HTTP endpoint and run a read-only PubMed search.",
|
|
338
|
+
risks: "Custom endpoint behavior, authentication, NCBI policy handling, and availability are controlled by the endpoint operator; verify current policy before sustained use."
|
|
339
|
+
}
|
|
340
|
+
}
|
|
222
341
|
},
|
|
223
342
|
dblp: {
|
|
224
343
|
readiness: "low-friction-cs",
|
|
@@ -237,7 +356,26 @@ export const AGENT_STACK = {
|
|
|
237
356
|
recommended_env: [],
|
|
238
357
|
local_service: "",
|
|
239
358
|
smoke_test: "Search one known CS paper title and export or inspect its DBLP BibTeX.",
|
|
240
|
-
risks: "CS-specific metadata source; use with arXiv/Semantic Scholar/OpenAlex for coverage beyond DBLP."
|
|
359
|
+
risks: "CS-specific metadata source; use with arXiv/Semantic Scholar/OpenAlex for coverage beyond DBLP.",
|
|
360
|
+
default_mode: "local",
|
|
361
|
+
recommended_mode: "local",
|
|
362
|
+
modes: {
|
|
363
|
+
local: {
|
|
364
|
+
connection_mode: "stdio-local"
|
|
365
|
+
},
|
|
366
|
+
"remote-custom": {
|
|
367
|
+
connection_mode: "remote-custom",
|
|
368
|
+
execution_mode: "remote-custom",
|
|
369
|
+
install_command: "",
|
|
370
|
+
uninstall_command: "",
|
|
371
|
+
setup_commands: [],
|
|
372
|
+
command: "",
|
|
373
|
+
args: [],
|
|
374
|
+
env: {},
|
|
375
|
+
required_env: [],
|
|
376
|
+
recommended_env: []
|
|
377
|
+
}
|
|
378
|
+
}
|
|
241
379
|
},
|
|
242
380
|
zotero: {
|
|
243
381
|
readiness: "local-service",
|
|
@@ -256,7 +394,14 @@ export const AGENT_STACK = {
|
|
|
256
394
|
recommended_env: [],
|
|
257
395
|
local_service: "Zotero desktop running with local API enabled; Zoty Bridge required for attachment and collection write operations.",
|
|
258
396
|
smoke_test: "List collections, search one known item, and export BibTeX.",
|
|
259
|
-
risks: "Requires Zotero local API and bridge setup."
|
|
397
|
+
risks: "Requires Zotero local API and bridge setup.",
|
|
398
|
+
default_mode: "local",
|
|
399
|
+
recommended_mode: "local",
|
|
400
|
+
modes: {
|
|
401
|
+
local: {
|
|
402
|
+
connection_mode: "local-service"
|
|
403
|
+
}
|
|
404
|
+
}
|
|
260
405
|
},
|
|
261
406
|
overleaf: {
|
|
262
407
|
readiness: "manual-credentialed",
|
|
@@ -268,14 +413,21 @@ export const AGENT_STACK = {
|
|
|
268
413
|
install_command: "",
|
|
269
414
|
uninstall_command: "",
|
|
270
415
|
setup_commands: [],
|
|
271
|
-
command: "",
|
|
416
|
+
command: ".academic-research/mcp/overleaf/run-overleaf-mcp.sh",
|
|
272
417
|
args: [],
|
|
273
418
|
env: {},
|
|
274
|
-
required_env: ["OVERLEAF_TOKEN"],
|
|
275
|
-
recommended_env: [
|
|
419
|
+
required_env: ["OVERLEAF_TOKEN", "PROJECT_ID"],
|
|
420
|
+
recommended_env: [],
|
|
276
421
|
local_service: "Local clone of the Overleaf MCP server configured with uv and an Overleaf project that supports Git sync.",
|
|
277
422
|
smoke_test: "List projects or read one .tex file; do not write by default.",
|
|
278
|
-
risks: "Requires token and project setup; write/push access needs explicit approval."
|
|
423
|
+
risks: "Requires token and project setup; write/push access needs explicit approval.",
|
|
424
|
+
default_mode: "local",
|
|
425
|
+
recommended_mode: "local",
|
|
426
|
+
modes: {
|
|
427
|
+
local: {
|
|
428
|
+
connection_mode: "manual-local"
|
|
429
|
+
}
|
|
430
|
+
}
|
|
279
431
|
},
|
|
280
432
|
"paper-search": {
|
|
281
433
|
readiness: "fallback",
|
|
@@ -297,7 +449,14 @@ export const AGENT_STACK = {
|
|
|
297
449
|
],
|
|
298
450
|
local_service: "Manual review required before enabling; configure only permitted sources.",
|
|
299
451
|
smoke_test: "Search one harmless query with a source allow-list and verify provenance for each result.",
|
|
300
|
-
risks: "Powerful aggregator with optional restricted-source workflows; keep Sci-Hub or questionable download features disabled unless explicitly accepted."
|
|
452
|
+
risks: "Powerful aggregator with optional restricted-source workflows; keep Sci-Hub or questionable download features disabled unless explicitly accepted.",
|
|
453
|
+
default_mode: "manual",
|
|
454
|
+
recommended_mode: "manual",
|
|
455
|
+
modes: {
|
|
456
|
+
manual: {
|
|
457
|
+
connection_mode: "manual"
|
|
458
|
+
}
|
|
459
|
+
}
|
|
301
460
|
}
|
|
302
461
|
}
|
|
303
462
|
};
|
|
@@ -307,3 +466,90 @@ export function presetMcpServers(preset) {
|
|
|
307
466
|
throw new Error(`unknown capability preset: ${preset}`);
|
|
308
467
|
return [...config.mcp_servers];
|
|
309
468
|
}
|
|
469
|
+
export function resolveMcpServer(serverName, mode) {
|
|
470
|
+
const server = AGENT_STACK.mcp_servers[serverName];
|
|
471
|
+
if (!server)
|
|
472
|
+
throw new Error(`unknown MCP server: ${serverName}`);
|
|
473
|
+
const selectedMode = normalizeMcpMode(serverName, mode);
|
|
474
|
+
const variant = server.modes?.[selectedMode];
|
|
475
|
+
return {
|
|
476
|
+
...server,
|
|
477
|
+
...variant,
|
|
478
|
+
selected_mode: selectedMode,
|
|
479
|
+
connection_mode: variant?.connection_mode ?? defaultConnectionMode(server.execution_mode)
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
export function normalizeMcpMode(serverName, mode) {
|
|
483
|
+
const server = AGENT_STACK.mcp_servers[serverName];
|
|
484
|
+
if (!server)
|
|
485
|
+
throw new Error(`unknown MCP server: ${serverName}`);
|
|
486
|
+
const defaultMode = server.default_mode ?? "local";
|
|
487
|
+
if (!mode)
|
|
488
|
+
return defaultMode;
|
|
489
|
+
const normalized = modeAlias(mode);
|
|
490
|
+
if (server.modes?.[normalized])
|
|
491
|
+
return normalized;
|
|
492
|
+
if (!server.modes && normalized === defaultMode)
|
|
493
|
+
return defaultMode;
|
|
494
|
+
throw new Error(`${serverName} does not support MCP mode ${mode}. Supported modes: ${mcpServerModeKeys(serverName).join(", ")}`);
|
|
495
|
+
}
|
|
496
|
+
export function mcpServerModeKeys(serverName) {
|
|
497
|
+
const server = AGENT_STACK.mcp_servers[serverName];
|
|
498
|
+
if (!server)
|
|
499
|
+
throw new Error(`unknown MCP server: ${serverName}`);
|
|
500
|
+
return Object.keys(server.modes ?? { [server.default_mode ?? "local"]: { connection_mode: defaultConnectionMode(server.execution_mode) } });
|
|
501
|
+
}
|
|
502
|
+
export function mcpRecommendedMode(serverName) {
|
|
503
|
+
const server = AGENT_STACK.mcp_servers[serverName];
|
|
504
|
+
if (!server)
|
|
505
|
+
throw new Error(`unknown MCP server: ${serverName}`);
|
|
506
|
+
return normalizeMcpMode(serverName, server.recommended_mode ?? server.default_mode);
|
|
507
|
+
}
|
|
508
|
+
export function mcpModeLabel(serverName, mode) {
|
|
509
|
+
const server = resolveMcpServer(serverName, mode);
|
|
510
|
+
if (server.selected_mode === "remote-custom")
|
|
511
|
+
return "custom remote";
|
|
512
|
+
if (server.connection_mode === "remote-curated")
|
|
513
|
+
return "remote";
|
|
514
|
+
if (server.connection_mode === "remote-custom")
|
|
515
|
+
return "custom remote";
|
|
516
|
+
if (server.connection_mode === "local-service")
|
|
517
|
+
return "requires local app";
|
|
518
|
+
if (server.connection_mode === "manual-local")
|
|
519
|
+
return "manual setup";
|
|
520
|
+
if (server.connection_mode === "manual")
|
|
521
|
+
return "manual setup";
|
|
522
|
+
return "local";
|
|
523
|
+
}
|
|
524
|
+
export function mcpModeKeyLabel(mode) {
|
|
525
|
+
if (mode === "remote-custom")
|
|
526
|
+
return "custom remote";
|
|
527
|
+
if (mode === "remote" || mode === "remote-curated" || mode === "http-remote")
|
|
528
|
+
return "remote";
|
|
529
|
+
if (mode === "local-service")
|
|
530
|
+
return "requires local app";
|
|
531
|
+
if (mode === "manual-local" || mode === "manual")
|
|
532
|
+
return "manual setup";
|
|
533
|
+
return "local";
|
|
534
|
+
}
|
|
535
|
+
export function mcpSupportedModeLabels(serverName) {
|
|
536
|
+
return mcpServerModeKeys(serverName).map((mode) => mcpModeLabel(serverName, mode));
|
|
537
|
+
}
|
|
538
|
+
export function modeAlias(mode) {
|
|
539
|
+
if (mode === "stdio-local" || mode === "manual-local" || mode === "local-service")
|
|
540
|
+
return "local";
|
|
541
|
+
if (mode === "http-remote" || mode === "remote-curated" || mode === "curated-remote")
|
|
542
|
+
return "remote";
|
|
543
|
+
if (mode === "custom-remote")
|
|
544
|
+
return "remote-custom";
|
|
545
|
+
return mode;
|
|
546
|
+
}
|
|
547
|
+
function defaultConnectionMode(executionMode) {
|
|
548
|
+
if (executionMode === "uvx-runtime" || executionMode === "npx-runtime")
|
|
549
|
+
return "stdio-local";
|
|
550
|
+
if (executionMode === "local-service")
|
|
551
|
+
return "local-service";
|
|
552
|
+
if (executionMode === "manual-local")
|
|
553
|
+
return "manual-local";
|
|
554
|
+
return "manual";
|
|
555
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-academic-research",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Scaffold agent-ready academic research repositories with SOTA, source ledgers, wiki memory, MCP setup, and project-local skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
],
|
|
50
50
|
"scripts": {
|
|
51
51
|
"clean": "rm -rf dist",
|
|
52
|
-
"build": "npm run clean && tsc",
|
|
52
|
+
"build": "npm run clean && tsc && node scripts/chmod-bins.mjs",
|
|
53
53
|
"typecheck": "tsc --noEmit",
|
|
54
54
|
"test": "npm run build && node --test",
|
|
55
55
|
"lint": "npm run typecheck && node scripts/validate.mjs",
|
package/template/README.md
CHANGED
|
@@ -31,6 +31,7 @@ source .venv/bin/activate
|
|
|
31
31
|
python -m pip install --upgrade pip
|
|
32
32
|
python -m pip install -e ".[dev]"
|
|
33
33
|
npm run doctor
|
|
34
|
+
npm run update
|
|
34
35
|
```
|
|
35
36
|
|
|
36
37
|
## Core Folders
|
|
@@ -60,11 +61,17 @@ npm run skills:install -- --preset enhanced
|
|
|
60
61
|
npm run skills:install -- source-ingestion sota-literature-review
|
|
61
62
|
npm run skills:list
|
|
62
63
|
npm run skills:status
|
|
64
|
+
npm run update
|
|
63
65
|
npm run setup
|
|
64
66
|
npm run mcp:dotenv
|
|
65
67
|
npm run mcp:list
|
|
68
|
+
npm run mcp:modes
|
|
69
|
+
npm run mcp:status
|
|
66
70
|
npm run mcp:env -- openalex semantic-scholar zotero
|
|
71
|
+
npm run mcp:enable -- openalex --mode remote
|
|
67
72
|
npm run mcp:enable -- arxiv dblp
|
|
73
|
+
npm run mcp:setup -- overleaf --mode local --env-file .env.local
|
|
74
|
+
npm run mcp:client:add -- overleaf --agent codex --dry-run
|
|
68
75
|
npm run mcp:commands -- arxiv
|
|
69
76
|
npm run mcp:install -- arxiv
|
|
70
77
|
npm run mcp:smoke -- --env-file .env.local
|
|
@@ -73,13 +80,30 @@ npm run mcp:probe -- arxiv --timeout-ms 5000
|
|
|
73
80
|
```
|
|
74
81
|
|
|
75
82
|
`skills list` reports installed project-local skills. `skills presets` reports
|
|
76
|
-
available install presets. `mcp enable` changes project records
|
|
83
|
+
available install presets. `mcp enable` changes selected project records and
|
|
84
|
+
can record explicit modes such as `--mode remote`. Use `mcp modes` to see
|
|
85
|
+
which integrations support local, remote, custom remote, local-app, or manual
|
|
86
|
+
setup paths. `mcp status` separates selected records from setup, snippet,
|
|
87
|
+
client registration, and probe readiness; add `--verbose` for technical fields.
|
|
88
|
+
`mcp commands`
|
|
77
89
|
prints finite external install commands without running them. `mcp env` prints
|
|
78
90
|
env vars, hosted endpoints, local prerequisites, and setup commands before you
|
|
79
91
|
enable optional servers. `mcp install` runs only finite tool installation
|
|
80
92
|
commands; runtime-only `uvx`/`npx` MCP servers may have no install step and are
|
|
81
93
|
started later by the MCP client.
|
|
82
94
|
|
|
95
|
+
`npm run update` always uses `create-academic-research@latest` so older
|
|
96
|
+
projects can preview scaffold migrations with one command. It is a dry-run
|
|
97
|
+
unless you pass `-- --apply`; safe managed files are tracked in
|
|
98
|
+
`.academic-research/managed-files.json` and locally edited files are skipped
|
|
99
|
+
instead of overwritten. If this project was created before the latest update
|
|
100
|
+
script existed, run:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm exec --yes --package=create-academic-research@latest -- academic-research update --root .
|
|
104
|
+
npm exec --yes --package=create-academic-research@latest -- academic-research update --root . --apply
|
|
105
|
+
```
|
|
106
|
+
|
|
83
107
|
`.env.example` is the committed MCP environment reference. Regenerate it with
|
|
84
108
|
`npm run mcp:dotenv`. Copy it to `.env.local`, your shell profile, or your MCP
|
|
85
109
|
client secret store when secrets are needed. Filled `.env` files are ignored by
|
|
@@ -87,11 +111,20 @@ git. `mcp doctor` checks the current process environment unless you explicitly
|
|
|
87
111
|
pass `--env-file .env.local`.
|
|
88
112
|
|
|
89
113
|
`setup` prints the current project capability state, installed skill counts,
|
|
90
|
-
|
|
114
|
+
selected MCP records, and the next onboarding commands without changing files.
|
|
91
115
|
`mcp smoke` performs a non-launching MCP readiness check: it reports required
|
|
92
116
|
env vars, local/manual setup, and whether client runtime commands such as `uvx`
|
|
93
|
-
or `npx` are available. `mcp probe` is opt-in
|
|
94
|
-
|
|
117
|
+
or `npx` are available. `mcp probe` is opt-in: local stdio servers get a real
|
|
118
|
+
JSON-RPC handshake, while remote endpoints are reported as configured without a
|
|
119
|
+
network probe.
|
|
120
|
+
|
|
121
|
+
Overleaf setup creates a local wrapper under `.academic-research/mcp/` that
|
|
122
|
+
parses `.env.local` safely at runtime. The wrapper path and client/probe
|
|
123
|
+
observations are recorded in `docs/agent/capability-lock.json`; project-local
|
|
124
|
+
skill install/update/remove observations are recorded there too.
|
|
125
|
+
`configs/capabilities.yaml` is intended state, while the capability lock is
|
|
126
|
+
observed setup state. Token values are not stored there or in generated
|
|
127
|
+
snippets.
|
|
95
128
|
|
|
96
129
|
`default` installs the companion academic research skill package and keeps the
|
|
97
130
|
MCP records focused on low-friction arXiv discovery. `literature` and `full`
|
package/template/_gitignore
CHANGED
|
@@ -33,6 +33,7 @@ Do not commit filled `.env`, `.env.local`, tokens, cookies, or browser sessions.
|
|
|
33
33
|
environment unless you explicitly pass `--env-file .env.local`.
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
+
npm run mcp:status
|
|
36
37
|
npm run mcp:doctor -- --env-file .env.local
|
|
37
38
|
npm run mcp:smoke -- --env-file .env.local
|
|
38
39
|
npm run mcp:probe -- arxiv --timeout-ms 5000
|
|
@@ -54,14 +55,53 @@ client has its own secret store, prefer that store for API keys and tokens. If
|
|
|
54
55
|
the client inherits shell environment variables, start it from a shell where the
|
|
55
56
|
required variables are already exported.
|
|
56
57
|
|
|
58
|
+
Codex registration can be automated for servers with a generated command or
|
|
59
|
+
hosted URL:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm run mcp:client:add -- overleaf --agent codex
|
|
63
|
+
npm run mcp:client:remove -- overleaf --agent codex
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use `--dry-run` to print the exact `codex mcp add` or `codex mcp remove`
|
|
67
|
+
command without changing Codex config. Secrets are not written to Codex config;
|
|
68
|
+
credentialed local integrations should use a wrapper that loads `.env.local` at
|
|
69
|
+
runtime. Overleaf client registration is intentionally blocked until
|
|
70
|
+
`npm run mcp:setup -- overleaf --mode local --env-file .env.local` has created
|
|
71
|
+
the wrapper and recorded non-secret setup facts.
|
|
72
|
+
|
|
73
|
+
Custom remote endpoints may use a stored URL or a URL env var name. Bearer token
|
|
74
|
+
support stores only the token env var name. Codex automatic registration
|
|
75
|
+
supports stored URL mode because Codex has `--url`:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm run mcp:enable -- openalex --mode remote-custom --url https://example.com/mcp --bearer-token-env-var OPENALEX_MCP_TOKEN
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If the endpoint URL is kept in an env var with `--url-env`, automatic Codex
|
|
82
|
+
registration is not available because the Codex CLI currently has no
|
|
83
|
+
`--url-env` option. Either re-enable the server with `--url <url>` if the
|
|
84
|
+
endpoint URL may be stored in Codex config, or manually register it from a shell
|
|
85
|
+
where the env var is set:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
codex mcp add openalex --url "$OPENALEX_MCP_URL"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Claude Code, Cursor, and other clients may still require manual registration.
|
|
92
|
+
Use `npm run mcp:status` to see whether the selected server has a generated
|
|
93
|
+
snippet, a supported client registration path, and the next setup action.
|
|
94
|
+
|
|
57
95
|
## Workflow
|
|
58
96
|
|
|
59
97
|
1. Enable only the MCP servers needed for the current research task.
|
|
60
98
|
2. Inspect prerequisites with `npm run mcp:env -- <server>`.
|
|
61
99
|
3. Put required secrets in the MCP client secret store, shell, or `.env.local`.
|
|
62
100
|
4. Run `npm run mcp:smoke -- --env-file .env.local`.
|
|
63
|
-
5. Run `npm run mcp:
|
|
101
|
+
5. Run `npm run mcp:status`.
|
|
102
|
+
6. Register the selected server with the active client, or load the generated
|
|
103
|
+
snippet manually.
|
|
104
|
+
7. Run `npm run mcp:probe -- <server>` only when you want to start
|
|
64
105
|
the server and verify a real stdio handshake.
|
|
65
|
-
|
|
66
|
-
7. Treat MCP output as retrieval metadata until it is ingested into repository
|
|
106
|
+
8. Treat MCP output as retrieval metadata until it is ingested into repository
|
|
67
107
|
source records.
|
|
@@ -10,3 +10,63 @@ with `npm run mcp:dotenv`.
|
|
|
10
10
|
Use `npm run mcp:doctor -- --env-file .env.local` when you want the CLI to read
|
|
11
11
|
an explicit local env file. Use `npm run mcp:probe -- <server>` only when you
|
|
12
12
|
want to start a selected MCP server and verify a real stdio handshake.
|
|
13
|
+
|
|
14
|
+
Use `npm run mcp:modes` to see what each integration supports. Use
|
|
15
|
+
`npm run mcp:status` to distinguish selected project records from operational
|
|
16
|
+
readiness. Default status uses friendly labels such as ready, not selected,
|
|
17
|
+
setup needed, missing env, probe needed, probe failed, local, remote, requires
|
|
18
|
+
local app, and manual setup.
|
|
19
|
+
Use `npm run mcp:status -- --verbose` when you need technical mode names,
|
|
20
|
+
snippet state, client registration state, and probe details.
|
|
21
|
+
|
|
22
|
+
`configs/capabilities.yaml` records intended project capability state.
|
|
23
|
+
`docs/agent/capability-lock.json` records non-secret observed setup facts for
|
|
24
|
+
MCP setup/client/probe actions and project-local skill operations. The scaffold
|
|
25
|
+
manifest at `.academic-research/managed-files.json` records non-secret
|
|
26
|
+
checksums used by `npm run update` to avoid overwriting local edits.
|
|
27
|
+
|
|
28
|
+
Mode labels:
|
|
29
|
+
|
|
30
|
+
- local: your machine runs the MCP server when the client needs it.
|
|
31
|
+
- remote: your client connects to an existing hosted MCP endpoint.
|
|
32
|
+
- custom remote: you provide the endpoint.
|
|
33
|
+
- requires local app: another app must be running, such as Zotero Desktop.
|
|
34
|
+
- manual setup: guided setup is required before client registration.
|
|
35
|
+
|
|
36
|
+
OpenAlex and PubMed support explicit local and remote modes:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm run mcp:enable -- openalex --mode remote
|
|
40
|
+
npm run mcp:enable -- pubmed --mode local
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Advanced custom remote endpoints are non-secret project facts. Store only the
|
|
44
|
+
URL or the env var name that contains the URL. Store token env var names, never
|
|
45
|
+
token values:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm run mcp:enable -- openalex --mode remote-custom --url https://example.com/mcp
|
|
49
|
+
npm run mcp:enable -- openalex --mode remote-custom --url-env OPENALEX_MCP_URL --bearer-token-env-var OPENALEX_MCP_TOKEN
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Codex automatic registration supports stored URL mode with `--url`. If the URL
|
|
53
|
+
is kept in an env var with `--url-env`, automatic Codex registration is not
|
|
54
|
+
available because the Codex CLI currently has no `--url-env` option. Manually
|
|
55
|
+
register from a shell where the env var is set, or re-enable with `--url <url>`
|
|
56
|
+
if the endpoint URL may be stored in Codex config.
|
|
57
|
+
|
|
58
|
+
`mcp smoke` checks custom remote URL env vars without launching a local server.
|
|
59
|
+
`mcp probe` does not perform network probes for remote endpoints; it reports a
|
|
60
|
+
remote configured status when the required endpoint configuration is present.
|
|
61
|
+
If you use `--mode remote-custom` without `--url` or `--url-env`, smoke and
|
|
62
|
+
probe report `missing-remote-url`.
|
|
63
|
+
|
|
64
|
+
Overleaf is a manual-local integration. Keep secrets in `.env.local`, then run
|
|
65
|
+
the setup command to create a local wrapper and non-secret capability lock:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm run mcp:env -- overleaf --dotenv
|
|
69
|
+
npm run mcp:setup -- overleaf --mode local --env-file .env.local
|
|
70
|
+
npm run mcp:client:add -- overleaf --agent codex --dry-run
|
|
71
|
+
npm run mcp:probe -- overleaf --env-file .env.local
|
|
72
|
+
```
|