#!/usr/bin/env node

/**
 * Vibn MCP Adapter for Zed
 * 
 * This script runs locally as a standard stdio MCP server for Zed.
 * It intercepts tool calls and forwards them over HTTP to the Vibn API
 * using the proprietary format that Vibn expects.
 */

const { Server } = require("@modelcontextprotocol/sdk/server/index.js");
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
const { CallToolRequestSchema, ListToolsRequestSchema } = require("@modelcontextprotocol/sdk/types.js");

// Configuration from environment variables
const VIBN_API_URL = process.env.VIBN_API_URL || "https://vibnai.com/api/mcp";
const VIBN_API_KEY = process.env.VIBN_API_KEY;

if (!VIBN_API_KEY) {
  console.error("Missing VIBN_API_KEY environment variable.");
  process.exit(1);
}

// Create the MCP server
const server = new Server(
  {
    name: "vibn-zed-adapter",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

let cachedTools = null;

// Fetch the tool list from the Vibn API
async function fetchTools() {
  if (cachedTools) return cachedTools;

  try {
    const response = await fetch(VIBN_API_URL, {
      method: "GET",
      headers: {
        Authorization: \`Bearer \${VIBN_API_KEY}\`,
      },
    });

    if (!response.ok) {
      throw new Error(\`Failed to fetch tools: \${response.statusText}\`);
    }

    const data = await response.json();
    
    // We need to fetch the actual tool schemas since the GET endpoint 
    // only returns a string array of tool names. 
    // For this adapter, we define the schema passthrough.
    
    // Note: Since Vibn's GET /api/mcp only returns an array of names:
    // "available": ["workspace.describe", "gitea.credentials", ...]
    // We will construct basic MCP tool definitions for them.
    // In a production scenario, you would expose the JSON schemas on the GET endpoint.
    
    const available = data.capabilities?.tools?.available || [];
    
    cachedTools = available.map(name => ({
      name: name,
      description: \`Vibn workspace tool: \${name}\`,
      inputSchema: {
        type: "object",
        properties: {
          // Accept any parameters generically for the proxy
          projectId: { type: "string", description: "Vibn project ID" },
        },
        additionalProperties: true
      }
    }));

    return cachedTools;
  } catch (error) {
    console.error("Error fetching tools:", error);
    return [];
  }
}

// Handle List Tools Request
server.setRequestHandler(ListToolsRequestSchema, async () => {
  const tools = await fetchTools();
  return {
    tools: tools,
  };
});

// Handle Call Tool Request
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  try {
    // Forward the request to Vibn API
    const response = await fetch(VIBN_API_URL, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: \`Bearer \${VIBN_API_KEY}\`,
      },
      body: JSON.stringify({
        tool: name,     // Vibn's expected format
        params: args || {},
      }),
    });

    const data = await response.json();

    if (!response.ok) {
      return {
        content: [
          {
            type: "text",
            text: \`Error (\${response.status}): \${JSON.stringify(data.error || data)}\`,
          },
        ],
        isError: true,
      };
    }

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(data.result || data, null, 2),
        },
      ],
    };
  } catch (error) {
    return {
      content: [
        {
          type: "text",
          text: \`Internal Adapter Error: \${error.message}\`,
        },
      ],
      isError: true,
    };
  }
});

// Start the server
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Vibn Zed MCP Adapter running on stdio");
}

main().catch((error) => {
  console.error("Fatal error:", error);
  process.exit(1);
});
