Encrypted, ephemeral, private memos on atproto
1import { parseArgs } from "@std/cli";
2import { AsyncLocalStorage } from "node:async_hooks";
3import { configure, getConsoleSink, getLogger } from "@logtape/logtape";
4import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
6import { createServer } from "./server.ts";
7import { createApp } from "./hono.ts";
8import { collectOptions } from "./env.ts";
9
10async function main() {
11 await configure({
12 sinks: { console: getConsoleSink() },
13 loggers: [
14 {
15 category: ["cistern", "mcp"],
16 lowestLevel: "trace",
17 sinks: ["console"],
18 },
19 {
20 category: ["cistern", "http"],
21 lowestLevel: "info",
22 sinks: ["console"],
23 },
24 ],
25 contextLocalStorage: new AsyncLocalStorage(),
26 });
27
28 const logger = getLogger(["cistern", "mcp"]);
29 const args = parseArgs(Deno.args, {
30 boolean: ["http"],
31 });
32
33 if (!args.http) {
34 logger.info("starting in stdio mode");
35
36 const options = collectOptions();
37 const server = await createServer(options);
38 const transport = new StdioServerTransport();
39
40 await server.connect(transport);
41 } else {
42 logger.info("starting in streamable HTTP mode");
43
44 // Validate environment before starting the server
45 collectOptions();
46
47 const app = createApp();
48
49 Deno.serve(
50 {
51 onListen(addr) {
52 logger.info("http server listening at {hostname} on port {port}", {
53 ...addr,
54 });
55 },
56 },
57 app.fetch,
58 );
59 }
60}
61
62await main();