@1medium/cli 1.3.0 → 1.3.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/package.json +1 -1
- package/src/api.js +4 -4
- package/src/mcp-server.js +80 -18
- package/src/session-state.js +105 -0
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const fetch = require("node-fetch");
|
|
4
|
-
const
|
|
4
|
+
const sessionState = require("./session-state");
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Get API base URL
|
|
8
8
|
*/
|
|
9
9
|
function getApiUrl() {
|
|
10
|
-
return
|
|
10
|
+
return sessionState.get("apiUrl") || "https://1medium.ai/api";
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Get auth token
|
|
15
15
|
*/
|
|
16
16
|
function getToken() {
|
|
17
|
-
const token =
|
|
17
|
+
const token = sessionState.get("token");
|
|
18
18
|
if (!token) {
|
|
19
19
|
throw new Error(
|
|
20
20
|
"No token configured. Run '1m login' to set your API token."
|
|
@@ -27,7 +27,7 @@ function getToken() {
|
|
|
27
27
|
* Get configured org ID (if any)
|
|
28
28
|
*/
|
|
29
29
|
function getOrgId() {
|
|
30
|
-
return
|
|
30
|
+
return sessionState.get("orgId") || null;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
package/src/mcp-server.js
CHANGED
|
@@ -8,7 +8,7 @@ const {
|
|
|
8
8
|
ListToolsRequestSchema,
|
|
9
9
|
} = require("@modelcontextprotocol/sdk/types.js");
|
|
10
10
|
const api = require("./api");
|
|
11
|
-
const
|
|
11
|
+
const sessionState = require("./session-state");
|
|
12
12
|
|
|
13
13
|
const server = new Server(
|
|
14
14
|
{
|
|
@@ -368,6 +368,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
368
368
|
required: ["id"],
|
|
369
369
|
},
|
|
370
370
|
},
|
|
371
|
+
{
|
|
372
|
+
name: "config_persist",
|
|
373
|
+
description: "Persist current session settings (org/space/project) to the config file. Use this when you want changes to apply to all Claude Code tabs and persist across restarts.",
|
|
374
|
+
inputSchema: {
|
|
375
|
+
type: "object",
|
|
376
|
+
properties: {},
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
name: "config_reset",
|
|
381
|
+
description: "Reset session to values from the config file. Use this to discard any org/space/project changes made in this session and reload from persistent config.",
|
|
382
|
+
inputSchema: {
|
|
383
|
+
type: "object",
|
|
384
|
+
properties: {},
|
|
385
|
+
},
|
|
386
|
+
},
|
|
371
387
|
],
|
|
372
388
|
};
|
|
373
389
|
});
|
|
@@ -377,7 +393,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
377
393
|
const { name, arguments: args } = request.params;
|
|
378
394
|
|
|
379
395
|
// Check if configured
|
|
380
|
-
const token =
|
|
396
|
+
const token = sessionState.get("token");
|
|
381
397
|
if (!token) {
|
|
382
398
|
return {
|
|
383
399
|
content: [
|
|
@@ -397,7 +413,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
397
413
|
case "org_list": {
|
|
398
414
|
result = await api.listOrgs();
|
|
399
415
|
const orgs = result.orgs || [];
|
|
400
|
-
const currentOrgId =
|
|
416
|
+
const currentOrgId = sessionState.get("orgId");
|
|
401
417
|
|
|
402
418
|
if (orgs.length === 0) {
|
|
403
419
|
return {
|
|
@@ -424,9 +440,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
424
440
|
}
|
|
425
441
|
|
|
426
442
|
case "org_set": {
|
|
427
|
-
|
|
443
|
+
sessionState.set("orgId", args.id);
|
|
428
444
|
if (args.name) {
|
|
429
|
-
|
|
445
|
+
sessionState.set("orgName", args.name);
|
|
430
446
|
}
|
|
431
447
|
return {
|
|
432
448
|
content: [
|
|
@@ -439,8 +455,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
439
455
|
}
|
|
440
456
|
|
|
441
457
|
case "org_get": {
|
|
442
|
-
const orgId =
|
|
443
|
-
const orgName =
|
|
458
|
+
const orgId = sessionState.get("orgId");
|
|
459
|
+
const orgName = sessionState.get("orgName");
|
|
444
460
|
|
|
445
461
|
if (!orgId) {
|
|
446
462
|
return {
|
|
@@ -460,7 +476,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
460
476
|
|
|
461
477
|
case "task_create": {
|
|
462
478
|
// Use provided project_id or fall back to configured default
|
|
463
|
-
const projectId = args.project_id ||
|
|
479
|
+
const projectId = args.project_id || sessionState.get("projectId") || null;
|
|
464
480
|
const payload = {
|
|
465
481
|
title: args.title,
|
|
466
482
|
body_md: args.body,
|
|
@@ -586,7 +602,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
586
602
|
case "space_list": {
|
|
587
603
|
result = await api.listSpaces();
|
|
588
604
|
const spaces = result.spaces || [];
|
|
589
|
-
const currentSpaceId =
|
|
605
|
+
const currentSpaceId = sessionState.get("spaceId");
|
|
590
606
|
|
|
591
607
|
if (spaces.length === 0) {
|
|
592
608
|
return {
|
|
@@ -612,9 +628,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
612
628
|
}
|
|
613
629
|
|
|
614
630
|
case "space_set": {
|
|
615
|
-
|
|
631
|
+
sessionState.set("spaceId", args.id);
|
|
616
632
|
if (args.name) {
|
|
617
|
-
|
|
633
|
+
sessionState.set("spaceName", args.name);
|
|
618
634
|
}
|
|
619
635
|
return {
|
|
620
636
|
content: [
|
|
@@ -627,8 +643,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
627
643
|
}
|
|
628
644
|
|
|
629
645
|
case "space_get": {
|
|
630
|
-
const spaceId =
|
|
631
|
-
const spaceName =
|
|
646
|
+
const spaceId = sessionState.get("spaceId");
|
|
647
|
+
const spaceName = sessionState.get("spaceName");
|
|
632
648
|
|
|
633
649
|
if (!spaceId) {
|
|
634
650
|
return {
|
|
@@ -652,7 +668,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
652
668
|
|
|
653
669
|
result = await api.listProjects(params);
|
|
654
670
|
const projects = result.projects || [];
|
|
655
|
-
const currentProjectId =
|
|
671
|
+
const currentProjectId = sessionState.get("projectId");
|
|
656
672
|
|
|
657
673
|
if (projects.length === 0) {
|
|
658
674
|
return {
|
|
@@ -682,9 +698,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
682
698
|
}
|
|
683
699
|
|
|
684
700
|
case "project_set": {
|
|
685
|
-
|
|
701
|
+
sessionState.set("projectId", args.id);
|
|
686
702
|
if (args.name) {
|
|
687
|
-
|
|
703
|
+
sessionState.set("projectName", args.name);
|
|
688
704
|
}
|
|
689
705
|
return {
|
|
690
706
|
content: [
|
|
@@ -697,8 +713,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
697
713
|
}
|
|
698
714
|
|
|
699
715
|
case "project_get": {
|
|
700
|
-
const projectId =
|
|
701
|
-
const projectName =
|
|
716
|
+
const projectId = sessionState.get("projectId");
|
|
717
|
+
const projectName = sessionState.get("projectName");
|
|
702
718
|
|
|
703
719
|
if (!projectId) {
|
|
704
720
|
return {
|
|
@@ -803,6 +819,52 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
803
819
|
};
|
|
804
820
|
}
|
|
805
821
|
|
|
822
|
+
case "config_persist": {
|
|
823
|
+
sessionState.persistSession();
|
|
824
|
+
const state = sessionState.getSessionState();
|
|
825
|
+
let text = "Session settings persisted to config file.";
|
|
826
|
+
if (state.orgName || state.orgId) {
|
|
827
|
+
text += `\n Org: ${state.orgName || state.orgId || "(none)"}`;
|
|
828
|
+
}
|
|
829
|
+
if (state.spaceName || state.spaceId) {
|
|
830
|
+
text += `\n Space: ${state.spaceName || state.spaceId || "(none)"}`;
|
|
831
|
+
}
|
|
832
|
+
if (state.projectName || state.projectId) {
|
|
833
|
+
text += `\n Project: ${state.projectName || state.projectId || "(none)"}`;
|
|
834
|
+
}
|
|
835
|
+
return {
|
|
836
|
+
content: [
|
|
837
|
+
{
|
|
838
|
+
type: "text",
|
|
839
|
+
text,
|
|
840
|
+
},
|
|
841
|
+
],
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
case "config_reset": {
|
|
846
|
+
sessionState.resetSession();
|
|
847
|
+
const state = sessionState.getSessionState();
|
|
848
|
+
let text = "Session reset from config file.";
|
|
849
|
+
if (state.orgName || state.orgId) {
|
|
850
|
+
text += `\n Org: ${state.orgName || state.orgId || "(none)"}`;
|
|
851
|
+
}
|
|
852
|
+
if (state.spaceName || state.spaceId) {
|
|
853
|
+
text += `\n Space: ${state.spaceName || state.spaceId || "(none)"}`;
|
|
854
|
+
}
|
|
855
|
+
if (state.projectName || state.projectId) {
|
|
856
|
+
text += `\n Project: ${state.projectName || state.projectId || "(none)"}`;
|
|
857
|
+
}
|
|
858
|
+
return {
|
|
859
|
+
content: [
|
|
860
|
+
{
|
|
861
|
+
type: "text",
|
|
862
|
+
text,
|
|
863
|
+
},
|
|
864
|
+
],
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
|
|
806
868
|
default:
|
|
807
869
|
return {
|
|
808
870
|
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Session-scoped state for MCP server
|
|
5
|
+
*
|
|
6
|
+
* This module wraps the persistent config with an in-memory layer for session-scoped keys.
|
|
7
|
+
* Multiple Claude Code tabs can run separate MCP server processes without affecting each other's
|
|
8
|
+
* org/space/project selections.
|
|
9
|
+
*
|
|
10
|
+
* Session-scoped keys (in-memory only):
|
|
11
|
+
* - orgId, orgName, spaceId, spaceName, projectId, projectName
|
|
12
|
+
*
|
|
13
|
+
* Persistent keys (always read/write from config file):
|
|
14
|
+
* - token, apiUrl
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const config = require("./config");
|
|
18
|
+
|
|
19
|
+
// Keys that are session-scoped (stored in memory, not persisted by default)
|
|
20
|
+
const SESSION_KEYS = [
|
|
21
|
+
"orgId",
|
|
22
|
+
"orgName",
|
|
23
|
+
"spaceId",
|
|
24
|
+
"spaceName",
|
|
25
|
+
"projectId",
|
|
26
|
+
"projectName",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
// In-memory session state, initialized from config
|
|
30
|
+
const sessionState = {};
|
|
31
|
+
|
|
32
|
+
// Initialize session state from config on module load
|
|
33
|
+
for (const key of SESSION_KEYS) {
|
|
34
|
+
sessionState[key] = config.get(key);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get a config value
|
|
39
|
+
* Session-scoped keys return from memory; others fall through to persistent config
|
|
40
|
+
*/
|
|
41
|
+
function get(key) {
|
|
42
|
+
if (SESSION_KEYS.includes(key)) {
|
|
43
|
+
return sessionState[key];
|
|
44
|
+
}
|
|
45
|
+
return config.get(key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set a config value
|
|
50
|
+
* Session-scoped keys are stored in memory only; others persist to config file
|
|
51
|
+
*/
|
|
52
|
+
function set(key, value) {
|
|
53
|
+
if (SESSION_KEYS.includes(key)) {
|
|
54
|
+
sessionState[key] = value;
|
|
55
|
+
} else {
|
|
56
|
+
config.set(key, value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Persist current session state to the config file
|
|
62
|
+
* Call this to make session changes permanent across all Claude Code tabs
|
|
63
|
+
*/
|
|
64
|
+
function persistSession() {
|
|
65
|
+
for (const key of SESSION_KEYS) {
|
|
66
|
+
config.set(key, sessionState[key]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Reset session state from the config file
|
|
72
|
+
* Call this to discard session changes and reload from persistent config
|
|
73
|
+
*/
|
|
74
|
+
function resetSession() {
|
|
75
|
+
for (const key of SESSION_KEYS) {
|
|
76
|
+
sessionState[key] = config.get(key);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get the list of session-scoped keys
|
|
82
|
+
*/
|
|
83
|
+
function getSessionKeys() {
|
|
84
|
+
return [...SESSION_KEYS];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get all current session values (for debugging/display)
|
|
89
|
+
*/
|
|
90
|
+
function getSessionState() {
|
|
91
|
+
const state = {};
|
|
92
|
+
for (const key of SESSION_KEYS) {
|
|
93
|
+
state[key] = sessionState[key];
|
|
94
|
+
}
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = {
|
|
99
|
+
get,
|
|
100
|
+
set,
|
|
101
|
+
persistSession,
|
|
102
|
+
resetSession,
|
|
103
|
+
getSessionKeys,
|
|
104
|
+
getSessionState,
|
|
105
|
+
};
|