🐺 Initial commit - Lupul Augmentat MCP Server

- MCP server cu stdio transport pentru performanță maximă
- Tool-uri pentru file operations, HTTP requests, system commands
- Suport NATS pentru comunicare inter-module
- Configurare nginx cu API key auth și SSL
- Arhitectură modulară și extensibilă

🤖 Generated with Claude Code
This commit is contained in:
Claude (Lupul Augmentat)
2025-10-09 06:24:58 +02:00
commit 475f89af74
59 changed files with 12827 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
import { HttpRequestTool } from '../../src/tools/builtin/HttpRequestTool';
import { ToolContext } from '../../src/tools/base/ToolHandler';
// Mock fetch
global.fetch = jest.fn();
describe('HttpRequestTool', () => {
let tool: HttpRequestTool;
beforeEach(() => {
tool = new HttpRequestTool();
jest.clearAllMocks();
});
const createContext = (permissions: string[] = ['network:http']): ToolContext => ({
requestId: 'test-request',
permissions,
});
describe('execute', () => {
it('should make GET request successfully', async () => {
const mockResponse = {
status: 200,
statusText: 'OK',
headers: new Headers({ 'content-type': 'application/json' }),
json: async () => ({ data: 'test' }),
};
(global.fetch as jest.Mock).mockResolvedValue(mockResponse);
const result = await tool.execute(
{ url: 'https://api.example.com/data' },
createContext(),
);
expect(result).toMatchObject({
status: 200,
statusText: 'OK',
body: { data: 'test' },
});
expect(global.fetch).toHaveBeenCalledWith(
'https://api.example.com/data',
expect.objectContaining({
method: 'GET',
}),
);
});
it('should make POST request with JSON body', async () => {
const mockResponse = {
status: 201,
statusText: 'Created',
headers: new Headers({ 'content-type': 'application/json' }),
json: async () => ({ id: 123 }),
};
(global.fetch as jest.Mock).mockResolvedValue(mockResponse);
const result = await tool.execute(
{
url: 'https://api.example.com/users',
method: 'POST',
body: { name: 'John Doe' },
},
createContext(),
);
expect(result.status).toBe(201);
expect(global.fetch).toHaveBeenCalledWith(
'https://api.example.com/users',
expect.objectContaining({
method: 'POST',
body: JSON.stringify({ name: 'John Doe' }),
headers: expect.objectContaining({
'Content-Type': 'application/json',
}),
}),
);
});
it('should throw error for internal URLs', async () => {
await expect(
tool.execute(
{ url: 'http://localhost:8080/internal' },
createContext(),
),
).rejects.toThrow('Requests to internal networks are not allowed');
await expect(
tool.execute(
{ url: 'http://192.168.1.1/admin' },
createContext(),
),
).rejects.toThrow('Requests to internal networks are not allowed');
});
it('should throw error without permission', async () => {
await expect(
tool.execute(
{ url: 'https://api.example.com' },
createContext([]),
),
).rejects.toThrow('Permission denied: network:http required');
});
it('should handle timeout', async () => {
(global.fetch as jest.Mock).mockImplementation(
(_url, options) => new Promise((_resolve, reject) => {
// Simulate AbortController behavior
if (options?.signal) {
options.signal.addEventListener('abort', () => {
const error = new Error('The operation was aborted');
error.name = 'AbortError';
reject(error);
});
}
// Never resolve to simulate timeout
}),
);
await expect(
tool.execute(
{ url: 'https://api.example.com', timeout: 100 },
createContext(),
),
).rejects.toThrow('Request timeout after 100ms');
});
});
});