@hasna/hooks 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/LICENSE +1 -1
  2. package/bin/index.js +67 -3
  3. package/package.json +1 -1
package/LICENSE CHANGED
@@ -176,7 +176,7 @@
176
176
 
177
177
  END OF TERMS AND CONDITIONS
178
178
 
179
- Copyright 2025 Hasna
179
+ Copyright 2026 Hasna, Inc.
180
180
 
181
181
  Licensed under the Apache License, Version 2.0 (the "License");
182
182
  you may not use this file except in compliance with the License.
package/bin/index.js CHANGED
@@ -14633,6 +14633,65 @@ var init_server = __esm(() => {
14633
14633
  _hooksAgents = new Map;
14634
14634
  });
14635
14635
 
14636
+ // src/mcp/http.ts
14637
+ var exports_http = {};
14638
+ __export(exports_http, {
14639
+ startMcpHttpServer: () => startMcpHttpServer,
14640
+ resolveMcpHttpPort: () => resolveMcpHttpPort,
14641
+ isHttpMode: () => isHttpMode,
14642
+ healthPayload: () => healthPayload,
14643
+ handleMcpRequest: () => handleMcpRequest,
14644
+ MCP_SERVICE_NAME: () => MCP_SERVICE_NAME,
14645
+ MCP_HTTP_HOST: () => MCP_HTTP_HOST,
14646
+ DEFAULT_MCP_HTTP_PORT: () => DEFAULT_MCP_HTTP_PORT
14647
+ });
14648
+ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
14649
+ function isHttpMode(args) {
14650
+ return args.includes("--http") || process.env.MCP_HTTP === "1";
14651
+ }
14652
+ function resolveMcpHttpPort(args) {
14653
+ const portIdx = args.indexOf("--port");
14654
+ if (portIdx >= 0 && args[portIdx + 1]) {
14655
+ return Number(args[portIdx + 1]);
14656
+ }
14657
+ const envPort = process.env.MCP_HTTP_PORT;
14658
+ if (envPort)
14659
+ return Number(envPort);
14660
+ return DEFAULT_MCP_HTTP_PORT;
14661
+ }
14662
+ function healthPayload(name = MCP_SERVICE_NAME) {
14663
+ return { status: "ok", name };
14664
+ }
14665
+ async function handleMcpRequest(req, buildServer) {
14666
+ const transport = new WebStandardStreamableHTTPServerTransport({
14667
+ sessionIdGenerator: undefined
14668
+ });
14669
+ const server = buildServer();
14670
+ await server.connect(transport);
14671
+ return transport.handleRequest(req);
14672
+ }
14673
+ function startMcpHttpServer(options) {
14674
+ const { name, port, buildServer } = options;
14675
+ const server = Bun.serve({
14676
+ hostname: MCP_HTTP_HOST,
14677
+ port,
14678
+ async fetch(req) {
14679
+ const url = new URL(req.url);
14680
+ if (url.pathname === "/health" && req.method === "GET") {
14681
+ return Response.json(healthPayload(name));
14682
+ }
14683
+ if (url.pathname === "/mcp") {
14684
+ return handleMcpRequest(req, buildServer);
14685
+ }
14686
+ return new Response("Not Found", { status: 404 });
14687
+ }
14688
+ });
14689
+ console.error(`${name}-mcp HTTP listening on http://${MCP_HTTP_HOST}:${port}/mcp`);
14690
+ return server;
14691
+ }
14692
+ var DEFAULT_MCP_HTTP_PORT = 8847, MCP_HTTP_HOST = "127.0.0.1", MCP_SERVICE_NAME = "hooks";
14693
+ var init_http = () => {};
14694
+
14636
14695
  // src/cli/index.tsx
14637
14696
  import { render } from "ink";
14638
14697
 
@@ -16690,13 +16749,18 @@ logCmd.command("clear").description("Delete hook event logs").option("--hook <na
16690
16749
  }
16691
16750
  console.log(chalk2.green(`\u2713 Cleared ${count} event(s).`));
16692
16751
  });
16693
- program2.command("mcp").option("-s, --stdio", "Use stdio transport (for agent MCP integration)", false).option("-p, --port <port>", "Port for SSE transport", "39427").description("Start MCP server for AI agent integration").action(async (options) => {
16752
+ program2.command("mcp").option("-s, --stdio", "Use stdio transport (one process per agent)", false).option("--sse", "Use legacy SSE transport (port 39427)", false).option("--http", "Use Streamable HTTP transport (explicit; this is also the default)", false).option("-p, --port <port>", "Port for HTTP/SSE transport (defaults to 8847 for HTTP, 39427 for SSE)").description("Start MCP server for AI agent integration (default: shared Streamable HTTP)").action(async (options) => {
16694
16753
  if (options.stdio) {
16695
16754
  const { startStdioServer: startStdioServer2 } = await Promise.resolve().then(() => (init_server(), exports_server));
16696
16755
  await startStdioServer2();
16697
- } else {
16756
+ } else if (options.sse) {
16698
16757
  const { startSSEServer: startSSEServer2 } = await Promise.resolve().then(() => (init_server(), exports_server));
16699
- await startSSEServer2(parseInt(options.port));
16758
+ await startSSEServer2(options.port ? parseInt(options.port) : 39427);
16759
+ } else {
16760
+ const { createHooksServer: createHooksServer2 } = await Promise.resolve().then(() => (init_server(), exports_server));
16761
+ const { resolveMcpHttpPort: resolveMcpHttpPort2, startMcpHttpServer: startMcpHttpServer2 } = await Promise.resolve().then(() => (init_http(), exports_http));
16762
+ const args = options.port ? ["--port", options.port] : [];
16763
+ startMcpHttpServer2({ name: "hooks", port: resolveMcpHttpPort2(args), buildServer: createHooksServer2 });
16700
16764
  }
16701
16765
  });
16702
16766
  program2.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/hooks",
3
- "version": "0.2.13",
3
+ "version": "0.2.15",
4
4
  "description": "Open source hooks library for AI coding agents - Install safety, quality, and automation hooks with a single command",
5
5
  "type": "module",
6
6
  "bin": {