workfullcircle-mcp-local 1.1.2 → 1.4.0
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/index.js +73 -195
- package/package.json +12 -4
- package/workfullcircle-mcp-local-1.0.0.tgz +0 -0
package/index.js
CHANGED
|
@@ -2,220 +2,98 @@
|
|
|
2
2
|
|
|
3
3
|
const fetch = require('node-fetch');
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
const
|
|
7
|
-
const API_KEY = process.env.WFC_API_KEY;
|
|
5
|
+
// Parse command line arguments
|
|
6
|
+
const args = process.argv.slice(2);
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
console.error('Error: WFC_API_KEY environment variable is required');
|
|
8
|
+
function printUsage() {
|
|
11
9
|
process.exit(1);
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
name: 'save_memory',
|
|
20
|
-
description: 'Save a memory to WorkFullCircle',
|
|
21
|
-
inputSchema: {
|
|
22
|
-
type: 'object',
|
|
23
|
-
properties: {
|
|
24
|
-
content: { type: 'string', description: 'Memory content to save' },
|
|
25
|
-
sector: { type: 'string', description: 'Memory sector (Semantic, Episodic, Procedural, Emotional, Reflective)' },
|
|
26
|
-
tags: { type: 'array', items: { type: 'string' }, description: 'Tags for the memory' }
|
|
27
|
-
},
|
|
28
|
-
required: ['content']
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'get_memory',
|
|
33
|
-
description: 'Retrieve memories from WorkFullCircle',
|
|
34
|
-
inputSchema: {
|
|
35
|
-
type: 'object',
|
|
36
|
-
properties: {
|
|
37
|
-
query: { type: 'string', description: 'Search query' },
|
|
38
|
-
limit: { type: 'number', description: 'Maximum number of results' },
|
|
39
|
-
sector: { type: 'string', description: 'Filter by sector' }
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'delete_memory',
|
|
45
|
-
description: 'Delete a memory from WorkFullCircle',
|
|
46
|
-
inputSchema: {
|
|
47
|
-
type: 'object',
|
|
48
|
-
properties: {
|
|
49
|
-
id: { type: 'string', description: 'Memory ID to delete' }
|
|
50
|
-
},
|
|
51
|
-
required: ['id']
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'update_memory',
|
|
56
|
-
description: 'Update a memory in WorkFullCircle',
|
|
57
|
-
inputSchema: {
|
|
58
|
-
type: 'object',
|
|
59
|
-
properties: {
|
|
60
|
-
id: { type: 'string', description: 'Memory ID to update' },
|
|
61
|
-
content: { type: 'string', description: 'Updated memory content' },
|
|
62
|
-
sector: { type: 'string', description: 'Updated memory sector' },
|
|
63
|
-
tags: { type: 'array', items: { type: 'string' }, description: 'Updated tags' }
|
|
64
|
-
},
|
|
65
|
-
required: ['id']
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: 'list_all_memories',
|
|
70
|
-
description: 'List all memories in WorkFullCircle',
|
|
71
|
-
inputSchema: {
|
|
72
|
-
type: 'object',
|
|
73
|
-
properties: {
|
|
74
|
-
limit: { type: 'number', description: 'Maximum number of results' },
|
|
75
|
-
offset: { type: 'number', description: 'Number of results to skip' }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
];
|
|
80
|
-
}
|
|
12
|
+
function parseArgs(argv) {
|
|
13
|
+
const parsed = {
|
|
14
|
+
token: null,
|
|
15
|
+
url: process.env.WFC_API_URL || 'https://workfullcircle.com'
|
|
16
|
+
};
|
|
81
17
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
capabilities: {
|
|
90
|
-
tools: {}
|
|
91
|
-
},
|
|
92
|
-
serverInfo: {
|
|
93
|
-
name: 'workfullcircle-mcp-local',
|
|
94
|
-
version: '1.0.0'
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Handle tools/list request
|
|
101
|
-
handleToolsList(request) {
|
|
102
|
-
return {
|
|
103
|
-
jsonrpc: '2.0',
|
|
104
|
-
id: request.id,
|
|
105
|
-
result: {
|
|
106
|
-
tools: this.tools
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Handle tools/call request
|
|
112
|
-
async handleToolsCall(request) {
|
|
113
|
-
const { name, arguments: args } = request.params;
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
const result = await this.callAPI(name, args);
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
jsonrpc: '2.0',
|
|
120
|
-
id: request.id,
|
|
121
|
-
result: {
|
|
122
|
-
content: [
|
|
123
|
-
{
|
|
124
|
-
type: 'text',
|
|
125
|
-
text: JSON.stringify(result, null, 2)
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
} catch (error) {
|
|
131
|
-
return {
|
|
132
|
-
jsonrpc: '2.0',
|
|
133
|
-
id: request.id,
|
|
134
|
-
error: {
|
|
135
|
-
code: -32603,
|
|
136
|
-
message: error.message
|
|
137
|
-
}
|
|
138
|
-
};
|
|
18
|
+
for (let i = 0; i < argv.length; i++) {
|
|
19
|
+
if (argv[i] === '--token') {
|
|
20
|
+
parsed.token = argv[i + 1];
|
|
21
|
+
i++;
|
|
22
|
+
} else if (argv[i] === '--url') {
|
|
23
|
+
parsed.url = argv[i + 1];
|
|
24
|
+
i++;
|
|
139
25
|
}
|
|
140
26
|
}
|
|
141
27
|
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const response = await fetch(endpoint, {
|
|
147
|
-
method: 'POST',
|
|
148
|
-
headers: {
|
|
149
|
-
'Content-Type': 'application/json',
|
|
150
|
-
'Authorization': `Bearer ${API_KEY}`
|
|
151
|
-
},
|
|
152
|
-
body: JSON.stringify(args)
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
if (!response.ok) {
|
|
156
|
-
const errorText = await response.text();
|
|
157
|
-
throw new Error(`API Error ${response.status}: ${errorText}`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return await response.json();
|
|
28
|
+
// Fallback to environment variable
|
|
29
|
+
if (!parsed.token) {
|
|
30
|
+
parsed.token = process.env.WFC_TOKEN;
|
|
161
31
|
}
|
|
162
32
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
switch (request.method) {
|
|
166
|
-
case 'initialize':
|
|
167
|
-
return this.handleInitialize(request);
|
|
168
|
-
case 'tools/list':
|
|
169
|
-
return this.handleToolsList(request);
|
|
170
|
-
case 'tools/call':
|
|
171
|
-
return await this.handleToolsCall(request);
|
|
172
|
-
default:
|
|
173
|
-
return {
|
|
174
|
-
jsonrpc: '2.0',
|
|
175
|
-
id: request.id,
|
|
176
|
-
error: {
|
|
177
|
-
code: -32601,
|
|
178
|
-
message: 'Method not found'
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
}
|
|
33
|
+
if (!parsed.token) {
|
|
34
|
+
printUsage();
|
|
182
35
|
}
|
|
36
|
+
|
|
37
|
+
return parsed;
|
|
183
38
|
}
|
|
184
39
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
40
|
+
const { token: API_TOKEN, url: API_URL } = parseArgs(args);
|
|
41
|
+
|
|
42
|
+
// Forward all MCP requests directly to the server's MCP endpoint
|
|
43
|
+
async function handleStdio() {
|
|
44
|
+
let inputBuffer = '';
|
|
189
45
|
process.stdin.setEncoding('utf8');
|
|
190
|
-
|
|
46
|
+
|
|
191
47
|
process.stdin.on('data', async (chunk) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
48
|
+
inputBuffer += chunk;
|
|
49
|
+
let newlineIndex;
|
|
50
|
+
|
|
51
|
+
while ((newlineIndex = inputBuffer.indexOf('\n')) !== -1) {
|
|
52
|
+
const line = inputBuffer.slice(0, newlineIndex).trim();
|
|
53
|
+
inputBuffer = inputBuffer.slice(newlineIndex + 1);
|
|
54
|
+
|
|
55
|
+
if (!line) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let payload;
|
|
197
60
|
try {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
61
|
+
payload = JSON.parse(line);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
// Forward the MCP request directly to the server
|
|
68
|
+
const response = await fetch(API_URL, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: {
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
'Authorization': `Bearer ${API_TOKEN}`
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify(payload)
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const responseText = await response.text();
|
|
78
|
+
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Validate response is valid JSON before outputting
|
|
84
|
+
try {
|
|
85
|
+
JSON.parse(responseText);
|
|
86
|
+
process.stdout.write(`${responseText}\n`);
|
|
87
|
+
} catch (jsonError) {
|
|
88
|
+
}
|
|
201
89
|
} catch (error) {
|
|
202
|
-
console.error('Error processing request:', error.message);
|
|
203
90
|
}
|
|
204
91
|
}
|
|
205
92
|
});
|
|
206
|
-
|
|
207
|
-
// Handle process termination
|
|
208
|
-
process.on('SIGINT', () => {
|
|
209
|
-
process.exit(0);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
process.on('SIGTERM', () => {
|
|
213
|
-
process.exit(0);
|
|
214
|
-
});
|
|
215
93
|
}
|
|
216
94
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
95
|
+
async function main() {
|
|
96
|
+
await handleStdio();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "workfullcircle-mcp-local",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Local STDIO MCP server for WorkFullCircle API",
|
|
4
|
+
"version": "1.4.0",
|
|
5
|
+
"description": "Local STDIO MCP server for WorkFullCircle API with Antigravity path fixes",
|
|
5
6
|
"main": "index.js",
|
|
6
7
|
"bin": {
|
|
7
8
|
"workfullcircle-mcp-local": "index.js"
|
|
@@ -17,7 +18,9 @@
|
|
|
17
18
|
"ai",
|
|
18
19
|
"memory",
|
|
19
20
|
"windsurf",
|
|
20
|
-
"antigravity"
|
|
21
|
+
"antigravity",
|
|
22
|
+
"path-fix",
|
|
23
|
+
"plug-and-play"
|
|
21
24
|
],
|
|
22
25
|
"author": "Afreensiyad",
|
|
23
26
|
"license": "MIT",
|
|
@@ -30,5 +33,10 @@
|
|
|
30
33
|
"publishConfig": {
|
|
31
34
|
"access": "public"
|
|
32
35
|
},
|
|
33
|
-
"homepage": "https://workfullcircle.com"
|
|
36
|
+
"homepage": "https://workfullcircle.com",
|
|
37
|
+
"files": [
|
|
38
|
+
"index.js",
|
|
39
|
+
"test.js",
|
|
40
|
+
"README.md"
|
|
41
|
+
]
|
|
34
42
|
}
|
|
Binary file
|