/**
 * Studiograph MCP server (stdio transport)
 *
 * Creates a McpServer instance, registers all tools, and connects via stdio
 * transport for integration with Claude Desktop and other MCP clients.
 *
 * Identity: requires STUDIOGRAPH_MCP_TOKEN to be set to a per-user API token
 * (or a JWT). The token is resolved against the workspace's AuthService to
 * produce the caller identity used by every tool's access control check.
 * Fails closed — if the token is missing or invalid the process exits.
 *
 * NOTE: All logging uses log.error() — stdout is reserved for the
 * JSON-RPC protocol messages and must not be written to directly.
 * log.error writes to stderr (via console.error under the hood), which
 * preserves the stdio-transport invariant.
 */
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
import { registerTools, MCP_SERVER_INFO, MCP_INSTRUCTIONS } from './tools.js';
import { log } from '../utils/log.js';
export async function startMcpServer(workspaceManager, authService) {
    const user = resolveStdioUser(authService);
    if (!user) {
        process.stderr.write('Studiograph MCP: STUDIOGRAPH_MCP_TOKEN is required.\n' +
            'Generate a token with:\n' +
            '  curl -X POST http://<host>/api/auth/tokens \\\n' +
            '       -H "Content-Type: application/json" \\\n' +
            '       -b __sg_token=<your-jwt> \\\n' +
            '       -d \'{"name":"claude-desktop"}\'\n' +
            'Then set STUDIOGRAPH_MCP_TOKEN=<token> in your Claude Desktop MCP config env.\n');
        process.exit(1);
    }
    const server = new McpServer(MCP_SERVER_INFO, { instructions: MCP_INSTRUCTIONS });
    registerTools(server, workspaceManager, authService, { user });
    const transport = new StdioServerTransport();
    await server.connect(transport);
    log.error(`Studiograph MCP server ready (user: ${user.email})`);
    // Keep the process alive — the transport closes when the client disconnects
    process.on('SIGINT', async () => {
        await server.close();
        process.exit(0);
    });
}
export function resolveStdioUser(authService) {
    const token = process.env.STUDIOGRAPH_MCP_TOKEN?.trim();
    if (!token)
        return null;
    return authService.verifyApiToken(token) ?? authService.verifyToken(token);
}
/**
 * Build an in-process MCP server (full tool surface, same as stdio/HTTP) and
 * return a connected `Client` wired to it over an in-memory transport. Used by
 * the stdio proxy as the LOCAL fallback when no live HTTP server is reachable —
 * in that case there is no open editor, so a direct write is safe.
 *
 * Identity is the resolved per-user `STUDIOGRAPH_MCP_TOKEN`, threaded through
 * `registerTools` exactly as the real stdio server does, so access control is
 * identical on both upstreams.
 */
export async function createInProcessMcpClient(workspaceManager, authService, user) {
    const server = new McpServer(MCP_SERVER_INFO, { instructions: MCP_INSTRUCTIONS });
    registerTools(server, workspaceManager, authService, { user });
    const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
    await server.connect(serverTransport);
    const client = new Client({ name: 'studiograph-stdio-proxy-local', version: '1.0.0' });
    await client.connect(clientTransport);
    return client;
}
//# sourceMappingURL=server.js.map