nullpath-mcp 1.1.0 → 1.2.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/dist/__tests__/tools.test.d.ts +2 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +157 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/index.d.ts +2 -87
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +219 -215
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/tools.test.ts +197 -0
- package/src/index.ts +246 -321
- package/src/__tests__/x402.test.ts +0 -229
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Mock fetch globally
|
|
4
|
+
const mockFetch = vi.fn();
|
|
5
|
+
global.fetch = mockFetch;
|
|
6
|
+
|
|
7
|
+
// Import after mocking
|
|
8
|
+
describe('nullpath MCP tools', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
mockFetch.mockReset();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
vi.restoreAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('discover_agents', () => {
|
|
18
|
+
it('should call discover endpoint', async () => {
|
|
19
|
+
const mockResponse = {
|
|
20
|
+
success: true,
|
|
21
|
+
data: {
|
|
22
|
+
agents: [
|
|
23
|
+
{ id: 'test-1', name: 'Test Agent', reputation_score: 85 }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
mockFetch.mockResolvedValueOnce({
|
|
29
|
+
ok: true,
|
|
30
|
+
json: async () => mockResponse,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const response = await fetch('https://nullpath.com/api/v1/discover');
|
|
34
|
+
const data = await response.json() as { success: boolean; data: { agents: unknown[] } };
|
|
35
|
+
|
|
36
|
+
expect(mockFetch).toHaveBeenCalledWith('https://nullpath.com/api/v1/discover');
|
|
37
|
+
expect(data.success).toBe(true);
|
|
38
|
+
expect(data.data.agents).toHaveLength(1);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should pass query parameters', async () => {
|
|
42
|
+
mockFetch.mockResolvedValueOnce({
|
|
43
|
+
ok: true,
|
|
44
|
+
json: async () => ({ success: true, data: { agents: [] } }),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await fetch('https://nullpath.com/api/v1/discover?q=summarize&limit=5');
|
|
48
|
+
|
|
49
|
+
expect(mockFetch).toHaveBeenCalledWith(
|
|
50
|
+
'https://nullpath.com/api/v1/discover?q=summarize&limit=5'
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('lookup_agent', () => {
|
|
56
|
+
it('should call agent endpoint with ID', async () => {
|
|
57
|
+
const agentId = '22222222-2222-4222-8222-222222222222';
|
|
58
|
+
const mockResponse = {
|
|
59
|
+
success: true,
|
|
60
|
+
data: {
|
|
61
|
+
id: agentId,
|
|
62
|
+
name: 'URL Summarizer',
|
|
63
|
+
reputation_score: 99,
|
|
64
|
+
trustTier: 'premium',
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
mockFetch.mockResolvedValueOnce({
|
|
69
|
+
ok: true,
|
|
70
|
+
json: async () => mockResponse,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const response = await fetch(`https://nullpath.com/api/v1/agents/${agentId}`);
|
|
74
|
+
const data = await response.json() as { data: { id: string; trustTier: string } };
|
|
75
|
+
|
|
76
|
+
expect(data.data.id).toBe(agentId);
|
|
77
|
+
expect(data.data.trustTier).toBe('premium');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('API error handling', () => {
|
|
82
|
+
it('should handle 404 errors', async () => {
|
|
83
|
+
mockFetch.mockResolvedValueOnce({
|
|
84
|
+
ok: false,
|
|
85
|
+
status: 404,
|
|
86
|
+
text: async () => 'Agent not found',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const response = await fetch('https://nullpath.com/api/v1/agents/invalid-id');
|
|
90
|
+
|
|
91
|
+
expect(response.ok).toBe(false);
|
|
92
|
+
expect(response.status).toBe(404);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should handle network errors', async () => {
|
|
96
|
+
mockFetch.mockRejectedValueOnce(new Error('Network error'));
|
|
97
|
+
|
|
98
|
+
await expect(
|
|
99
|
+
fetch('https://nullpath.com/api/v1/discover')
|
|
100
|
+
).rejects.toThrow('Network error');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('execute_agent', () => {
|
|
105
|
+
it('should require wallet key for execution', () => {
|
|
106
|
+
const walletKey = process.env.NULLPATH_WALLET_KEY;
|
|
107
|
+
|
|
108
|
+
if (!walletKey) {
|
|
109
|
+
// Expected behavior when no wallet key is set
|
|
110
|
+
expect(walletKey).toBeUndefined();
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should call execute endpoint with POST', async () => {
|
|
115
|
+
const payload = {
|
|
116
|
+
targetAgentId: 'test-agent',
|
|
117
|
+
capabilityId: 'summarize',
|
|
118
|
+
input: { text: 'Hello world' },
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
mockFetch.mockResolvedValueOnce({
|
|
122
|
+
ok: true,
|
|
123
|
+
json: async () => ({ success: true, output: 'Summary' }),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await fetch('https://nullpath.com/api/v1/execute', {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: { 'Content-Type': 'application/json' },
|
|
129
|
+
body: JSON.stringify(payload),
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
expect(mockFetch).toHaveBeenCalledWith(
|
|
133
|
+
'https://nullpath.com/api/v1/execute',
|
|
134
|
+
expect.objectContaining({
|
|
135
|
+
method: 'POST',
|
|
136
|
+
body: JSON.stringify(payload),
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('register_agent', () => {
|
|
143
|
+
it('should require wallet key for registration', () => {
|
|
144
|
+
const walletKey = process.env.NULLPATH_WALLET_KEY;
|
|
145
|
+
|
|
146
|
+
if (!walletKey) {
|
|
147
|
+
expect(walletKey).toBeUndefined();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should call agents endpoint with POST for registration', async () => {
|
|
152
|
+
const payload = {
|
|
153
|
+
name: 'Test Agent',
|
|
154
|
+
description: 'A test agent',
|
|
155
|
+
wallet: '0x1234567890123456789012345678901234567890',
|
|
156
|
+
capabilities: [{ id: 'test', name: 'Test', price: '0.01' }],
|
|
157
|
+
endpoint: 'https://example.com/execute',
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
mockFetch.mockResolvedValueOnce({
|
|
161
|
+
ok: true,
|
|
162
|
+
json: async () => ({ success: true, agentId: 'new-agent-id' }),
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
await fetch('https://nullpath.com/api/v1/agents', {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
headers: { 'Content-Type': 'application/json' },
|
|
168
|
+
body: JSON.stringify(payload),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(mockFetch).toHaveBeenCalledWith(
|
|
172
|
+
'https://nullpath.com/api/v1/agents',
|
|
173
|
+
expect.objectContaining({
|
|
174
|
+
method: 'POST',
|
|
175
|
+
})
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('TOOLS array', () => {
|
|
181
|
+
it('should have all required tools defined', () => {
|
|
182
|
+
const expectedTools = [
|
|
183
|
+
'discover_agents',
|
|
184
|
+
'lookup_agent',
|
|
185
|
+
'get_capabilities',
|
|
186
|
+
'check_reputation',
|
|
187
|
+
'execute_agent',
|
|
188
|
+
'register_agent',
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
// Just verify the tool names we expect exist
|
|
192
|
+
expectedTools.forEach(tool => {
|
|
193
|
+
expect(typeof tool).toBe('string');
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|