// @bun
// src/application/mcp/common.ts
import { PresentationRegistry } from "@contractspec/lib.contracts-spec/presentations";
import { createMcpServer } from "@contractspec/lib.contracts-runtime-server-mcp/provider-mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
import { Elysia } from "elysia";
import { randomUUID } from "crypto";
var baseCtx = {
  actor: "anonymous",
  decide: async () => ({ effect: "allow" })
};
function createJsonRpcErrorResponse(status, code, message, data) {
  return new Response(JSON.stringify({
    jsonrpc: "2.0",
    error: {
      code,
      message,
      ...data ? { data } : {}
    },
    id: null
  }), {
    status,
    headers: {
      "content-type": "application/json"
    }
  });
}
function createSessionState({
  logger,
  serverName,
  ops,
  resources,
  prompts,
  presentations,
  stateful
}) {
  const server = new McpServer({
    name: serverName,
    version: "1.0.0"
  }, {
    capabilities: {
      tools: {},
      resources: {},
      prompts: {},
      logging: {}
    }
  });
  logger.info("Setting up MCP server...");
  createMcpServer(server, ops, resources, prompts, {
    logger,
    toolCtx: () => baseCtx,
    promptCtx: () => ({ locale: "en" }),
    resourceCtx: () => ({ locale: "en" }),
    presentations: new PresentationRegistry(presentations)
  });
  const transport = new WebStandardStreamableHTTPServerTransport({
    sessionIdGenerator: stateful ? () => randomUUID() : undefined,
    enableJsonResponse: true
  });
  return server.connect(transport).then(() => ({ server, transport }));
}
async function closeSessionState(state) {
  await Promise.allSettled([state.transport.close(), state.server.close()]);
}
function toErrorMessage(error) {
  return error instanceof Error ? error.stack ?? error.message : String(error);
}
function createMcpElysiaHandler({
  logger,
  path,
  serverName,
  ops,
  resources,
  prompts,
  presentations,
  validateAuth,
  requiredAuthMethods
}) {
  logger.info("Setting up MCP handler...", {
    requiredAuthMethods: requiredAuthMethods ?? []
  });
  const isStateful = process.env.CONTRACTSPEC_MCP_STATEFUL === "1";
  const sessions = new Map;
  async function handleStateless(request) {
    const state = await createSessionState({
      logger,
      path,
      serverName,
      ops,
      resources,
      prompts,
      presentations,
      stateful: false
    });
    try {
      return await state.transport.handleRequest(request);
    } finally {
      await closeSessionState(state);
    }
  }
  async function closeSession(sessionId) {
    const state = sessions.get(sessionId);
    if (!state)
      return;
    sessions.delete(sessionId);
    await closeSessionState(state);
  }
  async function handleStateful(request) {
    const requestedSessionId = request.headers.get("mcp-session-id");
    let state;
    let createdState = false;
    if (requestedSessionId) {
      const existing = sessions.get(requestedSessionId);
      if (!existing) {
        return createJsonRpcErrorResponse(404, -32001, "Session not found");
      }
      state = existing;
    } else {
      state = await createSessionState({
        logger,
        path,
        serverName,
        ops,
        resources,
        prompts,
        presentations,
        stateful: true
      });
      createdState = true;
    }
    try {
      const response = await state.transport.handleRequest(request);
      const activeSessionId = state.transport.sessionId;
      if (activeSessionId && !sessions.has(activeSessionId)) {
        sessions.set(activeSessionId, state);
      }
      if (request.method === "DELETE" && activeSessionId) {
        await closeSession(activeSessionId);
      } else if (!activeSessionId && createdState) {
        await closeSessionState(state);
      }
      return response;
    } catch (error) {
      if (createdState) {
        await closeSessionState(state);
      }
      throw error;
    }
  }
  return new Elysia({ name: `mcp-${serverName}` }).all(path, async ({ request }) => {
    try {
      if (validateAuth) {
        const authResult = await validateAuth(request);
        if (!authResult.valid) {
          return createJsonRpcErrorResponse(401, -32002, "Authentication failed", authResult.reason);
        }
      }
      if (isStateful) {
        return await handleStateful(request);
      }
      return await handleStateless(request);
    } catch (error) {
      logger.error("Error handling MCP request", {
        path,
        method: request.method,
        error: toErrorMessage(error)
      });
      return createJsonRpcErrorResponse(500, -32000, "Internal error");
    }
  });
}

