@siddharth.sharma/mcp-core 0.1.1 → 1.0.0
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/README.md +11 -1
- package/dist/dist/dist/index.d.ts +4 -0
- package/dist/dist/dist/index.js +3 -0
- package/dist/dist/dist/load-env.d.ts +5 -0
- package/dist/dist/dist/load-env.js +21 -0
- package/dist/dist/dist/read-secret-json.d.ts +6 -0
- package/dist/dist/dist/read-secret-json.js +26 -0
- package/dist/dist/dist/types.d.ts +39 -0
- package/dist/dist/dist/types.js +7 -0
- package/dist/dist/index.d.ts +4 -0
- package/dist/dist/index.js +3 -0
- package/dist/dist/load-env.d.ts +5 -0
- package/dist/dist/load-env.js +21 -0
- package/dist/dist/read-secret-json.d.ts +6 -0
- package/dist/dist/read-secret-json.js +26 -0
- package/dist/dist/types.d.ts +39 -0
- package/dist/dist/types.js +7 -0
- package/dist/index.d.ts +4 -0
- package/dist/load-env.d.ts +5 -0
- package/dist/read-secret-json.d.ts +6 -0
- package/dist/types.d.ts +39 -0
- package/docs/README.md +11 -0
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
# @siddharth.sharma/mcp-core
|
|
2
2
|
|
|
3
|
-
Shared runtime types and utilities used by
|
|
3
|
+
Shared runtime types and env utilities used by first-party Valkyrie MCP packages.
|
|
4
|
+
|
|
5
|
+
> `@siddharth.sharma/mcp-core` is an internal dependency package.
|
|
6
|
+
> It is not a standalone MCP server and is not intended to be run directly by end users.
|
|
7
|
+
|
|
8
|
+
This package has no standalone MCP server entrypoint; it is consumed by:
|
|
9
|
+
|
|
10
|
+
- `@siddharth.sharma/jenkins-mcp`
|
|
11
|
+
- `@siddharth.sharma/testrail-mcp`
|
|
12
|
+
- `@siddharth.sharma/db-mcp`
|
|
13
|
+
- `@siddharth.sharma/product-mcp-server`
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { FirstPartyMcpProduct, StreamableMcpProductConfig, StreamableMcpProductInput, StreamableMcpSessionBase, StreamableMcpSessionCreateContext, UserPlatformSecrets, ValkyriePlatformSecretKey, } from "./types.js";
|
|
2
|
+
export { VALKYRIE_PLATFORM_SECRET_KEYS } from "./types.js";
|
|
3
|
+
export { loadEnvFromAncestors } from "./load-env.js";
|
|
4
|
+
export { readSecretJsonRaw } from "./read-secret-json.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { config as loadDotenvFile } from "dotenv";
|
|
4
|
+
/**
|
|
5
|
+
* Populate process.env from the nearest `.env` walking up from `startDir`.
|
|
6
|
+
* Existing process.env values from shell/launcher take precedence.
|
|
7
|
+
*/
|
|
8
|
+
export function loadEnvFromAncestors(startDir, maxDepth = 16) {
|
|
9
|
+
let dir = resolve(startDir);
|
|
10
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
11
|
+
const envPath = resolve(dir, ".env");
|
|
12
|
+
if (existsSync(envPath)) {
|
|
13
|
+
loadDotenvFile({ path: envPath });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const parent = dirname(dir);
|
|
17
|
+
if (parent === dir)
|
|
18
|
+
break;
|
|
19
|
+
dir = parent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve raw secret JSON from env. Precedence:
|
|
5
|
+
* 1) inline JSON env var
|
|
6
|
+
* 2) file path env var
|
|
7
|
+
*/
|
|
8
|
+
export function readSecretJsonRaw(inlineEnvVar, fileEnvVar) {
|
|
9
|
+
const inline = process.env[inlineEnvVar]?.trim();
|
|
10
|
+
if (inline) {
|
|
11
|
+
return inline;
|
|
12
|
+
}
|
|
13
|
+
const filePath = process.env[fileEnvVar]?.trim();
|
|
14
|
+
if (!filePath) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const resolvedPath = resolve(filePath);
|
|
18
|
+
if (!existsSync(resolvedPath)) {
|
|
19
|
+
throw new Error(`Missing secret JSON file at ${resolvedPath} (from ${fileEnvVar})`);
|
|
20
|
+
}
|
|
21
|
+
const raw = readFileSync(resolvedPath, "utf8").trim();
|
|
22
|
+
if (!raw) {
|
|
23
|
+
throw new Error(`Secret JSON file is empty at ${resolvedPath} (from ${fileEnvVar})`);
|
|
24
|
+
}
|
|
25
|
+
return raw;
|
|
26
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
/** Minimal session shape — SDK transport handles MCP JSON-RPC. */
|
|
3
|
+
export type StreamableMcpSessionBase = {
|
|
4
|
+
transport: {
|
|
5
|
+
handleRequest(req: Request, res: Response, body: unknown): Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
/** Platform ids aligned with wrapper per-user secret paths (`…/{user}/{platform}`). */
|
|
9
|
+
export declare const VALKYRIE_PLATFORM_SECRET_KEYS: readonly ["jenkins", "testrail", "database", "product"];
|
|
10
|
+
export type ValkyriePlatformSecretKey = (typeof VALKYRIE_PLATFORM_SECRET_KEYS)[number];
|
|
11
|
+
/** Parsed JSON payloads keyed by integration; hub fills this from AWS SSM parameter storage. */
|
|
12
|
+
export type UserPlatformSecrets = Partial<Record<ValkyriePlatformSecretKey, Record<string, unknown>>>;
|
|
13
|
+
/** Passed into `createSession` on the first Streamable HTTP request (new session). */
|
|
14
|
+
export type StreamableMcpSessionCreateContext = {
|
|
15
|
+
/** From `x-valkyrie-user` when the gateway forwards it */
|
|
16
|
+
valkyrieUser?: string;
|
|
17
|
+
/** Per-integration secrets for this session (hub-loaded or injected in tests) */
|
|
18
|
+
userPlatformSecrets?: UserPlatformSecrets;
|
|
19
|
+
};
|
|
20
|
+
export type StreamableMcpProductConfig = {
|
|
21
|
+
id: string;
|
|
22
|
+
displayName: string;
|
|
23
|
+
version: string;
|
|
24
|
+
mcpServerName?: string;
|
|
25
|
+
mcpServerVersion?: string;
|
|
26
|
+
};
|
|
27
|
+
/** One MCP product mounted at `/${config.id}/mcp`. */
|
|
28
|
+
export type StreamableMcpProductInput<S extends StreamableMcpSessionBase> = {
|
|
29
|
+
config: StreamableMcpProductConfig;
|
|
30
|
+
toolCount: number;
|
|
31
|
+
sessions: Map<string, S>;
|
|
32
|
+
createSession(ctx?: StreamableMcpSessionCreateContext): Promise<S>;
|
|
33
|
+
/** GET probe without `Mcp-Session-Id` — defaults from options.fallbackProbeCapabilities */
|
|
34
|
+
probeCapabilities?: string[];
|
|
35
|
+
/** Default `name` in GET probe when `config.mcpServerName` is unset */
|
|
36
|
+
defaultMcpServerName?: string;
|
|
37
|
+
};
|
|
38
|
+
/** Canonical first-party integration contract used across Valkyrie packages. */
|
|
39
|
+
export type FirstPartyMcpProduct<S extends StreamableMcpSessionBase> = StreamableMcpProductInput<S>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { FirstPartyMcpProduct, StreamableMcpProductConfig, StreamableMcpProductInput, StreamableMcpSessionBase, StreamableMcpSessionCreateContext, UserPlatformSecrets, ValkyriePlatformSecretKey, } from "./types.js";
|
|
2
|
+
export { VALKYRIE_PLATFORM_SECRET_KEYS } from "./types.js";
|
|
3
|
+
export { loadEnvFromAncestors } from "./load-env.js";
|
|
4
|
+
export { readSecretJsonRaw } from "./read-secret-json.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { config as loadDotenvFile } from "dotenv";
|
|
4
|
+
/**
|
|
5
|
+
* Populate process.env from the nearest `.env` walking up from `startDir`.
|
|
6
|
+
* Existing process.env values from shell/launcher take precedence.
|
|
7
|
+
*/
|
|
8
|
+
export function loadEnvFromAncestors(startDir, maxDepth = 16) {
|
|
9
|
+
let dir = resolve(startDir);
|
|
10
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
11
|
+
const envPath = resolve(dir, ".env");
|
|
12
|
+
if (existsSync(envPath)) {
|
|
13
|
+
loadDotenvFile({ path: envPath });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const parent = dirname(dir);
|
|
17
|
+
if (parent === dir)
|
|
18
|
+
break;
|
|
19
|
+
dir = parent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve raw secret JSON from env. Precedence:
|
|
5
|
+
* 1) inline JSON env var
|
|
6
|
+
* 2) file path env var
|
|
7
|
+
*/
|
|
8
|
+
export function readSecretJsonRaw(inlineEnvVar, fileEnvVar) {
|
|
9
|
+
const inline = process.env[inlineEnvVar]?.trim();
|
|
10
|
+
if (inline) {
|
|
11
|
+
return inline;
|
|
12
|
+
}
|
|
13
|
+
const filePath = process.env[fileEnvVar]?.trim();
|
|
14
|
+
if (!filePath) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const resolvedPath = resolve(filePath);
|
|
18
|
+
if (!existsSync(resolvedPath)) {
|
|
19
|
+
throw new Error(`Missing secret JSON file at ${resolvedPath} (from ${fileEnvVar})`);
|
|
20
|
+
}
|
|
21
|
+
const raw = readFileSync(resolvedPath, "utf8").trim();
|
|
22
|
+
if (!raw) {
|
|
23
|
+
throw new Error(`Secret JSON file is empty at ${resolvedPath} (from ${fileEnvVar})`);
|
|
24
|
+
}
|
|
25
|
+
return raw;
|
|
26
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
/** Minimal session shape — SDK transport handles MCP JSON-RPC. */
|
|
3
|
+
export type StreamableMcpSessionBase = {
|
|
4
|
+
transport: {
|
|
5
|
+
handleRequest(req: Request, res: Response, body: unknown): Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
/** Platform ids aligned with wrapper per-user secret paths (`…/{user}/{platform}`). */
|
|
9
|
+
export declare const VALKYRIE_PLATFORM_SECRET_KEYS: readonly ["jenkins", "testrail", "database", "product"];
|
|
10
|
+
export type ValkyriePlatformSecretKey = (typeof VALKYRIE_PLATFORM_SECRET_KEYS)[number];
|
|
11
|
+
/** Parsed JSON payloads keyed by integration; hub fills this from AWS SSM parameter storage. */
|
|
12
|
+
export type UserPlatformSecrets = Partial<Record<ValkyriePlatformSecretKey, Record<string, unknown>>>;
|
|
13
|
+
/** Passed into `createSession` on the first Streamable HTTP request (new session). */
|
|
14
|
+
export type StreamableMcpSessionCreateContext = {
|
|
15
|
+
/** From `x-valkyrie-user` when the gateway forwards it */
|
|
16
|
+
valkyrieUser?: string;
|
|
17
|
+
/** Per-integration secrets for this session (hub-loaded or injected in tests) */
|
|
18
|
+
userPlatformSecrets?: UserPlatformSecrets;
|
|
19
|
+
};
|
|
20
|
+
export type StreamableMcpProductConfig = {
|
|
21
|
+
id: string;
|
|
22
|
+
displayName: string;
|
|
23
|
+
version: string;
|
|
24
|
+
mcpServerName?: string;
|
|
25
|
+
mcpServerVersion?: string;
|
|
26
|
+
};
|
|
27
|
+
/** One MCP product mounted at `/${config.id}/mcp`. */
|
|
28
|
+
export type StreamableMcpProductInput<S extends StreamableMcpSessionBase> = {
|
|
29
|
+
config: StreamableMcpProductConfig;
|
|
30
|
+
toolCount: number;
|
|
31
|
+
sessions: Map<string, S>;
|
|
32
|
+
createSession(ctx?: StreamableMcpSessionCreateContext): Promise<S>;
|
|
33
|
+
/** GET probe without `Mcp-Session-Id` — defaults from options.fallbackProbeCapabilities */
|
|
34
|
+
probeCapabilities?: string[];
|
|
35
|
+
/** Default `name` in GET probe when `config.mcpServerName` is unset */
|
|
36
|
+
defaultMcpServerName?: string;
|
|
37
|
+
};
|
|
38
|
+
/** Canonical first-party integration contract used across Valkyrie packages. */
|
|
39
|
+
export type FirstPartyMcpProduct<S extends StreamableMcpSessionBase> = StreamableMcpProductInput<S>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { FirstPartyMcpProduct, StreamableMcpProductConfig, StreamableMcpProductInput, StreamableMcpSessionBase, StreamableMcpSessionCreateContext, UserPlatformSecrets, ValkyriePlatformSecretKey, } from "./types.js";
|
|
2
|
+
export { VALKYRIE_PLATFORM_SECRET_KEYS } from "./types.js";
|
|
3
|
+
export { loadEnvFromAncestors } from "./load-env.js";
|
|
4
|
+
export { readSecretJsonRaw } from "./read-secret-json.js";
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
/** Minimal session shape — SDK transport handles MCP JSON-RPC. */
|
|
3
|
+
export type StreamableMcpSessionBase = {
|
|
4
|
+
transport: {
|
|
5
|
+
handleRequest(req: Request, res: Response, body: unknown): Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
/** Platform ids aligned with wrapper per-user secret paths (`…/{user}/{platform}`). */
|
|
9
|
+
export declare const VALKYRIE_PLATFORM_SECRET_KEYS: readonly ["jenkins", "testrail", "database", "product"];
|
|
10
|
+
export type ValkyriePlatformSecretKey = (typeof VALKYRIE_PLATFORM_SECRET_KEYS)[number];
|
|
11
|
+
/** Parsed JSON payloads keyed by integration; hub fills this from AWS SSM parameter storage. */
|
|
12
|
+
export type UserPlatformSecrets = Partial<Record<ValkyriePlatformSecretKey, Record<string, unknown>>>;
|
|
13
|
+
/** Passed into `createSession` on the first Streamable HTTP request (new session). */
|
|
14
|
+
export type StreamableMcpSessionCreateContext = {
|
|
15
|
+
/** From `x-valkyrie-user` when the gateway forwards it */
|
|
16
|
+
valkyrieUser?: string;
|
|
17
|
+
/** Per-integration secrets for this session (hub-loaded or injected in tests) */
|
|
18
|
+
userPlatformSecrets?: UserPlatformSecrets;
|
|
19
|
+
};
|
|
20
|
+
export type StreamableMcpProductConfig = {
|
|
21
|
+
id: string;
|
|
22
|
+
displayName: string;
|
|
23
|
+
version: string;
|
|
24
|
+
mcpServerName?: string;
|
|
25
|
+
mcpServerVersion?: string;
|
|
26
|
+
};
|
|
27
|
+
/** One MCP product mounted at `/${config.id}/mcp`. */
|
|
28
|
+
export type StreamableMcpProductInput<S extends StreamableMcpSessionBase> = {
|
|
29
|
+
config: StreamableMcpProductConfig;
|
|
30
|
+
toolCount: number;
|
|
31
|
+
sessions: Map<string, S>;
|
|
32
|
+
createSession(ctx?: StreamableMcpSessionCreateContext): Promise<S>;
|
|
33
|
+
/** GET probe without `Mcp-Session-Id` — defaults from options.fallbackProbeCapabilities */
|
|
34
|
+
probeCapabilities?: string[];
|
|
35
|
+
/** Default `name` in GET probe when `config.mcpServerName` is unset */
|
|
36
|
+
defaultMcpServerName?: string;
|
|
37
|
+
};
|
|
38
|
+
/** Canonical first-party integration contract used across Valkyrie packages. */
|
|
39
|
+
export type FirstPartyMcpProduct<S extends StreamableMcpSessionBase> = StreamableMcpProductInput<S>;
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# mcp-core package docs
|
|
2
|
+
|
|
3
|
+
Shared runtime helpers for first-party packages.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
- Environment loading utilities.
|
|
8
|
+
- Shared secret JSON parsing helpers.
|
|
9
|
+
- Shared runtime types.
|
|
10
|
+
|
|
11
|
+
This package intentionally has no runtime MCP server or secret sample payloads.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siddharth.sharma/mcp-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Shared Valkyrie MCP runtime types and env helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -14,11 +14,16 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"README.md"
|
|
17
|
+
"README.md",
|
|
18
|
+
"docs"
|
|
18
19
|
],
|
|
19
20
|
"engines": {
|
|
20
21
|
"node": ">=22.18.0"
|
|
21
22
|
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build:pkg": "tsc -p tsconfig.build.json",
|
|
25
|
+
"copy:assets": "cpy \"**/*\" \"dist\" --cwd \"../../src/mcp-core\" --parents --ignore \"**/*.ts\" --ignore \"**/*.tsx\" --ignore \"**/*.mts\" --ignore \"**/*.cts\" --ignore \"dist/**\" --ignore \"**/dist/**\""
|
|
26
|
+
},
|
|
22
27
|
"publishConfig": {
|
|
23
28
|
"registry": "https://registry.npmjs.org/",
|
|
24
29
|
"access": "public"
|