@hormonaly/mcp-server 1.0.1
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.
- package/dist/client.d.ts +21 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +58 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -0
- package/dist/tools.d.ts +460 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +766 -0
- package/dist/tools.js.map +1 -0
- package/hormonaly-mcp-config.json +13 -0
- package/package.json +60 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hormonaly API HTTP client
|
|
3
|
+
* Handles authentication and request routing for all API endpoints.
|
|
4
|
+
*/
|
|
5
|
+
export interface HoromnalyConfig {
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
helixApiKey?: string;
|
|
8
|
+
sessionToken?: string;
|
|
9
|
+
adminSessionToken?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class HoromnalyClient {
|
|
12
|
+
private config;
|
|
13
|
+
get apiUrl(): string;
|
|
14
|
+
constructor(config: HoromnalyConfig);
|
|
15
|
+
fetch(path: string, options?: RequestInit, authMode?: "helix" | "session" | "admin" | "public"): Promise<Response>;
|
|
16
|
+
get<T = unknown>(path: string, authMode?: "helix" | "session" | "admin" | "public"): Promise<T>;
|
|
17
|
+
post<T = unknown>(path: string, body: unknown, authMode?: "helix" | "session" | "admin" | "public"): Promise<T>;
|
|
18
|
+
}
|
|
19
|
+
/** Load config from environment variables */
|
|
20
|
+
export declare function loadConfig(overrides?: Partial<HoromnalyConfig>): HoromnalyConfig;
|
|
21
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAAkB;IAElC,IAAI,MAAM,IAAI,MAAM,CAEnB;gBAEW,MAAM,EAAE,eAAe;IAI7B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,EAAE,QAAQ,GAAE,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,QAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAmBhI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,QAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IASzG,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,GAAE,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,QAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;CAQhI;AAED,6CAA6C;AAC7C,wBAAgB,UAAU,CAAC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAQpF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hormonaly API HTTP client
|
|
3
|
+
* Handles authentication and request routing for all API endpoints.
|
|
4
|
+
*/
|
|
5
|
+
export class HoromnalyClient {
|
|
6
|
+
config;
|
|
7
|
+
get apiUrl() {
|
|
8
|
+
return this.config.apiUrl;
|
|
9
|
+
}
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async fetch(path, options = {}, authMode = "public") {
|
|
14
|
+
const url = `${this.config.apiUrl}${path}`;
|
|
15
|
+
const headers = {
|
|
16
|
+
"Content-Type": "application/json",
|
|
17
|
+
...(options.headers || {}),
|
|
18
|
+
};
|
|
19
|
+
if (authMode === "helix" && this.config.helixApiKey) {
|
|
20
|
+
headers["Authorization"] = `Bearer ${this.config.helixApiKey}`;
|
|
21
|
+
}
|
|
22
|
+
else if (authMode === "session" && this.config.sessionToken) {
|
|
23
|
+
headers["Cookie"] = `connect.sid=${this.config.sessionToken}`;
|
|
24
|
+
}
|
|
25
|
+
else if (authMode === "admin" && this.config.adminSessionToken) {
|
|
26
|
+
headers["Cookie"] = `connect.sid=${this.config.adminSessionToken}`;
|
|
27
|
+
}
|
|
28
|
+
const res = await fetch(url, { ...options, headers });
|
|
29
|
+
return res;
|
|
30
|
+
}
|
|
31
|
+
async get(path, authMode = "public") {
|
|
32
|
+
const res = await this.fetch(path, {}, authMode);
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const body = await res.text().catch(() => "");
|
|
35
|
+
throw new Error(`GET ${path} → HTTP ${res.status}: ${body.slice(0, 300)}`);
|
|
36
|
+
}
|
|
37
|
+
return res.json();
|
|
38
|
+
}
|
|
39
|
+
async post(path, body, authMode = "public") {
|
|
40
|
+
const res = await this.fetch(path, { method: "POST", body: JSON.stringify(body) }, authMode);
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
const errBody = await res.text().catch(() => "");
|
|
43
|
+
throw new Error(`POST ${path} → HTTP ${res.status}: ${errBody.slice(0, 300)}`);
|
|
44
|
+
}
|
|
45
|
+
return res.json();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Load config from environment variables */
|
|
49
|
+
export function loadConfig(overrides = {}) {
|
|
50
|
+
return {
|
|
51
|
+
apiUrl: overrides.apiUrl ?? process.env["HORMONALY_API_URL"] ?? "https://hormonaly.ai",
|
|
52
|
+
helixApiKey: overrides.helixApiKey ?? process.env["HORMONALY_API_KEY"],
|
|
53
|
+
sessionToken: overrides.sessionToken ?? process.env["HORMONALY_SESSION_TOKEN"],
|
|
54
|
+
adminSessionToken: overrides.adminSessionToken ?? process.env["HORMONALY_ADMIN_SESSION_TOKEN"],
|
|
55
|
+
...overrides,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Hormonaly MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes the Hormonaly evidence platform as MCP tools for Claude Desktop
|
|
6
|
+
* and other MCP-compatible AI agents.
|
|
7
|
+
*
|
|
8
|
+
* Transports:
|
|
9
|
+
* stdio — for Claude Desktop (default when no --http flag)
|
|
10
|
+
* HTTP — for remote agents (run with --http or HTTP_PORT env var)
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Hormonaly MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes the Hormonaly evidence platform as MCP tools for Claude Desktop
|
|
6
|
+
* and other MCP-compatible AI agents.
|
|
7
|
+
*
|
|
8
|
+
* Transports:
|
|
9
|
+
* stdio — for Claude Desktop (default when no --http flag)
|
|
10
|
+
* HTTP — for remote agents (run with --http or HTTP_PORT env var)
|
|
11
|
+
*/
|
|
12
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
13
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
14
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
15
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
16
|
+
import express from "express";
|
|
17
|
+
import { loadConfig, HoromnalyClient } from "./client.js";
|
|
18
|
+
import { TOOL_DEFINITIONS, handleTool } from "./tools.js";
|
|
19
|
+
// ─── Config ───────────────────────────────────────────────────────────────────
|
|
20
|
+
const config = loadConfig();
|
|
21
|
+
const client = new HoromnalyClient(config);
|
|
22
|
+
// ─── MCP Server ───────────────────────────────────────────────────────────────
|
|
23
|
+
function createServer() {
|
|
24
|
+
const server = new Server({
|
|
25
|
+
name: "hormonaly-mcp-server",
|
|
26
|
+
version: "1.0.0",
|
|
27
|
+
}, {
|
|
28
|
+
capabilities: {
|
|
29
|
+
tools: {},
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
// List all available tools
|
|
33
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
34
|
+
tools: TOOL_DEFINITIONS.map((t) => ({
|
|
35
|
+
name: t.name,
|
|
36
|
+
description: t.description,
|
|
37
|
+
inputSchema: t.inputSchema,
|
|
38
|
+
})),
|
|
39
|
+
}));
|
|
40
|
+
// Handle tool calls
|
|
41
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
42
|
+
const { name, arguments: args } = request.params;
|
|
43
|
+
if (!args || typeof args !== "object") {
|
|
44
|
+
throw new McpError(ErrorCode.InvalidParams, "Tool arguments must be an object");
|
|
45
|
+
}
|
|
46
|
+
const toolExists = TOOL_DEFINITIONS.some((t) => t.name === name);
|
|
47
|
+
if (!toolExists) {
|
|
48
|
+
throw new McpError(ErrorCode.MethodNotFound, `Tool not found: ${name}`);
|
|
49
|
+
}
|
|
50
|
+
return handleTool(name, args, client);
|
|
51
|
+
});
|
|
52
|
+
return server;
|
|
53
|
+
}
|
|
54
|
+
// ─── stdio transport (Claude Desktop) ─────────────────────────────────────────
|
|
55
|
+
async function runStdio() {
|
|
56
|
+
const server = createServer();
|
|
57
|
+
const transport = new StdioServerTransport();
|
|
58
|
+
await server.connect(transport);
|
|
59
|
+
// stderr only — stdout is reserved for MCP protocol
|
|
60
|
+
process.stderr.write("[Hormonaly MCP] Running on stdio transport\n");
|
|
61
|
+
}
|
|
62
|
+
// ─── HTTP/SSE transport (remote agents) ───────────────────────────────────────
|
|
63
|
+
async function runHttp(port) {
|
|
64
|
+
const app = express();
|
|
65
|
+
app.use(express.json());
|
|
66
|
+
// Track active SSE transports by session ID
|
|
67
|
+
const transports = new Map();
|
|
68
|
+
app.get("/health", (_req, res) => {
|
|
69
|
+
res.json({ status: "ok", server: "hormonaly-mcp", version: "1.0.0" });
|
|
70
|
+
});
|
|
71
|
+
// SSE endpoint — client connects here to receive messages
|
|
72
|
+
app.get("/sse", async (req, res) => {
|
|
73
|
+
const sessionId = String(req.query["sessionId"] ?? crypto.randomUUID());
|
|
74
|
+
const transport = new SSEServerTransport(`/messages?sessionId=${sessionId}`, res);
|
|
75
|
+
transports.set(sessionId, transport);
|
|
76
|
+
res.on("close", () => {
|
|
77
|
+
transports.delete(sessionId);
|
|
78
|
+
});
|
|
79
|
+
const server = createServer();
|
|
80
|
+
await server.connect(transport);
|
|
81
|
+
});
|
|
82
|
+
// Message endpoint — client POSTs tool calls here
|
|
83
|
+
app.post("/messages", async (req, res) => {
|
|
84
|
+
const sessionId = String(req.query["sessionId"] ?? "");
|
|
85
|
+
const transport = transports.get(sessionId);
|
|
86
|
+
if (!transport) {
|
|
87
|
+
res.status(404).json({ error: "Session not found. Connect to /sse first." });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
await transport.handlePostMessage(req, res);
|
|
91
|
+
});
|
|
92
|
+
app.listen(port, () => {
|
|
93
|
+
process.stderr.write(`[Hormonaly MCP] HTTP/SSE server running on http://localhost:${port}\n`);
|
|
94
|
+
process.stderr.write(`[Hormonaly MCP] SSE endpoint: GET http://localhost:${port}/sse\n`);
|
|
95
|
+
process.stderr.write(`[Hormonaly MCP] Message endpoint: POST http://localhost:${port}/messages\n`);
|
|
96
|
+
process.stderr.write(`[Hormonaly MCP] Health check: GET http://localhost:${port}/health\n`);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// ─── Entry point ──────────────────────────────────────────────────────────────
|
|
100
|
+
const useHttp = process.argv.includes("--http") || !!process.env["HTTP_PORT"];
|
|
101
|
+
const httpPort = parseInt(process.env["HTTP_PORT"] ?? "3100", 10);
|
|
102
|
+
if (useHttp) {
|
|
103
|
+
runHttp(httpPort).catch((e) => {
|
|
104
|
+
process.stderr.write(`[Hormonaly MCP] Fatal: ${e}\n`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
runStdio().catch((e) => {
|
|
110
|
+
process.stderr.write(`[Hormonaly MCP] Fatal: ${e}\n`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|