@1mcp/agent 0.4.0 → 0.8.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.
Files changed (81) hide show
  1. package/README.md +57 -2
  2. package/build/capabilities/capabilityManager.d.ts +34 -0
  3. package/build/capabilities/capabilityManager.d.ts.map +1 -0
  4. package/build/capabilities/capabilityManager.js +13 -5
  5. package/build/capabilities/capabilityManager.js.map +1 -0
  6. package/build/client.d.ts +25 -0
  7. package/build/client.d.ts.map +1 -0
  8. package/build/client.js +3 -10
  9. package/build/client.js.map +1 -0
  10. package/build/clients/clientManager.d.ts +40 -0
  11. package/build/clients/clientManager.d.ts.map +1 -0
  12. package/build/clients/clientManager.js +45 -21
  13. package/build/clients/clientManager.js.map +1 -0
  14. package/build/config/configManager.d.ts +54 -0
  15. package/build/config/configManager.d.ts.map +1 -0
  16. package/build/config/configManager.js +1 -0
  17. package/build/config/configManager.js.map +1 -0
  18. package/build/config/transportConfig.d.ts +7 -0
  19. package/build/config/transportConfig.d.ts.map +1 -0
  20. package/build/config/transportConfig.js +1 -0
  21. package/build/config/transportConfig.js.map +1 -0
  22. package/build/constants.d.ts +43 -0
  23. package/build/constants.d.ts.map +1 -0
  24. package/build/constants.js +19 -4
  25. package/build/constants.js.map +1 -0
  26. package/build/handlers/notificationHandlers.d.ts +14 -0
  27. package/build/handlers/notificationHandlers.d.ts.map +1 -0
  28. package/build/handlers/notificationHandlers.js +1 -0
  29. package/build/handlers/notificationHandlers.js.map +1 -0
  30. package/build/handlers/requestHandlers.d.ts +10 -0
  31. package/build/handlers/requestHandlers.d.ts.map +1 -0
  32. package/build/handlers/requestHandlers.js +45 -30
  33. package/build/handlers/requestHandlers.js.map +1 -0
  34. package/build/index.d.ts +3 -0
  35. package/build/index.d.ts.map +1 -0
  36. package/build/index.js +6 -1
  37. package/build/index.js.map +1 -0
  38. package/build/logger/logger.d.ts +13 -0
  39. package/build/logger/logger.d.ts.map +1 -0
  40. package/build/logger/logger.js +7 -33
  41. package/build/logger/logger.js.map +1 -0
  42. package/build/middleware/loggingMiddleware.d.ts +6 -0
  43. package/build/middleware/loggingMiddleware.d.ts.map +1 -0
  44. package/build/middleware/loggingMiddleware.js +1 -0
  45. package/build/middleware/loggingMiddleware.js.map +1 -0
  46. package/build/server/expressServer.d.ts +10 -0
  47. package/build/server/expressServer.d.ts.map +1 -0
  48. package/build/server/expressServer.js +2 -11
  49. package/build/server/expressServer.js.map +1 -0
  50. package/build/server.d.ts +7 -0
  51. package/build/server.d.ts.map +1 -0
  52. package/build/server.js +1 -0
  53. package/build/server.js.map +1 -0
  54. package/build/serverManager.d.ts +25 -0
  55. package/build/serverManager.d.ts.map +1 -0
  56. package/build/serverManager.js +4 -2
  57. package/build/serverManager.js.map +1 -0
  58. package/build/services/configReloadService.d.ts +37 -0
  59. package/build/services/configReloadService.d.ts.map +1 -0
  60. package/build/services/configReloadService.js +1 -0
  61. package/build/services/configReloadService.js.map +1 -0
  62. package/build/types.d.ts +129 -0
  63. package/build/types.d.ts.map +1 -0
  64. package/build/types.js +1 -0
  65. package/build/types.js.map +1 -0
  66. package/build/utils/clientFiltering.d.ts +37 -0
  67. package/build/utils/clientFiltering.d.ts.map +1 -0
  68. package/build/utils/clientFiltering.js +73 -0
  69. package/build/utils/clientFiltering.js.map +1 -0
  70. package/build/utils/errorHandling.d.ts +62 -0
  71. package/build/utils/errorHandling.d.ts.map +1 -0
  72. package/build/utils/errorHandling.js +1 -0
  73. package/build/utils/errorHandling.js.map +1 -0
  74. package/build/utils/errorTypes.d.ts +25 -0
  75. package/build/utils/errorTypes.d.ts.map +1 -0
  76. package/build/utils/errorTypes.js +1 -0
  77. package/build/utils/errorTypes.js.map +1 -0
  78. package/package.json +28 -11
  79. package/build/config/configManager.test.js +0 -106
  80. package/build/logger/mcpTransport.js +0 -150
  81. package/build/serverManager.test.js +0 -158
