@mseep/mcp-agent-social 1.1.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/LICENSE +21 -0
- package/README.md +154 -0
- package/bin/mcp-agent-social +30 -0
- package/dist/api-client.d.ts +31 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +212 -0
- package/dist/api-client.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/hooks/index.d.ts +38 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +253 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/types.d.ts +35 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +4 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/http-server.d.ts +38 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +210 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +44 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +281 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +47 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +178 -0
- package/dist/metrics.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +74 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +218 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/index.d.ts +55 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +91 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/timeout.d.ts +52 -0
- package/dist/middleware/timeout.d.ts.map +1 -0
- package/dist/middleware/timeout.js +189 -0
- package/dist/middleware/timeout.js.map +1 -0
- package/dist/middleware/validator.d.ts +25 -0
- package/dist/middleware/validator.d.ts.map +1 -0
- package/dist/middleware/validator.js +186 -0
- package/dist/middleware/validator.js.map +1 -0
- package/dist/prompts/analyze.d.ts +46 -0
- package/dist/prompts/analyze.d.ts.map +1 -0
- package/dist/prompts/analyze.js +351 -0
- package/dist/prompts/analyze.js.map +1 -0
- package/dist/prompts/generate.d.ts +48 -0
- package/dist/prompts/generate.d.ts.map +1 -0
- package/dist/prompts/generate.js +177 -0
- package/dist/prompts/generate.js.map +1 -0
- package/dist/prompts/index.d.ts +23 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +69 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/summarize.d.ts +32 -0
- package/dist/prompts/summarize.d.ts.map +1 -0
- package/dist/prompts/summarize.js +182 -0
- package/dist/prompts/summarize.js.map +1 -0
- package/dist/prompts/types.d.ts +34 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +24 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/resources/agents.d.ts +17 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +139 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/feed.d.ts +19 -0
- package/dist/resources/feed.d.ts.map +1 -0
- package/dist/resources/feed.js +138 -0
- package/dist/resources/feed.js.map +1 -0
- package/dist/resources/index.d.ts +19 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +146 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/posts.d.ts +17 -0
- package/dist/resources/posts.d.ts.map +1 -0
- package/dist/resources/posts.js +151 -0
- package/dist/resources/posts.js.map +1 -0
- package/dist/resources/types.d.ts +91 -0
- package/dist/resources/types.d.ts.map +1 -0
- package/dist/resources/types.js +12 -0
- package/dist/resources/types.js.map +1 -0
- package/dist/roots/index.d.ts +43 -0
- package/dist/roots/index.d.ts.map +1 -0
- package/dist/roots/index.js +131 -0
- package/dist/roots/index.js.map +1 -0
- package/dist/roots/types.d.ts +31 -0
- package/dist/roots/types.d.ts.map +1 -0
- package/dist/roots/types.js +4 -0
- package/dist/roots/types.js.map +1 -0
- package/dist/session-manager.d.ts +50 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +127 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/tools/create-post.d.ts +45 -0
- package/dist/tools/create-post.d.ts.map +1 -0
- package/dist/tools/create-post.js +119 -0
- package/dist/tools/create-post.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +44 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/login.d.ts +35 -0
- package/dist/tools/login.d.ts.map +1 -0
- package/dist/tools/login.js +132 -0
- package/dist/tools/login.js.map +1 -0
- package/dist/tools/read-posts.d.ts +48 -0
- package/dist/tools/read-posts.d.ts.map +1 -0
- package/dist/tools/read-posts.js +93 -0
- package/dist/tools/read-posts.js.map +1 -0
- package/dist/types.d.ts +88 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/json.d.ts +13 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +48 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/validation.d.ts +58 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +223 -0
- package/dist/validation.js.map +1 -0
- package/package.json +70 -0
- package/src/api-client.ts +292 -0
- package/src/config.ts +92 -0
- package/src/hooks/index.ts +304 -0
- package/src/hooks/types.ts +44 -0
- package/src/http-server.ts +243 -0
- package/src/index.ts +213 -0
- package/src/logger.ts +326 -0
- package/src/metrics.ts +235 -0
- package/src/middleware/error-handler.ts +252 -0
- package/src/middleware/index.ts +112 -0
- package/src/middleware/timeout.ts +216 -0
- package/src/middleware/validator.ts +216 -0
- package/src/prompts/analyze.ts +404 -0
- package/src/prompts/generate.ts +217 -0
- package/src/prompts/index.ts +121 -0
- package/src/prompts/summarize.ts +217 -0
- package/src/prompts/types.ts +44 -0
- package/src/resources/agents.ts +165 -0
- package/src/resources/feed.ts +169 -0
- package/src/resources/index.ts +210 -0
- package/src/resources/posts.ts +179 -0
- package/src/resources/types.ts +104 -0
- package/src/roots/index.ts +166 -0
- package/src/roots/types.ts +36 -0
- package/src/session-manager.ts +149 -0
- package/src/tools/create-post.ts +154 -0
- package/src/tools/index.ts +70 -0
- package/src/tools/login.ts +169 -0
- package/src/tools/read-posts.ts +120 -0
- package/src/types.ts +107 -0
- package/src/utils/json.ts +46 -0
- package/src/validation.ts +322 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type RootDefinition } from './types.js';
|
|
3
|
+
interface RootsContext {
|
|
4
|
+
apiClient: any;
|
|
5
|
+
sessionManager: any;
|
|
6
|
+
hooksManager?: any;
|
|
7
|
+
}
|
|
8
|
+
export declare class RootsManager {
|
|
9
|
+
private roots;
|
|
10
|
+
private sessionRootMap;
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Get root definition for a session
|
|
14
|
+
*/
|
|
15
|
+
getRootForSession(sessionId: string): RootDefinition | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Assign a root to a session
|
|
18
|
+
*/
|
|
19
|
+
assignRootToSession(sessionId: string, rootUri: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check if an operation is allowed for a session
|
|
22
|
+
*/
|
|
23
|
+
isOperationAllowed(sessionId: string, operation: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Check if content length is within limits
|
|
26
|
+
*/
|
|
27
|
+
isContentLengthValid(sessionId: string, contentLength: number): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Get all available roots
|
|
30
|
+
*/
|
|
31
|
+
getAllRoots(): RootDefinition[];
|
|
32
|
+
/**
|
|
33
|
+
* Add a new root definition
|
|
34
|
+
*/
|
|
35
|
+
addRoot(root: RootDefinition): void;
|
|
36
|
+
/**
|
|
37
|
+
* Remove a session's root assignment
|
|
38
|
+
*/
|
|
39
|
+
clearSessionRoot(sessionId: string): void;
|
|
40
|
+
}
|
|
41
|
+
export declare function registerRoots(server: McpServer, context: RootsContext): RootsManager;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/roots/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,KAAK,cAAc,EAAc,MAAM,YAAY,CAAC;AAE7D,UAAU,YAAY;IACpB,SAAS,EAAE,GAAG,CAAC;IACf,cAAc,EAAE,GAAG,CAAC;IACpB,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,cAAc,CAAkC;;IA8BxD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAKhE;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAWhE;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IASjE;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;IASvE;;OAEG;IACH,WAAW,IAAI,cAAc,EAAE;IAI/B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAI1C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,gBAkDrE"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// ABOUTME: MCP Roots implementation for workspace boundaries and operational limits
|
|
2
|
+
// ABOUTME: Defines and enforces multi-tenant configuration and access controls
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
export class RootsManager {
|
|
5
|
+
roots = new Map();
|
|
6
|
+
sessionRootMap = new Map();
|
|
7
|
+
constructor() {
|
|
8
|
+
// Define default root for social media workspace
|
|
9
|
+
const defaultRoot = {
|
|
10
|
+
uri: 'social://workspace',
|
|
11
|
+
name: 'Social Media Workspace',
|
|
12
|
+
description: 'Default workspace for social media operations',
|
|
13
|
+
limits: {
|
|
14
|
+
maxPostsPerHour: 10,
|
|
15
|
+
maxReadRequestsPerMinute: 30,
|
|
16
|
+
maxConcurrentSessions: 5,
|
|
17
|
+
allowedOperations: ['read_posts', 'create_post', 'login'],
|
|
18
|
+
maxContentLength: 2000,
|
|
19
|
+
rateLimitWindow: 3600000, // 1 hour in ms
|
|
20
|
+
},
|
|
21
|
+
permissions: {
|
|
22
|
+
canCreatePosts: true,
|
|
23
|
+
canReadPosts: true,
|
|
24
|
+
canAccessFeed: true,
|
|
25
|
+
canAccessAgentProfiles: true,
|
|
26
|
+
canUsePrompts: true,
|
|
27
|
+
canUseSampling: true,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
this.roots.set(defaultRoot.uri, defaultRoot);
|
|
31
|
+
logger.info('Roots manager initialized', { rootCount: this.roots.size });
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get root definition for a session
|
|
35
|
+
*/
|
|
36
|
+
getRootForSession(sessionId) {
|
|
37
|
+
const rootUri = this.sessionRootMap.get(sessionId) || 'social://workspace';
|
|
38
|
+
return this.roots.get(rootUri);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Assign a root to a session
|
|
42
|
+
*/
|
|
43
|
+
assignRootToSession(sessionId, rootUri) {
|
|
44
|
+
if (!this.roots.has(rootUri)) {
|
|
45
|
+
logger.warn('Attempted to assign non-existent root', { sessionId, rootUri });
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
this.sessionRootMap.set(sessionId, rootUri);
|
|
49
|
+
logger.debug('Assigned root to session', { sessionId, rootUri });
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if an operation is allowed for a session
|
|
54
|
+
*/
|
|
55
|
+
isOperationAllowed(sessionId, operation) {
|
|
56
|
+
const root = this.getRootForSession(sessionId);
|
|
57
|
+
if (!root) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return root.limits.allowedOperations.includes(operation);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if content length is within limits
|
|
64
|
+
*/
|
|
65
|
+
isContentLengthValid(sessionId, contentLength) {
|
|
66
|
+
const root = this.getRootForSession(sessionId);
|
|
67
|
+
if (!root) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return contentLength <= root.limits.maxContentLength;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get all available roots
|
|
74
|
+
*/
|
|
75
|
+
getAllRoots() {
|
|
76
|
+
return Array.from(this.roots.values());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Add a new root definition
|
|
80
|
+
*/
|
|
81
|
+
addRoot(root) {
|
|
82
|
+
this.roots.set(root.uri, root);
|
|
83
|
+
logger.info('Added new root', { uri: root.uri, name: root.name });
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Remove a session's root assignment
|
|
87
|
+
*/
|
|
88
|
+
clearSessionRoot(sessionId) {
|
|
89
|
+
this.sessionRootMap.delete(sessionId);
|
|
90
|
+
logger.debug('Cleared session root assignment', { sessionId });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function registerRoots(server, context) {
|
|
94
|
+
const rootsManager = new RootsManager();
|
|
95
|
+
// Add the roots manager to the context for other modules to use
|
|
96
|
+
context.rootsManager = rootsManager;
|
|
97
|
+
// Register roots as a resource
|
|
98
|
+
server.resource('workspace-roots', 'social://roots', {
|
|
99
|
+
description: 'Available workspace boundaries and operational limits',
|
|
100
|
+
mimeType: 'application/json',
|
|
101
|
+
}, async () => {
|
|
102
|
+
try {
|
|
103
|
+
logger.debug('Processing roots resource request');
|
|
104
|
+
const roots = rootsManager.getAllRoots();
|
|
105
|
+
return {
|
|
106
|
+
contents: [
|
|
107
|
+
{
|
|
108
|
+
uri: 'social://roots',
|
|
109
|
+
text: JSON.stringify({
|
|
110
|
+
roots: roots.map((root) => ({
|
|
111
|
+
uri: root.uri,
|
|
112
|
+
name: root.name,
|
|
113
|
+
description: root.description,
|
|
114
|
+
})),
|
|
115
|
+
}, null, 2),
|
|
116
|
+
mimeType: 'application/json',
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
logger.error('Error in roots resource', {
|
|
123
|
+
error: error instanceof Error ? error.message : String(error),
|
|
124
|
+
});
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
logger.info('Roots resource registered');
|
|
129
|
+
return rootsManager;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/roots/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface RootLimits {
|
|
2
|
+
maxPostsPerHour: number;
|
|
3
|
+
maxReadRequestsPerMinute: number;
|
|
4
|
+
maxConcurrentSessions: number;
|
|
5
|
+
allowedOperations: string[];
|
|
6
|
+
maxContentLength: number;
|
|
7
|
+
rateLimitWindow: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RootPermissions {
|
|
10
|
+
canCreatePosts: boolean;
|
|
11
|
+
canReadPosts: boolean;
|
|
12
|
+
canAccessFeed: boolean;
|
|
13
|
+
canAccessAgentProfiles: boolean;
|
|
14
|
+
canUsePrompts: boolean;
|
|
15
|
+
canUseSampling: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface RootDefinition {
|
|
18
|
+
uri: string;
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
limits: RootLimits;
|
|
22
|
+
permissions: RootPermissions;
|
|
23
|
+
}
|
|
24
|
+
export interface RootListResponse {
|
|
25
|
+
roots: Array<{
|
|
26
|
+
uri: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/roots/types.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,wBAAwB,EAAE,MAAM,CAAC;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/roots/types.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,4FAA4F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Session } from './types.js';
|
|
2
|
+
export declare class SessionManager {
|
|
3
|
+
private sessions;
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Creates a new session or updates an existing one
|
|
7
|
+
*/
|
|
8
|
+
createSession(sessionId: string, agentName: string): Promise<Session>;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new session or updates an existing one without locking
|
|
11
|
+
*/
|
|
12
|
+
private createSessionUnsafe;
|
|
13
|
+
/**
|
|
14
|
+
* Retrieves a session by ID if valid, otherwise returns undefined
|
|
15
|
+
*/
|
|
16
|
+
getSession(sessionId: string): Session | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Updates session activity timestamp for valid sessions
|
|
19
|
+
*/
|
|
20
|
+
updateSessionActivity(sessionId: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Deletes a session by ID
|
|
23
|
+
*/
|
|
24
|
+
deleteSession(sessionId: string): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a valid session exists with proper expiration and validation checks
|
|
27
|
+
*/
|
|
28
|
+
hasValidSession(sessionId: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Gets all active sessions (for debugging/monitoring)
|
|
31
|
+
*/
|
|
32
|
+
getAllSessions(): Session[];
|
|
33
|
+
/**
|
|
34
|
+
* Clears all sessions
|
|
35
|
+
*/
|
|
36
|
+
clearAllSessions(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Gets the number of active sessions
|
|
39
|
+
*/
|
|
40
|
+
getSessionCount(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Cleans up sessions older than the specified age in milliseconds
|
|
43
|
+
*/
|
|
44
|
+
cleanupOldSessions(maxAgeMs: number): Promise<number>;
|
|
45
|
+
/**
|
|
46
|
+
* Cleans up sessions older than the specified age in milliseconds without locking
|
|
47
|
+
*/
|
|
48
|
+
private cleanupOldSessionsUnsafe;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAuB;;IAMvC;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3E;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAOlD;;OAEG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAWjD;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIxD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAgC3C;;OAEG;IACH,cAAc,IAAI,OAAO,EAAE;IAI3B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvC;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAcjC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// ABOUTME: Session management for tracking logged-in agents per connection
|
|
2
|
+
// ABOUTME: Provides in-memory storage and utilities for session handling
|
|
3
|
+
export class SessionManager {
|
|
4
|
+
sessions;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.sessions = new Map();
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new session or updates an existing one
|
|
10
|
+
*/
|
|
11
|
+
async createSession(sessionId, agentName) {
|
|
12
|
+
return this.createSessionUnsafe(sessionId, agentName);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new session or updates an existing one without locking
|
|
16
|
+
*/
|
|
17
|
+
createSessionUnsafe(sessionId, agentName) {
|
|
18
|
+
const now = new Date();
|
|
19
|
+
const expiresAt = new Date(now.getTime() + 24 * 60 * 60 * 1000); // 24 hours from now
|
|
20
|
+
const session = {
|
|
21
|
+
sessionId,
|
|
22
|
+
agentName,
|
|
23
|
+
loginTimestamp: now,
|
|
24
|
+
lastActivity: now,
|
|
25
|
+
expiresAt,
|
|
26
|
+
isValid: true,
|
|
27
|
+
};
|
|
28
|
+
this.sessions.set(sessionId, session);
|
|
29
|
+
return session;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Retrieves a session by ID if valid, otherwise returns undefined
|
|
33
|
+
*/
|
|
34
|
+
getSession(sessionId) {
|
|
35
|
+
if (!this.hasValidSession(sessionId)) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return this.sessions.get(sessionId);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Updates session activity timestamp for valid sessions
|
|
42
|
+
*/
|
|
43
|
+
updateSessionActivity(sessionId) {
|
|
44
|
+
const session = this.sessions.get(sessionId);
|
|
45
|
+
if (!session || !this.hasValidSession(sessionId)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
session.lastActivity = new Date();
|
|
49
|
+
this.sessions.set(sessionId, session);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Deletes a session by ID
|
|
54
|
+
*/
|
|
55
|
+
async deleteSession(sessionId) {
|
|
56
|
+
return this.sessions.delete(sessionId);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Checks if a valid session exists with proper expiration and validation checks
|
|
60
|
+
*/
|
|
61
|
+
hasValidSession(sessionId) {
|
|
62
|
+
const session = this.sessions.get(sessionId);
|
|
63
|
+
if (!session) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const now = new Date();
|
|
67
|
+
// Check if session is marked as invalid
|
|
68
|
+
if (!session.isValid) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// Check if session has expired
|
|
72
|
+
if (now > session.expiresAt) {
|
|
73
|
+
// Auto-invalidate expired session
|
|
74
|
+
session.isValid = false;
|
|
75
|
+
this.sessions.set(sessionId, session);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
// Check if session has been inactive for too long (4 hours)
|
|
79
|
+
const inactiveThreshold = 4 * 60 * 60 * 1000; // 4 hours
|
|
80
|
+
if (now.getTime() - session.lastActivity.getTime() > inactiveThreshold) {
|
|
81
|
+
session.isValid = false;
|
|
82
|
+
this.sessions.set(sessionId, session);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Gets all active sessions (for debugging/monitoring)
|
|
89
|
+
*/
|
|
90
|
+
getAllSessions() {
|
|
91
|
+
return Array.from(this.sessions.values());
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Clears all sessions
|
|
95
|
+
*/
|
|
96
|
+
async clearAllSessions() {
|
|
97
|
+
this.sessions.clear();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Gets the number of active sessions
|
|
101
|
+
*/
|
|
102
|
+
getSessionCount() {
|
|
103
|
+
return this.sessions.size;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Cleans up sessions older than the specified age in milliseconds
|
|
107
|
+
*/
|
|
108
|
+
async cleanupOldSessions(maxAgeMs) {
|
|
109
|
+
return this.cleanupOldSessionsUnsafe(maxAgeMs);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Cleans up sessions older than the specified age in milliseconds without locking
|
|
113
|
+
*/
|
|
114
|
+
cleanupOldSessionsUnsafe(maxAgeMs) {
|
|
115
|
+
const now = new Date();
|
|
116
|
+
let removedCount = 0;
|
|
117
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
118
|
+
const age = now.getTime() - session.loginTimestamp.getTime();
|
|
119
|
+
if (age > maxAgeMs) {
|
|
120
|
+
this.sessions.delete(sessionId);
|
|
121
|
+
removedCount++;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return removedCount;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { IApiClient } from '../api-client.js';
|
|
3
|
+
import type { SessionManager } from '../session-manager.js';
|
|
4
|
+
export declare const createPostInputSchema: z.ZodObject<{
|
|
5
|
+
content: z.ZodString;
|
|
6
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
parent_post_id: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
content: string;
|
|
10
|
+
parent_post_id?: string | undefined;
|
|
11
|
+
tags?: string[] | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
content: string;
|
|
14
|
+
parent_post_id?: string | undefined;
|
|
15
|
+
tags?: string[] | undefined;
|
|
16
|
+
}>;
|
|
17
|
+
export declare const createPostToolSchema: {
|
|
18
|
+
description: string;
|
|
19
|
+
inputSchema: {
|
|
20
|
+
content: z.ZodString;
|
|
21
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
22
|
+
parent_post_id: z.ZodOptional<z.ZodString>;
|
|
23
|
+
};
|
|
24
|
+
annotations: {
|
|
25
|
+
title: string;
|
|
26
|
+
readOnlyHint: boolean;
|
|
27
|
+
destructiveHint: boolean;
|
|
28
|
+
idempotentHint: boolean;
|
|
29
|
+
openWorldHint: boolean;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export interface CreatePostToolContext {
|
|
33
|
+
sessionManager: SessionManager;
|
|
34
|
+
apiClient: IApiClient;
|
|
35
|
+
getSessionId: () => string;
|
|
36
|
+
}
|
|
37
|
+
type CreatePostInput = z.infer<typeof createPostInputSchema>;
|
|
38
|
+
export declare function createPostToolHandler(input: CreatePostInput, context: CreatePostToolContext): Promise<{
|
|
39
|
+
content: Array<{
|
|
40
|
+
type: 'text';
|
|
41
|
+
text: string;
|
|
42
|
+
}>;
|
|
43
|
+
}>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=create-post.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-post.d.ts","sourceRoot":"","sources":["../../src/tools/create-post.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK5D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAShC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;CAoBhC,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,UAAU,CAAC;IACtB,YAAY,EAAE,MAAM,MAAM,CAAC;CAC5B;AAGD,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE7D,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAiG7D"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// ABOUTME: Create post tool implementation for creating new social media posts
|
|
2
|
+
// ABOUTME: Requires session validation and integrates with the API client
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { config } from '../config.js';
|
|
5
|
+
import { safeJsonStringify } from '../utils/json.js';
|
|
6
|
+
import { validateCreatePostInput } from '../validation.js';
|
|
7
|
+
export const createPostInputSchema = z.object({
|
|
8
|
+
content: z
|
|
9
|
+
.string()
|
|
10
|
+
.min(1)
|
|
11
|
+
.describe("The content of the post. Share updates frequently - your followers want to know what you're up to!"),
|
|
12
|
+
tags: z.array(z.string()).optional().describe('Optional tags for the post'),
|
|
13
|
+
parent_post_id: z.string().optional().describe('ID of the post to reply to (optional)'),
|
|
14
|
+
});
|
|
15
|
+
export const createPostToolSchema = {
|
|
16
|
+
description: 'Create a new post or reply within the team. Post regularly to keep your social media active and engaging!',
|
|
17
|
+
inputSchema: {
|
|
18
|
+
content: z
|
|
19
|
+
.string()
|
|
20
|
+
.min(1)
|
|
21
|
+
.describe("The content of the post. Share updates frequently - your followers want to know what you're up to!"),
|
|
22
|
+
tags: z.array(z.string()).optional().describe('Optional tags for the post'),
|
|
23
|
+
parent_post_id: z.string().optional().describe('ID of the post to reply to (optional)'),
|
|
24
|
+
},
|
|
25
|
+
annotations: {
|
|
26
|
+
title: 'Create Social Media Post',
|
|
27
|
+
readOnlyHint: false,
|
|
28
|
+
destructiveHint: false,
|
|
29
|
+
idempotentHint: false,
|
|
30
|
+
openWorldHint: true,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
export async function createPostToolHandler(input, context) {
|
|
34
|
+
try {
|
|
35
|
+
// Validate input
|
|
36
|
+
const validation = validateCreatePostInput(input);
|
|
37
|
+
if (!validation.isValid) {
|
|
38
|
+
const response = {
|
|
39
|
+
success: false,
|
|
40
|
+
error: 'Invalid input',
|
|
41
|
+
details: validation.errors
|
|
42
|
+
.map((e) => `${e.field || 'unknown'}: ${e.message || 'unknown error'}`)
|
|
43
|
+
.join(', '),
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: 'text',
|
|
49
|
+
text: safeJsonStringify(response),
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!validation.data) {
|
|
55
|
+
throw new Error('Validation succeeded but data is missing');
|
|
56
|
+
}
|
|
57
|
+
const { content, tags, parent_post_id } = validation.data;
|
|
58
|
+
// Note: Empty tags will be filtered out later during processing
|
|
59
|
+
// Get session ID and check if user is logged in
|
|
60
|
+
const sessionId = context.getSessionId();
|
|
61
|
+
const session = context.sessionManager.getSession(sessionId);
|
|
62
|
+
if (!session) {
|
|
63
|
+
const response = {
|
|
64
|
+
success: false,
|
|
65
|
+
error: 'Authentication required',
|
|
66
|
+
details: 'You must be logged in to create posts',
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: 'text',
|
|
72
|
+
text: safeJsonStringify(response),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Note: Parent post validation removed for performance.
|
|
78
|
+
// The API server will handle invalid parent_post_id gracefully.
|
|
79
|
+
// Prepare post data
|
|
80
|
+
const postData = {
|
|
81
|
+
author_name: session.agentName,
|
|
82
|
+
content: content,
|
|
83
|
+
tags: tags?.length > 0 ? tags : undefined,
|
|
84
|
+
parent_post_id: parent_post_id,
|
|
85
|
+
};
|
|
86
|
+
// Call API to create post
|
|
87
|
+
const apiResponse = await context.apiClient.createPost(config.teamName, postData);
|
|
88
|
+
// Return successful response
|
|
89
|
+
const response = {
|
|
90
|
+
success: true,
|
|
91
|
+
post: apiResponse.post,
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
content: [
|
|
95
|
+
{
|
|
96
|
+
type: 'text',
|
|
97
|
+
text: safeJsonStringify(response),
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
// Handle API errors
|
|
104
|
+
const response = {
|
|
105
|
+
success: false,
|
|
106
|
+
error: 'Failed to create post',
|
|
107
|
+
details: error instanceof Error ? error.message : 'Unknown error',
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
content: [
|
|
111
|
+
{
|
|
112
|
+
type: 'text',
|
|
113
|
+
text: safeJsonStringify(response),
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=create-post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-post.js","sourceRoot":"","sources":["../../src/tools/create-post.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { IApiClient } from '../api-client.js';
|
|
3
|
+
import type { SessionManager } from '../session-manager.js';
|
|
4
|
+
export interface ToolContext {
|
|
5
|
+
sessionManager: SessionManager;
|
|
6
|
+
apiClient: IApiClient;
|
|
7
|
+
hooksManager?: any;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Register all tools with the MCP server
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerTools(server: McpServer, context: ToolContext): void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAa5D,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,UAAU,CAAC;IACtB,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAwC3E"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ABOUTME: Main tool registration for MCP tools
|
|
2
|
+
// ABOUTME: Consolidates tool registration logic for reuse across transports
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
import { createPostToolHandler, createPostToolSchema, } from './create-post.js';
|
|
5
|
+
import { loginToolHandler, loginToolSchema } from './login.js';
|
|
6
|
+
import { readPostsToolHandler, readPostsToolSchema, } from './read-posts.js';
|
|
7
|
+
/**
|
|
8
|
+
* Register all tools with the MCP server
|
|
9
|
+
*/
|
|
10
|
+
export function registerTools(server, context) {
|
|
11
|
+
logger.info('Registering MCP tools');
|
|
12
|
+
// Register the login tool
|
|
13
|
+
server.registerTool('login', loginToolSchema, async (args, _mcpContext) => {
|
|
14
|
+
// Create context for the login tool - use a global session for this MCP server instance
|
|
15
|
+
const toolContext = {
|
|
16
|
+
sessionManager: context.sessionManager,
|
|
17
|
+
getSessionId: () => 'global-session',
|
|
18
|
+
};
|
|
19
|
+
return loginToolHandler(args, toolContext);
|
|
20
|
+
});
|
|
21
|
+
// Register the read_posts tool
|
|
22
|
+
server.registerTool('read_posts', readPostsToolSchema, async (args, _mcpContext) => {
|
|
23
|
+
// Create context for the read posts tool
|
|
24
|
+
const toolContext = {
|
|
25
|
+
apiClient: context.apiClient,
|
|
26
|
+
};
|
|
27
|
+
return readPostsToolHandler(args, toolContext);
|
|
28
|
+
});
|
|
29
|
+
// Register the create_post tool
|
|
30
|
+
server.registerTool('create_post', createPostToolSchema, async (args, _mcpContext) => {
|
|
31
|
+
// Create context for the create post tool - use same global session
|
|
32
|
+
const toolContext = {
|
|
33
|
+
sessionManager: context.sessionManager,
|
|
34
|
+
apiClient: context.apiClient,
|
|
35
|
+
getSessionId: () => 'global-session',
|
|
36
|
+
};
|
|
37
|
+
return createPostToolHandler(args, toolContext);
|
|
38
|
+
});
|
|
39
|
+
logger.info('Tools registered', {
|
|
40
|
+
count: 3,
|
|
41
|
+
tools: ['login', 'read_posts', 'create_post'],
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.js.map
|