[ ⌘K ]
← BACK TO SEARCH

mizcausevic-dev/mcp-kinetic-gain

critical

Unified MCP server exposing all 5 Kinetic Gain Protocol Suite specs as tools (18 total across AEO, Prompt Provenance, Agent Cards, AI Evidence, MCP Tool Cards). One Claude Desktop config entry. Companion to kinetic-gain-visualizer.

MCP server (purpose undetermined)

purpose: MCP server (purpose undetermined)threat: network exposed
TypeScript0May 20, 2026May 20, 2026GITHUB
aeoagent-cardsanthropicclaudekinetic-gain-protocol-suitemcpmcp-servermodel-context-protocolprompt-provenanceprotocol-implementationtypescript
5/20/2026
high1 finding
src/server.ts
163export const handlers: Record<string, (args: any) => Promise<string>> = {
164  // AEO
165  aeo_fetch: handleAeoFetch,
166  aeo_inspect: handleAeoInspect,
167  aeo_get_claim: handleAeoGetClaim,
168  aeo_well_known_url: handleAeoWellKnownUrl,
169  // ...
170  tutor_card_fetch: handleTutorCardFetch,
171  // ...
172  aup_fetch: handleClassroomAupFetch,
173  // ...
174  clinical_ai_fetch: handleClinicalAiFetch,
175  // ...
176  incident_fetch: handleIncidentFetch,
177  // ...
178  decision_card_fetch: handleDecisionCardFetch,
179  // ...
180};
src/server.ts:163-250

// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or if LLM is compromised (local_only).

Multiple tools (aeo_fetch, tutor_card_fetch, aup_fetch, clinical_ai_fetch, incident_fetch, decision_card_fetch, and others) accept a URL parameter and fetch it without validation. The handlers are imported from separate files; the server.ts file shows the registration. The actual fetch logic is in the handler files, but the server exposes these tools. An attacker can provide arbitrary URLs, including internal network addresses (e.g., http://169.254.169.254/latest/meta-data/ for cloud metadata, or http://localhost:8080/ for internal services).

ImpactAn attacker (or a compromised LLM) can use the MCP server as a proxy to scan internal networks, access cloud metadata endpoints, or interact with internal services, potentially leading to information disclosure or further compromise.

FixImplement a URL allowlist or blocklist. Validate that the URL's host resolves to a public IP (not private, loopback, or link-local). Use a URL parser to reject non-HTTP(S) schemes. Consider requiring the user to pre-configure allowed origins.

high1 finding
src/tools.ts
551  {
552    name: "incident_index_fetch",
553    description: "HEADLINE TOOL — fetch a vendor's /.well-known/ai-incidents.json index ...",
554    inputSchema: {
555      type: "object",
556      required: ["origin"],
557      additionalProperties: false,
558      properties: {
559        origin: { type: "string", format: "uri", description: "Vendor origin (e.g. https://edu.kineticgain.com)." },
560      },
561    },
562  },
src/tools.ts:551-561

// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or if LLM is compromised (local_only).

The incident_index_fetch tool takes an 'origin' parameter and fetches a well-known path from it. The origin is not validated to be a safe, public URL. An attacker can supply an internal IP or a URL with a different scheme, causing the server to make requests to arbitrary hosts.

ImpactSame as above: SSRF to internal networks, cloud metadata, or other services.

FixValidate that the origin is a public HTTPS URL. Reject private IPs, loopback, and non-HTTP schemes.

high1 finding
src/tools.ts
811  {
812    name: "audit_event_emit",
813    description: "POST one governance event to a running audit-stream-py instance (env var AUDIT_STREAM_URL). ...",
814    inputSchema: { ... },
815  },
816  {
817    name: "audit_events_query",
818    description: "GET recent governance events from a running audit-stream-py instance (env var AUDIT_STREAM_URL) ...",
819    inputSchema: { ... },
820  },
821  {
822    name: "audit_chain_verify_live",
823    description: "Ask a running audit-stream-py instance to walk its own chain ...",
824    inputSchema: {},
825  },
src/tools.ts:811-876

// Exploitable if attacker can control environment variables (local_only) or if MCP is exposed to untrusted prompts (network_exposed).

These tools use the AUDIT_STREAM_URL environment variable to make HTTP requests. If an attacker can control this environment variable (e.g., via a compromised LLM or local access), they can redirect requests to arbitrary endpoints. Additionally, the tools do not validate the URL, so even if the env var is set, an attacker could potentially influence it through other means.

ImpactAn attacker could redirect audit events to a malicious server, exfiltrate data, or perform SSRF attacks against internal services.

FixValidate that AUDIT_STREAM_URL is a safe, internal URL (e.g., localhost or a known private network). Consider hardcoding the URL or using a configuration file that cannot be modified at runtime.

medium1 finding
src/tools.ts
133  {
134    name: "agent_card_inspect",
135    description: "Structured summary of an Agent Card document. Pass EITHER `url` (the server fetches it) OR `document_json` (already-fetched).",
136    inputSchema: {
137      type: "object",
138      additionalProperties: false,
139      properties: {
140        url: { type: "string", format: "uri" },
141        document_json: { type: "string" },
142      },
143    },
144  },
src/tools.ts:133-143

// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or if LLM is compromised (local_only).

Many tools (agent_card_inspect, tool_card_inspect, tutor_card_inspect, etc.) accept either a URL or a document_json string. While this is convenient, it means that even if URL fetching is restricted, an attacker can still pass arbitrary JSON via document_json. This could be used to bypass intended fetch restrictions or to inject malicious data that exploits parsing logic.

ImpactAn attacker could provide crafted JSON that triggers vulnerabilities in the parsing or validation logic (e.g., prototype pollution, denial of service).

FixConsider removing the document_json option or validating that the JSON conforms to expected schemas before processing. Alternatively, limit the size and depth of accepted JSON.

medium1 finding
src/server.ts
262  server.setRequestHandler(CallToolRequestSchema, async (request) => {
263    const { name, arguments: args } = request.params;
264    const handler = handlers[name];
265    if (!handler) {
266      return {
267        content: [{ type: "text", text: `unknown tool: ${name}` }],
268        isError: true,
269      };
270    }
271    try {
272      const result = await handler(args ?? {});
273      return { content: [{ type: "text", text: result }] };
274    } catch (err) {
275      const message = err instanceof Error ? err.message : String(err);
276      return { content: [{ type: "text", text: message }], isError: true };
277    }
278  });
src/server.ts:262-278

// Exploitable if any handler uses args unsafely; applies to both network_exposed and local_only.

The server passes the raw arguments object directly to each handler without any validation against the tool's inputSchema. While the SDK may validate the schema, the handlers themselves do not re-validate. If a handler expects a string but receives an object, it may behave unexpectedly. More critically, if a handler uses arguments in a dangerous way (e.g., constructing file paths or shell commands), missing validation could lead to injection attacks.

ImpactPotential for unexpected behavior or injection if handlers do not properly sanitize inputs. For example, a handler that constructs a URL from user input could be exploited for SSRF if it doesn't validate the input.

FixAdd input validation in each handler using the tool's inputSchema (e.g., using zod). Alternatively, use a middleware that validates args against the schema before calling the handler.

shell.execauth.noneenv.exposurefilesystem.readfilesystem.writenetwork.http
100
LLM-based
high findings+75
medium findings+30
scoringcompleted