@@ -1,150 +0,0 @@
1
- import Transport from 'winston-transport';
2
- // Map Winston log levels to MCP log levels
3
- const LOG_LEVEL_MAP = {
4
- error: 'error',
5
- warn: 'warning',
6
- info: 'info',
7
- verbose: 'debug',
8
- debug: 'debug',
9
- silly: 'debug',
10
- };
11
- /**
12
- * Winston transport for sending logs to MCP clients
13
- */
14
- export class MCPTransport extends Transport {
15
- server;
16
- loggerName;
17
- connected = false;
18
- constructor(options) {
19
- super(options);
20
- this.server = options.server;
21
- this.loggerName = options.loggerName || '1mcp';
22
- // Set up connection status handlers
23
- this.setupConnectionHandlers();
24
- }
25
- /**
26
- * Set up handlers for connection status changes
27
- */
28
- setupConnectionHandlers() {
29
- // Handle connection close
30
- this.server.onclose = () => {
31
- this.setConnected(false);
32
- };
33
- }
34
- /**
35
- * Set the connection status of the transport
36
- * @param connected Whether the server is connected
37
- */
38
- setConnected(connected) {
39
- const previousState = this.connected;
40
- this.connected = connected;
41
- // Log connection state changes
42
- if (previousState !== connected) {
43
- console.debug(`MCP Transport connection state changed to: ${connected ? 'connected' : 'disconnected'}`);
44
- }
45
- }
46
- /**
47
- * Send a log notification to the MCP client
48
- * @param info The log info object
49
- * @returns true if the notification was sent, false otherwise
50
- */
51
- sendLogNotification(info) {
52
- if (!this.server || !this.connected) {
53
- return false;
54
- }
55
- // Map Winston log level to MCP log level
56
- const level = LOG_LEVEL_MAP[info.level] || 'info';
57
- const sanitizedData = this.sanitizeData(info);
58
- // Extract message and metadata
59
- const { message, level: _, ...meta } = sanitizedData;
60
- // Create MCP logging notification
61
- const notification = {
62
- method: 'notifications/message',
63
- params: {
64
- level,
65
- message: typeof message === 'string' ? message : JSON.stringify(message),
66
- logger: this.loggerName,
67
- data: Object.keys(meta).length > 0 ? meta : undefined,
68
- },
69
- };
70
- // Send notification to MCP clients
71
- try {
72
- this.server.notification(notification);
73
- return true;
74
- }
75
- catch (error) {
76
- console.error('Failed to send log notification to MCP client:', error);
77
- return false;
78
- }
79
- }
80
- /**
81
- * Sanitize log data to remove sensitive information
82
- * @param data The data to sanitize
83
- * @returns Sanitized data
84
- */
85
- sanitizeData(data) {
86
- if (typeof data !== 'object' || data === null) {
87
- return data;
88
- }
89
- // List of potentially sensitive field names
90
- const sensitiveFields = [
91
- 'password',
92
- 'token',
93
- 'secret',
94
- 'key',
95
- 'credential',
96
- 'auth',
97
- 'apiKey',
98
- 'api_key',
99
- 'accessToken',
100
- 'access_token',
101
- 'jwt',
102
- 'ssn',
103
- 'creditCard',
104
- 'credit_card',
105
- 'cvv',
106
- 'pin',
107
- ];
108
- if (Array.isArray(data)) {
109
- return data.map((item) => this.sanitizeData(item));
110
- }
111
- const sanitized = {};
112
- for (const [key, value] of Object.entries(data)) {
113
- // Check if this is a sensitive field
114
- const isSensitive = sensitiveFields.some((field) => key.toLowerCase().includes(field.toLowerCase()));
115
- if (isSensitive) {
116
- sanitized[key] = '[REDACTED]';
117
- }
118
- else if (typeof value === 'object' && value !== null) {
119
- sanitized[key] = this.sanitizeData(value);
120
- }
121
- else {
122
- sanitized[key] = value;
123
- }
124
- }
125
- return sanitized;
126
- }
127
- log(info, callback) {
128
- setImmediate(() => {
129
- this.emit('logged', info);
130
- });
131
- // Only try to send if connected
132
- if (this.connected) {
133
- try {
134
- this.sendLogNotification(info);
135
- }
136
- catch (_) {
137
- // Ignore any errors during log sending
138
- }
139
- }
140
- // Always call the callback to prevent blocking
141
- callback();
142
- }
143
- /**
144
- * Clean up resources when the transport is closed
145
- */
146
- close() {
147
- this.setConnected(false);
148
- this.server.onclose = undefined;
149
- }
150
- }
@@ -1,158 +0,0 @@
1
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
- import { ServerManager } from './serverManager.js';
3
- import logger from './logger/logger.js';
4
- import configReloadService from './services/configReloadService.js';
5
- import { setupCapabilities } from './capabilities/capabilityManager.js';
6
- import { enhanceServerWithLogging } from './middleware/loggingMiddleware.js';
7
- // Mock dependencies
8
- jest.mock('@modelcontextprotocol/sdk/server/index.js', () => ({
9
- Server: jest.fn(),
10
- }));
11
- jest.mock('@modelcontextprotocol/sdk/shared/transport.js', () => ({
12
- Transport: jest.fn(),
13
- }));
14
- jest.mock('./logger/logger.js', () => {
15
- const mockLogger = {
16
- info: jest.fn(),
17
- error: jest.fn(),
18
- };
19
- return {
20
- __esModule: true,
21
- default: mockLogger,
22
- };
23
- });
24
- jest.mock('./services/configReloadService.js', () => ({
25
- __esModule: true,
26
- default: {
27
- initialize: jest.fn(),
28
- },
29
- }));
30
- jest.mock('./capabilities/capabilityManager.js', () => ({
31
- setupCapabilities: jest.fn(),
32
- }));
33
- jest.mock('./middleware/loggingMiddleware.js', () => ({
34
- enhanceServerWithLogging: jest.fn(),
35
- }));
36
- describe('ServerManager', () => {
37
- let mockConfig;
38
- let mockCapabilities;
39
- let mockClients;
40
- let mockTransports;
41
- let mockTransport;
42
- let mockServer;
43
- beforeEach(() => {
44
- // Reset all mocks
45
- jest.clearAllMocks();
46
- // Setup test data
47
- mockConfig = { name: 'test-server', version: '1.0.0' };
48
- mockCapabilities = { capabilities: { test: true } };
49
- mockClients = {};
50
- mockTransports = {};
51
- mockTransport = {
52
- // Add any required Transport properties here
53
- };
54
- mockServer = {
55
- connect: jest.fn().mockResolvedValue(undefined),
56
- transport: mockTransport,
57
- };
58
- // Setup mocks
59
- Server.mockImplementation(() => mockServer);
60
- setupCapabilities.mockResolvedValue(undefined);
61
- enhanceServerWithLogging.mockReturnValue(undefined);
62
- configReloadService.initialize.mockImplementation(() => undefined);
63
- });
64
- describe('getInstance', () => {
65
- it('should create a singleton instance', () => {
66
- const instance1 = ServerManager.getInstance(mockConfig, mockCapabilities, mockClients, mockTransports);
67
- const instance2 = ServerManager.getInstance(mockConfig, mockCapabilities, mockClients, mockTransports);
68
- expect(instance1).toBe(instance2);
69
- });
70
- });
71
- describe('connectTransport', () => {
72
- let serverManager;
73
- const sessionId = 'test-session';
74
- const tags = ['tag1', 'tag2'];
75
- beforeEach(() => {
76
- serverManager = ServerManager.getInstance(mockConfig, mockCapabilities, mockClients, mockTransports);
77
- });
78
- it('should successfully connect a transport', async () => {
79
- await serverManager.connectTransport(mockTransport, sessionId, tags);
80
- expect(Server).toHaveBeenCalledWith(mockConfig, mockCapabilities);
81
- expect(enhanceServerWithLogging).toHaveBeenCalledWith(mockServer);
82
- expect(setupCapabilities).toHaveBeenCalled();
83
- expect(configReloadService.initialize).toHaveBeenCalled();
84
- expect(mockServer.connect).toHaveBeenCalledWith(mockTransport);
85
- expect(logger.info).toHaveBeenCalledWith(`Connected transport for session ${sessionId}`);
86
- });
87
- it('should handle connection errors', async () => {
88
- const error = new Error('Connection failed');
89
- mockServer.connect.mockRejectedValueOnce(error);
90
- await expect(serverManager.connectTransport(mockTransport, sessionId, tags)).rejects.toThrow('Connection failed');
91
- expect(logger.error).toHaveBeenCalled();
92
- });
93
- });
94
- describe('disconnectTransport', () => {
95
- let serverManager;
96
- const sessionId = 'test-session';
97
- beforeEach(() => {
98
- serverManager = ServerManager.getInstance(mockConfig, mockCapabilities, mockClients, mockTransports);
99
- });
100
- it('should successfully disconnect a transport', async () => {
101
- await serverManager.connectTransport(mockTransport, sessionId);
102
- jest.clearAllMocks(); // Clear the logs from connectTransport
103
- serverManager.disconnectTransport(sessionId);
104
- expect(logger.info).toHaveBeenCalledWith(`Disconnected transport for session ${sessionId}`);
105
- });
106
- it('should handle non-existent session gracefully', () => {
107
- serverManager.disconnectTransport('non-existent');
108
- expect(logger.info).not.toHaveBeenCalled();
109
- });
110
- });
111
- describe('transport management methods', () => {
112
- let serverManager;
113
- const sessionId = 'test-session';
114
- beforeEach(async () => {
115
- serverManager = ServerManager.getInstance(mockConfig, mockCapabilities, mockClients, mockTransports);
116
- await serverManager.connectTransport(mockTransport, sessionId);
117
- });
118
- it('should get transport by session id', () => {
119
- const transport = serverManager.getTransport(sessionId);
120
- expect(transport).toBe(mockTransport);
121
- });
122
- it('should return undefined for non-existent session', () => {
123
- const transport = serverManager.getTransport('non-existent');
124
- expect(transport).toBeUndefined();
125
- });
126
- it('should get all transports', () => {
127
- const transports = serverManager.getTransports();
128
- expect(transports.size).toBe(1);
129
- expect(transports.get(sessionId)).toBe(mockTransport);
130
- });
131
- it('should get client transports', () => {
132
- const clientTransports = serverManager.getClientTransports();
133
- expect(clientTransports).toEqual(mockTransports);
134
- });
135
- it('should get active transports count', () => {
136
- expect(serverManager.getActiveTransportsCount()).toBe(1);
137
- });
138
- });
139
- describe('getServer', () => {
140
- let serverManager;
141
- const sessionId = 'test-session';
142
- const tags = ['tag1', 'tag2'];
143
- beforeEach(async () => {
144
- serverManager = ServerManager.getInstance(mockConfig, mockCapabilities, mockClients, mockTransports);
145
- await serverManager.connectTransport(mockTransport, sessionId, tags);
146
- });
147
- it('should return server info for existing session', () => {
148
- const serverInfo = serverManager.getServer(sessionId);
149
- expect(serverInfo).toBeDefined();
150
- expect(serverInfo?.server).toBe(mockServer);
151
- expect(serverInfo?.tags).toEqual(tags);
152
- });
153
- it('should return undefined for non-existent session', () => {
154
- const serverInfo = serverManager.getServer('non-existent');
155
- expect(serverInfo).toBeUndefined();
156
- });
157
- });
158
- });