···11+import { getLogger } from "@logtape/logtape";
22+import type { ConsumerOptions } from "@cistern/consumer";
33+44+export function collectOptions(): ConsumerOptions {
55+ const logger = getLogger(["cistern", "mcp"]);
66+ const handle = Deno.env.get("CISTERN_MCP_HANDLE");
77+ const appPassword = Deno.env.get("CISTERN_MCP_APP_PASSWORD");
88+99+ if (!handle || !appPassword) {
1010+ logger.error(
1111+ "CISTERN_MCP_HANDLE or CISTERN_MCP_APP_PASSWORD are not set in the environment",
1212+ );
1313+ return Deno.exit(1);
1414+ }
1515+1616+ const privateKey = Deno.env.get("CISTERN_MCP_PRIVATE_KEY");
1717+ const publicKeyUri = Deno.env.get("CISTERN_MCP_PUBLIC_KEY_URI");
1818+1919+ return {
2020+ appPassword,
2121+ handle,
2222+ keypair: privateKey && publicKeyUri
2323+ ? {
2424+ privateKey,
2525+ publicKey: publicKeyUri,
2626+ }
2727+ : undefined,
2828+ };
2929+}
+5-1
packages/mcp/hono.ts
···11import { Hono } from "hono";
22import { cors } from "hono/cors";
33+import { createConsumer } from "@cistern/consumer";
34import { getLogger, withContext } from "@logtape/logtape";
45import { toFetchResponse, toReqRes } from "fetch-to-node";
56import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
77+import { collectOptions } from "./env.ts";
68import { createServer } from "./server.ts";
79810export function createApp() {
···7880 } else {
7981 logger.info("creating new session {sessionId}", { sessionId });
80828181- const server = createServer();
8383+ const options = collectOptions();
8484+ const consumer = await createConsumer(options);
8585+ const server = createServer(consumer);
82868387 session = new StreamableHTTPServerTransport({
8488 sessionIdGenerator: () => sessionId,
+8-1
packages/mcp/index.ts
···11import { parseArgs } from "@std/cli";
22+import { createConsumer } from "@cistern/consumer";
23import { AsyncLocalStorage } from "node:async_hooks";
34import { configure, getConsoleSink, getLogger } from "@logtape/logtape";
45import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5667import { createServer } from "./server.ts";
78import { createApp } from "./hono.ts";
99+import { collectOptions } from "./env.ts";
810911async function main() {
1012 await configure({
···3234 if (!args.http) {
3335 logger.info("starting in stdio mode");
34363737+ const options = collectOptions();
3838+ const consumer = await createConsumer(options);
3539 const transport = new StdioServerTransport();
3636- const server = createServer();
4040+ const server = createServer(consumer);
37413842 await server.connect(transport);
3943 } else {
4044 logger.info("starting in streamable HTTP mode");
4545+4646+ // Validate environment before starting the server
4747+ collectOptions();
41484249 const app = createApp();
4350
+2-1
packages/mcp/server.ts
···11import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22import { getLogger } from "@logtape/logtape";
33import { z } from "zod";
44+import type { Consumer } from "@cistern/consumer";
4555-export function createServer() {
66+export function createServer(consumer: Consumer) {
67 const logger = getLogger("cistern-mcp");
78 const server = new McpServer({
89 name: "cistern-mcp",