init project
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
import http from 'node:http';
|
||||
import { URL } from 'node:url';
|
||||
|
||||
const baseUrl = process.env.MCP_HTTP_URL ?? 'http://127.0.0.1:3940';
|
||||
const authToken = process.env.MCP_HTTP_TOKEN;
|
||||
|
||||
function request(path, body, headers = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = new URL(path, baseUrl);
|
||||
const postData = body ? JSON.stringify(body) : undefined;
|
||||
const req = http.request(
|
||||
{
|
||||
hostname: url.hostname,
|
||||
port: url.port,
|
||||
path: url.pathname,
|
||||
method: body ? 'POST' : 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json, text/event-stream',
|
||||
'Content-Type': 'application/json',
|
||||
...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
|
||||
...headers,
|
||||
...(postData ? { 'Content-Length': Buffer.byteLength(postData) } : {}),
|
||||
},
|
||||
},
|
||||
(res) => {
|
||||
let data = '';
|
||||
res.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
const parsedBody = parseSseBody(data);
|
||||
resolve({ status: res.statusCode, headers: res.headers, body: parsedBody });
|
||||
});
|
||||
},
|
||||
);
|
||||
req.on('error', reject);
|
||||
if (postData) req.write(postData);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
function parseSseBody(raw) {
|
||||
if (!raw.includes('event:')) return raw;
|
||||
const lines = raw.split(/\r?\n/);
|
||||
const dataLines = lines.filter((line) => line.startsWith('data:')).map((line) => line.slice(5).trim());
|
||||
return dataLines.join('');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const health = await request('/healthz');
|
||||
console.log('healthz:', health.status, health.body);
|
||||
|
||||
const init = await request('/mcp', {
|
||||
jsonrpc: '2.0',
|
||||
id: 1,
|
||||
method: 'initialize',
|
||||
params: {
|
||||
protocolVersion: '2024-11-05',
|
||||
capabilities: {},
|
||||
clientInfo: { name: 'http-smoke', version: '0.0.1' },
|
||||
},
|
||||
});
|
||||
console.log('initialize:', init.status, init.body);
|
||||
|
||||
if (init.status !== 200) {
|
||||
throw new Error(`initialize failed: ${init.body}`);
|
||||
}
|
||||
|
||||
const initResult = JSON.parse(init.body);
|
||||
const sessionId = init.headers['mcp-session-id'];
|
||||
console.log('sessionId:', sessionId);
|
||||
|
||||
const notif = await request('/mcp', {
|
||||
jsonrpc: '2.0',
|
||||
method: 'notifications/initialized',
|
||||
}, { 'mcp-session-id': sessionId });
|
||||
console.log('notifications/initialized:', notif.status, notif.body);
|
||||
|
||||
const resources = await request('/mcp', { jsonrpc: '2.0', id: 2, method: 'resources/list' }, { 'mcp-session-id': sessionId });
|
||||
console.log('resources/list:', resources.status, resources.body);
|
||||
|
||||
const prompts = await request('/mcp', { jsonrpc: '2.0', id: 3, method: 'prompts/list' }, { 'mcp-session-id': sessionId });
|
||||
console.log('prompts/list:', prompts.status, prompts.body);
|
||||
|
||||
const read = await request(
|
||||
'/mcp',
|
||||
{ jsonrpc: '2.0', id: 4, method: 'resources/read', params: { uri: 'workspace://project.json' } },
|
||||
{ 'mcp-session-id': sessionId },
|
||||
);
|
||||
console.log('resources/read:', read.status, read.body);
|
||||
|
||||
const expectedResourceUris = ['workspace://project.json'];
|
||||
const expectedPrompts = ['new-feature', 'new-laravel-resource', 'new-codeigniter-resource', 'new-react-component'];
|
||||
|
||||
let failed = false;
|
||||
const resourcesResult = JSON.parse(resources.body);
|
||||
const promptsResult = JSON.parse(prompts.body);
|
||||
const readResult = JSON.parse(read.body);
|
||||
|
||||
const staticUris = resourcesResult?.result?.resources?.map((r) => r.uri) ?? [];
|
||||
for (const uri of expectedResourceUris) {
|
||||
if (!staticUris.includes(uri)) {
|
||||
console.error(`Missing static resource: ${uri}`);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
const promptNames = promptsResult?.result?.prompts?.map((p) => p.name) ?? [];
|
||||
for (const name of expectedPrompts) {
|
||||
if (!promptNames.includes(name)) {
|
||||
console.error(`Missing prompt: ${name}`);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!readResult?.result?.contents?.[0]?.text) {
|
||||
console.error('resources/read failed', readResult);
|
||||
failed = true;
|
||||
}
|
||||
|
||||
console.log('Result:', failed ? 'FAILED' : 'OK');
|
||||
process.exit(failed ? 1 : 0);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user