Replace the xterm/PTY-based chat tab with a direct-to-API streaming chat UI that calls provider APIs (Anthropic, OpenAI) with SSE streaming and inline tool execution. - Extract 18 shared tools from MCP server into chat-tools.ts registry (knowledge, task, agent, model, web, shell, filesystem tools) - Add streaming adapters for Anthropic and OpenAI APIs (raw fetch, no SDK) - Add POST /api/chat SSE route with tool-use loop (max 10 rounds) - Rewrite chat-tab.tsx as message-based UI with model selector, streaming text, and collapsible tool call blocks - Refactor mcp-server.ts to consume shared tool registry
73 lines
2.1 KiB
JavaScript
73 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Harness MCP Server
|
|
*
|
|
* Stdio MCP server that exposes harness knowledge management and task
|
|
* orchestration tools to agents spawned by the harness orchestrator.
|
|
*
|
|
* Environment variables:
|
|
* DATABASE_URL — Postgres connection string (required)
|
|
* HARNESS_KNOWLEDGE_DIR — Path to knowledge documents directory
|
|
*/
|
|
|
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
import { toolRegistry } from "./lib/chat-tools";
|
|
|
|
// ── Database check ───────────────────────────────────────────
|
|
|
|
if (!process.env.DATABASE_URL) {
|
|
console.error("DATABASE_URL is required");
|
|
process.exit(1);
|
|
}
|
|
|
|
// ── Server ──────────────────────────────────────────────────
|
|
|
|
const server = new McpServer({
|
|
name: "harness",
|
|
version: "1.0.0",
|
|
});
|
|
|
|
// Register all tools from the shared registry
|
|
for (const tool of toolRegistry) {
|
|
if (tool.inputSchema) {
|
|
server.tool(
|
|
tool.name,
|
|
tool.description,
|
|
tool.inputSchema as any,
|
|
async (input: Record<string, unknown>) => {
|
|
const result = await tool.execute(input);
|
|
return {
|
|
content: [{ type: "text" as const, text: result.text }],
|
|
isError: result.isError,
|
|
};
|
|
},
|
|
);
|
|
} else {
|
|
server.tool(
|
|
tool.name,
|
|
tool.description,
|
|
async () => {
|
|
const result = await tool.execute({});
|
|
return {
|
|
content: [{ type: "text" as const, text: result.text }],
|
|
isError: result.isError,
|
|
};
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
// ── Start ───────────────────────────────────────────────────
|
|
|
|
async function main() {
|
|
const transport = new StdioServerTransport();
|
|
await server.connect(transport);
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error("Harness MCP server failed:", err);
|
|
process.exit(1);
|
|
});
|