@bluefly/openstandardagents 0.5.0 → 0.5.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.
Files changed (170) hide show
  1. package/.version.json +3 -3
  2. package/CHANGELOG.md +43 -12
  3. package/README.md +31 -26
  4. package/bin/postinstall +0 -0
  5. package/dist/.version.json +3 -3
  6. package/dist/adapters/a2a/a2a-protocol.js +4 -2
  7. package/dist/adapters/a2a/a2a-tool.js +4 -2
  8. package/dist/adapters/a2a/mcp-integration.d.ts +2 -1
  9. package/dist/adapters/a2a/mcp-integration.js +6 -3
  10. package/dist/adapters/browser/browser-exporter.d.ts +26 -0
  11. package/dist/adapters/browser/browser-exporter.js +73 -0
  12. package/dist/adapters/browser/browser-runner.d.ts +23 -0
  13. package/dist/adapters/browser/browser-runner.js +46 -0
  14. package/dist/adapters/browser/index.d.ts +9 -0
  15. package/dist/adapters/browser/index.js +9 -0
  16. package/dist/adapters/docker/index.d.ts +2 -0
  17. package/dist/adapters/docker/index.js +2 -0
  18. package/dist/adapters/docker/openclaw-bridge.d.ts +57 -0
  19. package/dist/adapters/docker/openclaw-bridge.js +173 -0
  20. package/dist/adapters/drupal/index.d.ts +1 -0
  21. package/dist/adapters/drupal/index.js +2 -0
  22. package/dist/adapters/drupal/twig-renderer.d.ts +23 -0
  23. package/dist/adapters/drupal/twig-renderer.js +99 -0
  24. package/dist/adapters/gitlab/agent-generator.js +2 -1
  25. package/dist/api/index.js +2 -1
  26. package/dist/api/routes/mcp.router.js +3 -1
  27. package/dist/api/routes/wizard.router.js +3 -1
  28. package/dist/cli/commands/agent/discover-type.command.js +1 -1
  29. package/dist/cli/commands/agent-card.command.js +37 -10
  30. package/dist/cli/commands/agents-sync.command.d.ts +2 -2
  31. package/dist/cli/commands/agents-sync.command.js +27 -17
  32. package/dist/cli/commands/catalog/config.js +1 -1
  33. package/dist/cli/commands/catalog/validate.command.js +2 -2
  34. package/dist/cli/commands/config.command.js +2 -2
  35. package/dist/cli/commands/daemon.command.js +32 -8
  36. package/dist/cli/commands/discover.d.ts +1 -1
  37. package/dist/cli/commands/discover.js +16 -8
  38. package/dist/cli/commands/economics.command.d.ts +9 -0
  39. package/dist/cli/commands/economics.command.js +113 -0
  40. package/dist/cli/commands/export.command.js +6 -3
  41. package/dist/cli/commands/mcp.command.js +3 -1
  42. package/dist/cli/commands/memory.command.d.ts +18 -0
  43. package/dist/cli/commands/memory.command.js +168 -0
  44. package/dist/cli/commands/publish.command.js +7 -4
  45. package/dist/cli/commands/serve-builder-routes.js +1 -1
  46. package/dist/cli/commands/usie-skills.command.d.ts +24 -0
  47. package/dist/cli/commands/usie-skills.command.js +297 -0
  48. package/dist/cli/commands/validate.command.js +8 -1
  49. package/dist/cli/commands/verify.d.ts +3 -3
  50. package/dist/cli/commands/verify.js +12 -6
  51. package/dist/cli/commands/workspace.command.d.ts +1 -0
  52. package/dist/cli/commands/workspace.command.js +28 -4
  53. package/dist/cli/index.js +12 -0
  54. package/dist/cli/workspace-validate.d.ts +23 -0
  55. package/dist/cli/workspace-validate.js +117 -0
  56. package/dist/data/platform-matrix.js +1 -4
  57. package/dist/generated/types.d.ts +97 -97
  58. package/dist/index.d.ts +2 -0
  59. package/dist/index.js +2 -0
  60. package/dist/mcp-server/index.js +658 -982
  61. package/dist/mesh/discovery-gkg.d.ts +26 -0
  62. package/dist/mesh/discovery-gkg.js +92 -0
  63. package/dist/messenger/Handler/AgentBatchHandler.js +3 -2
  64. package/dist/messenger/Handler/AgentExecutionHandler.js +6 -1
  65. package/dist/package.json +20 -4
  66. package/dist/sdks/shared/types.d.ts +1 -1
  67. package/dist/services/agent-card-generator.js +6 -2
  68. package/dist/services/daemon/audit-log.service.js +3 -1
  69. package/dist/services/daemon/execution.service.js +8 -4
  70. package/dist/services/daemon/fs-watcher.service.js +6 -7
  71. package/dist/services/daemon/pairing.service.js +2 -1
  72. package/dist/services/daemon/skill-aggregator.service.js +105 -21
  73. package/dist/services/daemon/sse-endpoints.js +1 -1
  74. package/dist/services/daemon/ws-server.js +10 -3
  75. package/dist/services/governance/cedar-provider.js +12 -8
  76. package/dist/services/governance/cedar-validator.service.js +1 -1
  77. package/dist/services/mcp/bridge.service.js +40 -9
  78. package/dist/services/openapi-extensions-validation.d.ts +20 -0
  79. package/dist/services/openapi-extensions-validation.js +193 -0
  80. package/dist/services/release-automation/merge-request.service.d.ts +4 -4
  81. package/dist/services/release-automation/release-buttons.js +3 -3
  82. package/dist/services/release-automation/schemas/release.schema.d.ts +3 -3
  83. package/dist/services/runtime/openai.adapter.d.ts +46 -13
  84. package/dist/services/runtime/openai.adapter.js +169 -131
  85. package/dist/services/skill-registry.service.d.ts +1 -1
  86. package/dist/services/skills-pipeline/skills-research.service.js +47 -7
  87. package/dist/services/trust/trust.service.js +6 -4
  88. package/dist/services/validation-zod.service.js +3 -22
  89. package/dist/services/validators/index.d.ts +1 -0
  90. package/dist/services/validators/index.js +1 -0
  91. package/dist/services/validators/registry.d.ts +21 -0
  92. package/dist/services/validators/registry.js +42 -0
  93. package/dist/skills/test-skill/package.json +1 -1
  94. package/dist/spec/extensions/cognition.schema.json +87 -0
  95. package/dist/spec/layer4-economics/duadp-examples.json +44 -0
  96. package/dist/spec/v0.4/agent.schema.json +14 -0
  97. package/dist/spec/v0.5/agent-builder-openapi.yaml +230 -0
  98. package/dist/spec/v0.5/agent.schema.json +32 -1
  99. package/dist/spec/v0.5/extensions/cognition/cognition.schema.json +78 -1
  100. package/dist/spec/v0.5/extensions/economics/context-pack.schema.json +91 -0
  101. package/dist/spec/v0.5/extensions/economics/execution-profile.schema.json +148 -0
  102. package/dist/spec/v0.5/extensions/economics/failure-semantics.schema.json +32 -0
  103. package/dist/spec/v0.5/extensions/economics/replay-packet.schema.json +120 -0
  104. package/dist/spec/v0.5/extensions/mcp/README.md +1 -1
  105. package/dist/spec/v0.5/memory-hierarchy.yaml +120 -0
  106. package/dist/spec/v1/agent-card.schema.json +254 -0
  107. package/dist/types/cognition.zod.d.ts +312 -0
  108. package/dist/types/cognition.zod.js +223 -0
  109. package/dist/types/identity.zod.d.ts +5 -5
  110. package/dist/types/index.d.ts +53 -7
  111. package/dist/types/index.js +4 -2
  112. package/dist/types/personality.zod.d.ts +3 -3
  113. package/dist/utils/http-client.d.ts +22 -0
  114. package/dist/utils/http-client.js +51 -0
  115. package/dist/utils/index.d.ts +3 -0
  116. package/dist/utils/index.js +3 -0
  117. package/dist/utils/proxy-resolver.d.ts +36 -0
  118. package/dist/utils/proxy-resolver.js +59 -0
  119. package/dist/utils/user-agent.d.ts +11 -0
  120. package/dist/utils/user-agent.js +17 -0
  121. package/dist/validation/version-compliance.js +1 -1
  122. package/examples/agentscope/react-assistant/README.md +1 -1
  123. package/examples/agentscope/react-assistant/agent.ossa.yaml +1 -1
  124. package/examples/drupal/drupal-contributor-agent/.eslintrc.json +58 -0
  125. package/examples/drupal/drupal-contributor-agent/.prettierrc.json +10 -0
  126. package/examples/drupal/drupal-contributor-agent/package.json +55 -0
  127. package/examples/drupal/drupal-contributor-agent/src/core/index.ts +10 -0
  128. package/examples/drupal/drupal-contributor-agent/src/index.ts +17 -0
  129. package/examples/drupal/drupal-contributor-agent/src/types/index.ts +180 -0
  130. package/examples/drupal/drupal-contributor-agent/tsconfig.json +36 -0
  131. package/examples/getting-started/01-minimal-agent.ossa.yaml +1 -1
  132. package/examples/getting-started/02-agent-with-tools.ossa.yaml +1 -1
  133. package/examples/getting-started/03-agent-with-safety.ossa.yaml +1 -1
  134. package/examples/getting-started/04-agent-with-messaging.ossa.yaml +1 -1
  135. package/examples/getting-started/05-workflow-composition.ossa.yaml +1 -1
  136. package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
  137. package/examples/reference-implementations/python-client/examples/basic_usage.py +0 -0
  138. package/examples/reference-implementations/python-client/examples/publish_agent.py +0 -0
  139. package/openapi/agent-cognition-sessions.yaml +580 -0
  140. package/openapi/agent-crud.yaml +20 -20
  141. package/openapi/core/ossa-registry-api.openapi.yaml +1 -1
  142. package/openapi/ossa-cli-enhancements.openapi.yaml +1 -1
  143. package/openapi/release-automation.openapi.yaml +1 -1
  144. package/openapi/schemas/common/economics.yaml +98 -0
  145. package/openapi/uadp-asyncapi.yaml +1 -1
  146. package/openapi/uadp-openapi.yaml +2 -2
  147. package/package.json +114 -96
  148. package/spec/extensions/cognition.schema.json +87 -0
  149. package/spec/layer4-economics/duadp-examples.json +44 -0
  150. package/spec/v0.4/agent.schema.json +14 -0
  151. package/spec/v0.5/agent-builder-openapi.yaml +230 -0
  152. package/spec/v0.5/agent.schema.json +32 -1
  153. package/spec/v0.5/extensions/cognition/cognition.schema.json +78 -1
  154. package/spec/v0.5/extensions/economics/context-pack.schema.json +91 -0
  155. package/spec/v0.5/extensions/economics/execution-profile.schema.json +148 -0
  156. package/spec/v0.5/extensions/economics/failure-semantics.schema.json +32 -0
  157. package/spec/v0.5/extensions/economics/replay-packet.schema.json +120 -0
  158. package/spec/v0.5/extensions/mcp/README.md +1 -1
  159. package/spec/v0.5/memory-hierarchy.yaml +120 -0
  160. package/spec/v1/agent-card.schema.json +254 -0
  161. package/dist/adapters/a2a/__tests__/mcp-integration.spec.d.ts +0 -5
  162. package/dist/adapters/a2a/__tests__/mcp-integration.spec.js +0 -268
  163. package/dist/adapters/a2a/__tests__/mcp-transport.spec.d.ts +0 -5
  164. package/dist/adapters/a2a/__tests__/mcp-transport.spec.js +0 -203
  165. package/dist/mcp-server/__tests__/mcp-server.spec.d.ts +0 -8
  166. package/dist/mcp-server/__tests__/mcp-server.spec.js +0 -566
  167. package/dist/validation/__tests__/error-codes.test.d.ts +0 -5
  168. package/dist/validation/__tests__/error-codes.test.js +0 -252
  169. package/dist/version-management/core/version-manager.test.d.ts +0 -2
  170. package/dist/version-management/core/version-manager.test.js +0 -210
