mizcausevic-dev/mcp-kinetic-gain
criticalUnified 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)
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};// 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.
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 },// 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.
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 },// 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.
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 },// 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.
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 });// 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.