workfullcircle-mcp-local 1.1.2 → 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/index.js +83 -195
- package/package.json +12 -4
- package/workfullcircle-mcp-local-1.0.0.tgz +0 -0
package/index.js
CHANGED
|
@@ -2,220 +2,108 @@
|
|
|
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
|
-
|
|
8
|
+
function printUsage() {
|
|
9
|
+
process.stderr.write('Usage: workfullcircle-mcp-local --token <api-token> [--url <api-url>]\n');
|
|
10
|
+
process.stderr.write('Environment variables: WFC_API_URL (default: https://workfullcircle.com)\n');
|
|
11
11
|
process.exit(1);
|
|
12
12
|
}
|
|
13
13
|
|
|
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
|
-
}
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const parsed = {
|
|
16
|
+
token: null,
|
|
17
|
+
url: process.env.WFC_API_URL || 'https://workfullcircle.com'
|
|
18
|
+
};
|
|
81
19
|
|
|
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
|
-
};
|
|
20
|
+
for (let i = 0; i < argv.length; i++) {
|
|
21
|
+
if (argv[i] === '--token') {
|
|
22
|
+
parsed.token = argv[i + 1];
|
|
23
|
+
i++;
|
|
24
|
+
} else if (argv[i] === '--url') {
|
|
25
|
+
parsed.url = argv[i + 1];
|
|
26
|
+
i++;
|
|
139
27
|
}
|
|
140
28
|
}
|
|
141
29
|
|
|
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();
|
|
30
|
+
// Fallback to environment variable
|
|
31
|
+
if (!parsed.token) {
|
|
32
|
+
parsed.token = process.env.WFC_TOKEN;
|
|
161
33
|
}
|
|
162
34
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
}
|
|
35
|
+
if (!parsed.token) {
|
|
36
|
+
process.stderr.write('Error: --token argument or WFC_TOKEN environment variable is required\n');
|
|
37
|
+
printUsage();
|
|
182
38
|
}
|
|
39
|
+
|
|
40
|
+
return parsed;
|
|
183
41
|
}
|
|
184
42
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
43
|
+
const { token: API_TOKEN, url: API_URL } = parseArgs(args);
|
|
44
|
+
|
|
45
|
+
// Forward all MCP requests directly to the server's MCP endpoint
|
|
46
|
+
async function handleStdio() {
|
|
47
|
+
let inputBuffer = '';
|
|
189
48
|
process.stdin.setEncoding('utf8');
|
|
190
|
-
|
|
49
|
+
|
|
191
50
|
process.stdin.on('data', async (chunk) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
51
|
+
inputBuffer += chunk;
|
|
52
|
+
let newlineIndex;
|
|
53
|
+
|
|
54
|
+
while ((newlineIndex = inputBuffer.indexOf('\n')) !== -1) {
|
|
55
|
+
const line = inputBuffer.slice(0, newlineIndex).trim();
|
|
56
|
+
inputBuffer = inputBuffer.slice(newlineIndex + 1);
|
|
57
|
+
|
|
58
|
+
if (!line) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let payload;
|
|
197
63
|
try {
|
|
198
|
-
|
|
199
|
-
const response = await server.handleRequest(request);
|
|
200
|
-
process.stdout.write(JSON.stringify(response) + '\n');
|
|
64
|
+
payload = JSON.parse(line);
|
|
201
65
|
} catch (error) {
|
|
202
|
-
|
|
66
|
+
process.stderr.write(`[WFC-Local] Invalid JSON input: ${error.message}\n`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
// Forward the MCP request directly to the server
|
|
72
|
+
const response = await fetch(API_URL, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
'Authorization': `Bearer ${API_TOKEN}`
|
|
77
|
+
},
|
|
78
|
+
body: JSON.stringify(payload)
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const responseText = await response.text();
|
|
82
|
+
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
process.stderr.write(`[WFC-Local] Remote error ${response.status}: ${responseText}\n`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Validate response is valid JSON before outputting
|
|
89
|
+
try {
|
|
90
|
+
JSON.parse(responseText);
|
|
91
|
+
process.stdout.write(`${responseText}\n`);
|
|
92
|
+
} catch (jsonError) {
|
|
93
|
+
process.stderr.write(`[WFC-Local] Invalid JSON response: ${jsonError.message}\n`);
|
|
94
|
+
process.stderr.write(`[WFC-Local] Response was: ${responseText.substring(0, 200)}...\n`);
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
process.stderr.write(`[WFC-Local] Request failed: ${error.message}\n`);
|
|
203
98
|
}
|
|
204
99
|
}
|
|
205
100
|
});
|
|
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
101
|
}
|
|
216
102
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
103
|
+
async function main() {
|
|
104
|
+
process.stderr.write(`[WFC-Local] Connected to MCP server at ${API_URL}\n`);
|
|
105
|
+
process.stderr.write(`[WFC-Local] Using token: ${API_TOKEN.substring(0, 10)}...\n`);
|
|
106
|
+
await handleStdio();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
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.1
|
|
4
|
-
"description": "Local STDIO MCP server for WorkFullCircle API",
|
|
4
|
+
"version": "1.3.1",
|
|
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
|