@@ -1,268 +0,0 @@
1
- /**
2
- * MCP Integration Service Tests
3
- */
4
- import { afterEach, beforeEach, describe, expect, it } from '@jest/globals';
5
- import { SPEC_VERSION } from '../../../version.js';
6
- import { A2AMessageType, MessagePriority } from '../a2a-protocol.js';
7
- import { MCPIntegrationService, MCPMessageType } from '../mcp-integration.js';
8
- // Helper to create test agent identity
9
- function createTestAgent(name, namespace) {
10
- return {
11
- id: crypto.randomUUID(),
12
- uri: `uadp://${namespace}/${name}`,
13
- name,
14
- namespace,
15
- capabilities: ['test'],
16
- version: '1.0.0',
17
- };
18
- }
19
- describe('MCPIntegrationService', () => {
20
- let service;
21
- beforeEach(() => {
22
- service = new MCPIntegrationService();
23
- });
24
- afterEach(async () => {
25
- await service.cleanup();
26
- });
27
- describe('Connection Management', () => {
28
- it('should connect to MCP server (mock)', async () => {
29
- const uri = 'http://localhost:3000/mcp';
30
- try {
31
- const connection = await service.connectMCPServer(uri);
32
- expect(connection).toBeDefined();
33
- expect(connection.uri).toBe(uri);
34
- expect(connection.status).toBe('connected');
35
- }
36
- catch (error) {
37
- // Expected to fail without real server, but should attempt connection
38
- expect(error).toBeDefined();
39
- }
40
- });
41
- it('should disconnect from MCP server', async () => {
42
- const uri = 'http://localhost:3000/mcp';
43
- try {
44
- const connection = await service.connectMCPServer(uri);
45
- await service.disconnectMCPServer(connection.id);
46
- }
47
- catch (error) {
48
- // Expected to fail without real server
49
- }
50
- });
51
- it('should handle disconnect of non-existent connection', async () => {
52
- await expect(service.disconnectMCPServer('non-existent-id')).rejects.toThrow('MCP connection not found');
53
- });
54
- });
55
- describe('Server Exposure', () => {
56
- it('should expose agent as MCP server', async () => {
57
- const agent = createTestAgent('Test Agent', 'test-namespace');
58
- const server = await service.exposeMCPServer(agent);
59
- expect(server).toBeDefined();
60
- expect(server.agent).toEqual(agent);
61
- expect(server.endpoint).toContain(agent.namespace);
62
- expect(server.endpoint).toContain(agent.name);
63
- expect(server.capabilities).toBeDefined();
64
- });
65
- it('should set default capabilities for exposed server', async () => {
66
- const agent = createTestAgent('Test Agent', 'test-namespace');
67
- const server = await service.exposeMCPServer(agent);
68
- expect(server.capabilities.resources?.list).toBe(true);
69
- expect(server.capabilities.prompts?.list).toBe(true);
70
- expect(server.capabilities.tools?.list).toBe(true);
71
- expect(server.capabilities.logging).toBeDefined();
72
- });
73
- });
74
- describe('Discovery Operations', () => {
75
- it('should discover resources (connection required)', async () => {
76
- const uri = 'http://localhost:3000/mcp';
77
- try {
78
- const connection = await service.connectMCPServer(uri);
79
- const resources = await service.discoverResources(connection.id);
80
- expect(Array.isArray(resources)).toBe(true);
81
- }
82
- catch (error) {
83
- // Expected to fail without real server
84
- expect(error).toBeDefined();
85
- }
86
- });
87
- it('should discover prompts (connection required)', async () => {
88
- const uri = 'http://localhost:3000/mcp';
89
- try {
90
- const connection = await service.connectMCPServer(uri);
91
- const prompts = await service.discoverPrompts(connection.id);
92
- expect(Array.isArray(prompts)).toBe(true);
93
- }
94
- catch (error) {
95
- // Expected to fail without real server
96
- expect(error).toBeDefined();
97
- }
98
- });
99
- it('should discover tools (connection required)', async () => {
100
- const uri = 'http://localhost:3000/mcp';
101
- try {
102
- const connection = await service.connectMCPServer(uri);
103
- const tools = await service.discoverTools(connection.id);
104
- expect(Array.isArray(tools)).toBe(true);
105
- }
106
- catch (error) {
107
- // Expected to fail without real server
108
- expect(error).toBeDefined();
109
- }
110
- });
111
- it('should handle discovery with invalid connection ID', async () => {
112
- await expect(service.discoverResources('invalid-id')).rejects.toThrow('MCP connection not found');
113
- await expect(service.discoverPrompts('invalid-id')).rejects.toThrow('MCP connection not found');
114
- await expect(service.discoverTools('invalid-id')).rejects.toThrow('MCP connection not found');
115
- });
116
- });
117
- describe('Tool Invocation', () => {
118
- it('should call MCP tool (connection required)', async () => {
119
- const uri = 'http://localhost:3000/mcp';
120
- try {
121
- const connection = await service.connectMCPServer(uri);
122
- const result = await service.callTool(connection.id, 'test-tool', {
123
- arg1: 'value1',
124
- });
125
- expect(result).toBeDefined();
126
- }
127
- catch (error) {
128
- // Expected to fail without real server
129
- expect(error).toBeDefined();
130
- }
131
- });
132
- it('should handle tool call with invalid connection', async () => {
133
- await expect(service.callTool('invalid-id', 'test-tool', {})).rejects.toThrow('MCP connection not found');
134
- });
135
- });
136
- describe('Resource Reading', () => {
137
- it('should read MCP resource (connection required)', async () => {
138
- const uri = 'http://localhost:3000/mcp';
139
- try {
140
- const connection = await service.connectMCPServer(uri);
141
- const content = await service.readResource(connection.id, 'resource://test/path');
142
- expect(content).toBeDefined();
143
- }
144
- catch (error) {
145
- // Expected to fail without real server
146
- expect(error).toBeDefined();
147
- }
148
- });
149
- it('should handle resource read with invalid connection', async () => {
150
- await expect(service.readResource('invalid-id', 'resource://test')).rejects.toThrow('MCP connection not found');
151
- });
152
- });
153
- describe('Protocol Conversion', () => {
154
- it('should convert A2A message to MCP format', () => {
155
- const from = createTestAgent('Sender', 'sender');
156
- const to = createTestAgent('Receiver', 'receiver');
157
- const a2aMessage = {
158
- id: 'test-123',
159
- from,
160
- to,
161
- type: A2AMessageType.COMMAND,
162
- payload: { action: 'test' },
163
- version: SPEC_VERSION,
164
- metadata: {
165
- priority: MessagePriority.NORMAL,
166
- timeout: 30000,
167
- retries: 3,
168
- traceContext: {
169
- traceparent: '00-trace-span-01',
170
- traceId: 'trace',
171
- spanId: 'span',
172
- },
173
- createdAt: new Date().toISOString(),
174
- },
175
- };
176
- const mcpMessage = service.a2aToMCP(a2aMessage);
177
- expect(mcpMessage).toHaveProperty('jsonrpc', '2.0');
178
- expect(mcpMessage).toHaveProperty('id', 'test-123');
179
- expect(mcpMessage).toHaveProperty('method');
180
- expect(mcpMessage).toHaveProperty('params');
181
- expect(mcpMessage.metadata).toHaveProperty('from', from.uri);
182
- });
183
- it('should convert MCP message to A2A format', () => {
184
- const from = createTestAgent('Sender', 'sender');
185
- const to = createTestAgent('Receiver', 'receiver');
186
- const mcpMessage = {
187
- jsonrpc: '2.0',
188
- id: 'mcp-123',
189
- method: MCPMessageType.TOOLS_CALL,
190
- params: { tool: 'test' },
191
- };
192
- const a2aMessage = service.mcpToA2A(mcpMessage, from, to);
193
- expect(a2aMessage).toHaveProperty('id', 'mcp-123');
194
- expect(a2aMessage).toHaveProperty('from', from);
195
- expect(a2aMessage).toHaveProperty('to', to);
196
- expect(a2aMessage).toHaveProperty('type');
197
- expect(a2aMessage).toHaveProperty('payload');
198
- expect(a2aMessage).toHaveProperty('version', '0.4.4');
199
- expect(a2aMessage.metadata).toBeDefined();
200
- });
201
- it('should map A2A types to MCP methods correctly', () => {
202
- const agent = createTestAgent('Test', 'test');
203
- const baseMessage = {
204
- id: '1',
205
- from: agent,
206
- to: agent,
207
- payload: {},
208
- version: SPEC_VERSION,
209
- metadata: {
210
- priority: MessagePriority.NORMAL,
211
- timeout: 30000,
212
- retries: 3,
213
- traceContext: { traceparent: '00-t-s-01', traceId: 't', spanId: 's' },
214
- createdAt: new Date().toISOString(),
215
- },
216
- };
217
- // Test request -> tools/call
218
- const requestMsg = { ...baseMessage, type: A2AMessageType.REQUEST };
219
- const mcpRequest = service.a2aToMCP(requestMsg);
220
- expect(mcpRequest.method).toBe(MCPMessageType.TOOLS_CALL);
221
- // Test command -> tools/call
222
- const commandMsg = { ...baseMessage, type: A2AMessageType.COMMAND };
223
- const mcpCommand = service.a2aToMCP(commandMsg);
224
- expect(mcpCommand.method).toBe(MCPMessageType.TOOLS_CALL);
225
- // Test event -> notification
226
- const eventMsg = { ...baseMessage, type: A2AMessageType.EVENT };
227
- const mcpEvent = service.a2aToMCP(eventMsg);
228
- expect(mcpEvent.method).toBe(MCPMessageType.NOTIFICATION);
229
- });
230
- });
231
- describe('Statistics and State', () => {
232
- it('should track connections', () => {
233
- const connections = service.getConnections();
234
- expect(Array.isArray(connections)).toBe(true);
235
- });
236
- it('should track exposed servers', async () => {
237
- const agent = createTestAgent('Test', 'test');
238
- await service.exposeMCPServer(agent);
239
- const servers = service.getServers();
240
- expect(servers.length).toBeGreaterThan(0);
241
- expect(servers[0].agent).toEqual(agent);
242
- });
243
- it('should provide transport statistics', () => {
244
- const stats = service.getTransportStats();
245
- expect(stats).toHaveProperty('totalConnections');
246
- expect(stats).toHaveProperty('totalRequests');
247
- expect(stats).toHaveProperty('connections');
248
- });
249
- });
250
- describe('Cleanup', () => {
251
- it('should cleanup all connections', async () => {
252
- await expect(service.cleanup()).resolves.not.toThrow();
253
- });
254
- it('should disconnect all transport connections on cleanup', async () => {
255
- const uri = 'http://localhost:3000/mcp';
256
- try {
257
- await service.connectMCPServer(uri);
258
- }
259
- catch (error) {
260
- // Ignore connection errors
261
- }
262
- await service.cleanup();
263
- const stats = service.getTransportStats();
264
- expect(stats.totalConnections).toBe(0);
265
- });
266
- });
267
- });
268
- //# sourceMappingURL=mcp-integration.spec.js.map
@@ -1,5 +0,0 @@
1
- /**
2
- * MCP Transport Manager Tests
3
- */
4
- export {};
5
- //# sourceMappingURL=mcp-transport.spec.d.ts.map
@@ -1,203 +0,0 @@
1
- /**
2
- * MCP Transport Manager Tests
3
- */
4
- import { describe, it, expect, beforeEach, afterEach, } from '@jest/globals';
5
- import { MCPTransportManager } from '../mcp-transport.js';
6
- describe('MCPTransportManager', () => {
7
- let transportManager;
8
- beforeEach(() => {
9
- transportManager = new MCPTransportManager();
10
- });
11
- afterEach(async () => {
12
- await transportManager.disconnectAll();
13
- });
14
- describe('URI Parsing', () => {
15
- it('should parse stdio URI correctly', async () => {
16
- const uri = 'stdio://python/path/to/script.py?arg1=value1&arg2=value2';
17
- try {
18
- await transportManager.getClient(uri);
19
- }
20
- catch (error) {
21
- // Expected to fail (no actual server), but parsing should work
22
- expect(error).toBeDefined();
23
- }
24
- // Check that connection attempt was made
25
- const connections = transportManager.getConnections();
26
- expect(connections.length).toBeLessThanOrEqual(1);
27
- });
28
- it('should parse HTTP URI correctly', async () => {
29
- const uri = 'http://localhost:3000/mcp';
30
- try {
31
- await transportManager.getClient(uri);
32
- }
33
- catch (error) {
34
- // Expected to fail (no actual server)
35
- expect(error).toBeDefined();
36
- }
37
- });
38
- it('should parse HTTPS URI correctly', async () => {
39
- const uri = 'https://api.example.com/mcp';
40
- try {
41
- await transportManager.getClient(uri);
42
- }
43
- catch (error) {
44
- // Expected to fail (no actual server)
45
- expect(error).toBeDefined();
46
- }
47
- });
48
- it('should reject unsupported protocols', async () => {
49
- const uri = 'ftp://example.com/mcp';
50
- await expect(transportManager.getClient(uri)).rejects.toThrow('Unsupported protocol');
51
- });
52
- it('should reject invalid URIs', async () => {
53
- const uri = 'not-a-valid-uri';
54
- await expect(transportManager.getClient(uri)).rejects.toThrow('Invalid MCP URI');
55
- });
56
- });
57
- describe('Connection Pooling', () => {
58
- it('should reuse existing connections', async () => {
59
- const uri = 'http://localhost:3000/mcp';
60
- // First connection attempt
61
- try {
62
- await transportManager.getClient(uri);
63
- }
64
- catch (error) {
65
- // Ignore connection error
66
- }
67
- const stats1 = transportManager.getStats();
68
- const initialConnections = stats1.totalConnections;
69
- // Second connection attempt (should reuse)
70
- try {
71
- await transportManager.getClient(uri);
72
- }
73
- catch (error) {
74
- // Ignore connection error
75
- }
76
- const stats2 = transportManager.getStats();
77
- expect(stats2.totalConnections).toBe(initialConnections);
78
- });
79
- it('should track request count', async () => {
80
- const uri = 'http://localhost:3000/mcp';
81
- try {
82
- const wrapper = await transportManager.getClient(uri);
83
- expect(wrapper.requestCount).toBe(0);
84
- }
85
- catch (error) {
86
- // Connection will fail, but wrapper should be tracked
87
- }
88
- });
89
- it('should update last activity timestamp', async () => {
90
- const uri = 'http://localhost:3000/mcp';
91
- try {
92
- const wrapper1 = await transportManager.getClient(uri);
93
- const firstActivity = wrapper1.lastActivity;
94
- // Wait a bit
95
- await new Promise((resolve) => setTimeout(resolve, 10));
96
- const wrapper2 = await transportManager.getClient(uri);
97
- expect(wrapper2.lastActivity.getTime()).toBeGreaterThanOrEqual(firstActivity.getTime());
98
- }
99
- catch (error) {
100
- // Ignore connection errors
101
- }
102
- });
103
- });
104
- describe('Connection Management', () => {
105
- it('should disconnect specific connection', async () => {
106
- const uri = 'http://localhost:3000/mcp';
107
- try {
108
- await transportManager.getClient(uri);
109
- }
110
- catch (error) {
111
- // Ignore connection error
112
- }
113
- await transportManager.disconnect(uri);
114
- const connections = transportManager.getConnections();
115
- expect(connections.find((c) => c.config.url === uri)).toBeUndefined();
116
- });
117
- it('should disconnect all connections', async () => {
118
- const uri1 = 'http://localhost:3000/mcp';
119
- const uri2 = 'http://localhost:3001/mcp';
120
- try {
121
- await transportManager.getClient(uri1);
122
- await transportManager.getClient(uri2);
123
- }
124
- catch (error) {
125
- // Ignore connection errors
126
- }
127
- await transportManager.disconnectAll();
128
- const connections = transportManager.getConnections();
129
- expect(connections.length).toBe(0);
130
- });
131
- it('should handle disconnect of non-existent connection gracefully', async () => {
132
- await expect(transportManager.disconnect('http://nonexistent:3000/mcp')).resolves.not.toThrow();
133
- });
134
- });
135
- describe('Statistics', () => {
136
- it('should track connection statistics', async () => {
137
- const uri = 'http://localhost:3000/mcp';
138
- try {
139
- await transportManager.getClient(uri);
140
- }
141
- catch (error) {
142
- // Ignore connection error
143
- }
144
- const stats = transportManager.getStats();
145
- expect(stats).toHaveProperty('totalConnections');
146
- expect(stats).toHaveProperty('totalRequests');
147
- expect(stats).toHaveProperty('connections');
148
- expect(Array.isArray(stats.connections)).toBe(true);
149
- });
150
- it('should return empty stats when no connections', () => {
151
- const stats = transportManager.getStats();
152
- expect(stats.totalConnections).toBe(0);
153
- expect(stats.totalRequests).toBe(0);
154
- expect(stats.connections.length).toBe(0);
155
- });
156
- });
157
- describe('Error Handling', () => {
158
- it('should handle connection timeout gracefully', async () => {
159
- const uri = 'http://192.0.2.1:9999/mcp'; // Non-routable IP
160
- await expect(transportManager.getClient(uri)).rejects.toThrow();
161
- }, 35000); // Longer timeout for connection attempt
162
- it('should handle request errors', async () => {
163
- const uri = 'http://localhost:9999/mcp';
164
- await expect(transportManager.sendRequest(uri, 'test/method', {})).rejects.toThrow();
165
- }, 35000);
166
- });
167
- describe('Transport Types', () => {
168
- it('should support STDIO transport type', async () => {
169
- const uri = 'stdio://node/script.js';
170
- try {
171
- await transportManager.getClient(uri);
172
- }
173
- catch (error) {
174
- // Connection will fail, but transport type should be parsed
175
- expect(error).toBeDefined();
176
- }
177
- });
178
- it('should support HTTP transport type', async () => {
179
- const uri = 'http://localhost:3000/mcp';
180
- try {
181
- await transportManager.getClient(uri);
182
- }
183
- catch (error) {
184
- expect(error).toBeDefined();
185
- }
186
- });
187
- it('should support HTTPS transport type', async () => {
188
- const uri = 'https://api.example.com/mcp';
189
- try {
190
- await transportManager.getClient(uri);
191
- }
192
- catch (error) {
193
- expect(error).toBeDefined();
194
- }
195
- });
196
- it('should accept WebSocket URI and use SSE fallback', async () => {
197
- const uri = 'ws://localhost:3000/mcp';
198
- await expect(transportManager.getClient(uri)).rejects.toThrow();
199
- // Connection fails (no server) but WebSocket path is handled via SSE fallback
200
- });
201
- });
202
- });
203
- //# sourceMappingURL=mcp-transport.spec.js.map
@@ -1,8 +0,0 @@
1
- /**
2
- * OSSA MCP Server — Integration Tests
3
- *
4
- * Tests all 7 tools end-to-end using the MCP SDK Client.
5
- * Uses vitest + @modelcontextprotocol/sdk.
6
- */
7
- export {};
8
- //# sourceMappingURL=mcp-server.spec.d.ts.map