// src/infrastructure/elysia/logger.ts
import { Logger, LogLevel } from "@contractspec/lib.logger";
var createAppLogger = () => new Logger({
  level: LogLevel.INFO,
  environment: "production",
  enableTracing: true,
  enableTiming: true,
  enableContext: true,
  enableColors: false
});
var appLogger = createAppLogger();
var dbLogger = new Logger({
  level: LogLevel.WARN,
  environment: "production",
  enableTracing: true,
  enableTiming: true,
  enableContext: true,
  enableColors: false
});
var authLogger = new Logger({
  level: LogLevel.INFO,
  environment: "production",
  enableTracing: true,
  enableTiming: true,
  enableContext: true,
  enableColors: false
});
// src/application/mcp/internalMcp.ts
import {
  defineCommand,
  definePrompt,
  defineResourceTemplate,
  installOp,
  OperationSpecRegistry,
  PromptRegistry,
  ResourceRegistry
} from "@contractspec/lib.contracts-spec";
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
import z from "zod";
import {
  getExample,
  listExamples,
  searchExamples
} from "@contractspec/module.examples";
var INTERNAL_TAGS = ["internal", "mcp"];
var INTERNAL_OWNERS = ["@contractspec"];
var ENDPOINTS = {
  docs: "/api/mcp/docs",
  cli: "/api/mcp/cli",
  internal: "/api/mcp/internal",
  graphql: "/graphql",
  health: "/health"
};
function buildInternalResources() {
  const resources = new ResourceRegistry;
  resources.register(defineResourceTemplate({
    meta: {
      uriTemplate: "examples://list{?q}",
      title: "ContractSpec examples registry",
      description: "List available examples (templates, integrations, knowledge, scripts). Optional query `q` filters results.",
      mimeType: "application/json",
      tags: ["examples", ...INTERNAL_TAGS]
    },
    input: z.object({ q: z.string().optional() }),
    resolve: async ({ q }) => {
      const items = q ? searchExamples(q) : [...listExamples()];
      return {
        uri: q ? `examples://list?q=${encodeURIComponent(q)}` : "examples://list",
        mimeType: "application/json",
        data: JSON.stringify(items, null, 2)
      };
    }
  }));
  resources.register(defineResourceTemplate({
    meta: {
      uriTemplate: "examples://example/{id}",
      title: "ContractSpec example (by id)",
      description: "Fetch a single example manifest by id.",
      mimeType: "application/json",
      tags: ["examples", ...INTERNAL_TAGS]
    },
    input: z.object({ id: z.string().min(1) }),
    resolve: async ({ id }) => {
      const example = getExample(id);
      if (!example) {
        return {
          uri: `examples://example/${encodeURIComponent(id)}`,
          mimeType: "application/json",
          data: JSON.stringify({ error: "not_found", id, message: `Unknown example id: ${id}` }, null, 2)
        };
      }
      return {
        uri: `examples://example/${encodeURIComponent(id)}`,
        mimeType: "application/json",
        data: JSON.stringify(example, null, 2)
      };
    }
  }));
  resources.register(defineResourceTemplate({
    meta: {
      uriTemplate: "internal://endpoints",
      title: "ContractSpec MCP endpoints",
      description: "Endpoints for docs, CLI, internal MCP servers.",
      mimeType: "application/json",
      tags: INTERNAL_TAGS
    },
    input: z.object({}),
    resolve: async () => ({
      uri: "internal://endpoints",
      mimeType: "application/json",
      data: JSON.stringify(ENDPOINTS, null, 2)
    })
  }));
  resources.register(defineResourceTemplate({
    meta: {
      uriTemplate: "internal://playbook",
      title: "Internal MCP usage playbook",
      description: "How internal agents should discover docs, CLI usage, and endpoints.",
      mimeType: "text/markdown",
      tags: INTERNAL_TAGS
    },
    input: z.object({}),
    resolve: async () => ({
      uri: "internal://playbook",
      mimeType: "text/markdown",
      data: [
        "# Internal MCP playbook",
        "- Connect to docs MCP first for canonical specs.",
        "- Use CLI MCP to surface quickstart/reference before running commands.",
        "- Keep calls read-only unless explicitly approved.",
        `- Endpoints: ${ENDPOINTS.docs}, ${ENDPOINTS.cli}, ${ENDPOINTS.internal}.`,
        "- For API work, GraphQL at /graphql; health at /health."
      ].join(`
`)
    })
  }));
  return resources;
}
function buildInternalPrompts() {
  const prompts = new PromptRegistry;
  prompts.register(definePrompt({
    meta: {
      key: "internal.bootstrap",
      version: "1.0.0",
      title: "Bootstrap internal ContractSpec agent",
      description: "Points agents to the correct MCP endpoints and guardrails.",
      tags: INTERNAL_TAGS,
      owners: INTERNAL_OWNERS,
      stability: "beta"
    },
    args: [],
    input: z.object({}),
    render: async () => [
      {
        type: "text",
        text: "Start with internal://endpoints to pick the right MCP. Use docs MCP for specifications and CLI MCP for commands. Keep actions read-only unless explicitly approved."
      },
      {
        type: "resource",
        uri: "internal://endpoints",
        title: "Endpoints"
      }
    ]
  }));
  return prompts;
}
function buildInternalOps() {
  const registry = new OperationSpecRegistry;
  const InternalDescribeOutput = defineSchemaModel({
    name: "InternalDescribeOutput",
    fields: {
      endpoints: {
        type: ScalarTypeEnum.JSONObject(),
        isOptional: false
      },
      notes: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
    }
  });
  const describeSpec = defineCommand({
    meta: {
      key: "internal.describe",
      version: "1.0.0",
      stability: "stable",
      owners: INTERNAL_OWNERS,
      tags: INTERNAL_TAGS,
      description: "Return MCP endpoints and guidance for internal ContractSpec agents.",
      goal: "Speed up internal development with the correct MCP entrypoints.",
      context: "Used by internal MCP surface; read-only."
    },
    io: {
      input: defineSchemaModel({
        name: "InternalDescribeInput",
        fields: {}
      }),
      output: InternalDescribeOutput
    },
    policy: {
      auth: "anonymous"
    }
  });
  installOp(registry, describeSpec, async () => ({
    endpoints: ENDPOINTS,
    notes: "Use docs MCP for canonical specs, CLI MCP for contractspec commands, and keep side-effecting actions gated behind human review."
  }));
  return registry;
}
function createInternalMcpHandler(path = "/api/mcp/internal") {
  return createMcpElysiaHandler({
    logger: appLogger,
    path,
    serverName: "contractspec-internal-mcp",
    ops: buildInternalOps(),
    resources: buildInternalResources(),
    prompts: buildInternalPrompts()
  });
}
export {
  createInternalMcpHandler
};
