@lifesi/genesis-mcp 0.1.7 → 0.1.8
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/minds.d.ts +46 -0
- package/dist/minds.js +27 -0
- package/dist/native-credentials.d.ts +9 -0
- package/dist/native-credentials.js +11 -0
- package/dist/server.js +4 -2
- package/dist/tools.js +9 -5
- package/package.json +11 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { createServer, createHttpServer, serveStdio } from './server.js';
|
|
2
2
|
export { tools, specTools, metaTools, searchTools, callTool } from './tools.js';
|
|
3
3
|
export declare function cli(args: string[]): Promise<void>;
|
|
4
|
+
export { nativeLoginCredentials } from './native-credentials.js';
|
package/dist/index.js
CHANGED
package/dist/minds.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type Genesis } from '@lifesi/genesis';
|
|
2
|
+
export declare function mindsInputSchema(id: string, schema: Record<string, unknown>): Record<string, unknown>;
|
|
3
|
+
export declare function callMindsTool(genesis: Genesis, id: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<{
|
|
4
|
+
schema_version: "minds.controller.v1";
|
|
5
|
+
items: import("@lifesi/genesis").components["schemas"]["Minds.Mind"][];
|
|
6
|
+
next_cursor: string | null;
|
|
7
|
+
context_sha256: string;
|
|
8
|
+
} | ({
|
|
9
|
+
schema_version: "minds.controller.v1";
|
|
10
|
+
mind_id: string;
|
|
11
|
+
organization_id: string;
|
|
12
|
+
project_id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
region: string;
|
|
15
|
+
plan: "free" | "pro";
|
|
16
|
+
capacity: import("@lifesi/genesis").components["schemas"]["Minds.Capacity"];
|
|
17
|
+
observed_capacity: import("@lifesi/genesis").components["schemas"]["Minds.Capacity"] | null;
|
|
18
|
+
services: string[];
|
|
19
|
+
volume_id: string;
|
|
20
|
+
base_url: string;
|
|
21
|
+
desired_state: "running" | "stopped" | "deleted";
|
|
22
|
+
observed_state: "pending" | "running" | "stopped" | "deleted" | "failed" | "uncertain";
|
|
23
|
+
desired_generation: number;
|
|
24
|
+
observed_generation: number;
|
|
25
|
+
status: "ready" | "provisioning" | "stopped" | "deleted" | "failed" | "uncertain";
|
|
26
|
+
capacity_applied: boolean;
|
|
27
|
+
operation_id: string | null;
|
|
28
|
+
error_code: string | null;
|
|
29
|
+
created_at: string;
|
|
30
|
+
updated_at: string;
|
|
31
|
+
} & {
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}) | {
|
|
34
|
+
item: import("@lifesi/genesis").components["schemas"]["Minds.EpisodicEvent"] | null;
|
|
35
|
+
} | {
|
|
36
|
+
id: string;
|
|
37
|
+
} | ({
|
|
38
|
+
id: string;
|
|
39
|
+
content: string;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
event_type: "Conversation" | "Command" | "Query" | "Document" | "Error" | "Success" | "Learning" | "Decision" | "Action" | "Context" | "Knowledge";
|
|
42
|
+
summary?: string | null;
|
|
43
|
+
tags: string[];
|
|
44
|
+
} & {
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
})[]>;
|
package/dist/minds.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { GenesisError } from '@lifesi/genesis';
|
|
2
|
+
export function mindsInputSchema(id, schema) {
|
|
3
|
+
if (id !== 'minds_createMind')
|
|
4
|
+
return schema;
|
|
5
|
+
return { ...schema, properties: { ...schema.properties,
|
|
6
|
+
idempotency_key: { type: 'string', format: 'uuid', description: 'Persisted UUID4 for this creation intent. Keep it after an uncertain outcome.' },
|
|
7
|
+
context_sha256: { type: 'string', pattern: '^[a-f0-9]{64}$', description: 'context_sha256 from the current Minds list; an assertion, not authority.' }, }, required: [...schema.required, 'idempotency_key', 'context_sha256'], additionalProperties: false };
|
|
8
|
+
}
|
|
9
|
+
export async function callMindsTool(genesis, id, args, signal) {
|
|
10
|
+
if (id === 'minds_listMinds')
|
|
11
|
+
return genesis.minds.list(args, { signal });
|
|
12
|
+
if (id === 'minds_getMind')
|
|
13
|
+
return genesis.request('minds_getMind', args, { signal });
|
|
14
|
+
if (id === 'minds_getEpisodicMemory')
|
|
15
|
+
return genesis.request('minds_getEpisodicMemory', args, { signal });
|
|
16
|
+
if (id === 'minds_insertEpisodicMemory')
|
|
17
|
+
return genesis.request('minds_insertEpisodicMemory', args, { signal });
|
|
18
|
+
if (id === 'minds_searchMemory')
|
|
19
|
+
return genesis.request('minds_searchMemory', args, { signal });
|
|
20
|
+
if (id === 'minds_createMind' && Object.keys(args).every(key => ['body', 'idempotency_key', 'context_sha256'].includes(key))
|
|
21
|
+
&& typeof args.idempotency_key === 'string' && typeof args.context_sha256 === 'string'
|
|
22
|
+
&& args.body && typeof args.body === 'object' && !Array.isArray(args.body)
|
|
23
|
+
&& Object.keys(args.body).length === 1 && typeof args.body.name === 'string') {
|
|
24
|
+
return genesis.minds.create(args.body.name, { idempotencyKey: args.idempotency_key, contextSha256: args.context_sha256, signal });
|
|
25
|
+
}
|
|
26
|
+
throw new GenesisError({ status: 0, type: 'invalid_request', operationId: id, message: 'Minds requires its exact input schema and retained creation context/key.' });
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CredentialStore } from '@lifesi/genesis-cli/store';
|
|
2
|
+
import type { CredentialProvider } from '@lifesi/genesis';
|
|
3
|
+
/** Reuse the CLI's exact OS-keychain entry and rotation; never print or export it.
|
|
4
|
+
* GenesisClient gives explicit options/environment credentials precedence. */
|
|
5
|
+
export declare function nativeLoginCredentials(options?: {
|
|
6
|
+
store?: () => Promise<CredentialStore>;
|
|
7
|
+
fetch?: typeof fetch;
|
|
8
|
+
env?: Record<string, string | undefined>;
|
|
9
|
+
}): CredentialProvider;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { authConfig, savedLoginProvider } from '@lifesi/genesis-cli/auth';
|
|
2
|
+
import { keychainStore } from '@lifesi/genesis-cli/store';
|
|
3
|
+
/** Reuse the CLI's exact OS-keychain entry and rotation; never print or export it.
|
|
4
|
+
* GenesisClient gives explicit options/environment credentials precedence. */
|
|
5
|
+
export function nativeLoginCredentials(options = {}) {
|
|
6
|
+
let provider;
|
|
7
|
+
return async () => {
|
|
8
|
+
provider ??= (async () => savedLoginProvider(authConfig(options.env ?? process.env, options.fetch ?? fetch), await (options.store ?? keychainStore)()))();
|
|
9
|
+
return await (await provider)();
|
|
10
|
+
};
|
|
11
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { nativeLoginCredentials } from './native-credentials.js';
|
|
1
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
4
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
@@ -5,12 +6,13 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
|
|
|
5
6
|
import http from 'node:http';
|
|
6
7
|
import { callTool, tools } from './tools.js';
|
|
7
8
|
export function createServer(opts = {}) {
|
|
8
|
-
const
|
|
9
|
+
const configured = { ...opts, credentials: opts.credentials ?? nativeLoginCredentials({ fetch: opts.fetch }) };
|
|
10
|
+
const server = new Server({ name: 'genesis', version: '0.1.8' }, {
|
|
9
11
|
capabilities: { tools: {} },
|
|
10
12
|
instructions: 'Genesis: one API for Foundry (inference), Hives (compute), Relays (DNS) and LifeID keys. Use the named tools for common tasks; use genesis_search_tools + genesis_call for anything else.',
|
|
11
13
|
});
|
|
12
14
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: tools() }));
|
|
13
|
-
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => callTool(
|
|
15
|
+
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => callTool(configured, req.params.name, (req.params.arguments ?? {}), extra.signal));
|
|
14
16
|
return server;
|
|
15
17
|
}
|
|
16
18
|
/** stdio: credential from GENESIS_API_KEY / GENESIS_TOKEN (or `credentials` provider). */
|
package/dist/tools.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mindsInputSchema, callMindsTool } from './minds.js';
|
|
1
2
|
import { callHivesResourceTool, hivesResourceInputSchema, isHivesResourceTool } from './hives-resources.js';
|
|
2
3
|
import { createHivesNodeTransport } from './hives-node-transport.js';
|
|
3
4
|
import { BEACONS_PROVISION_OPERATION, beaconsInputSchema, callBeaconsProvision } from './beacons.js';
|
|
@@ -9,7 +10,7 @@ const uploadSchema = { type: 'object', properties: {
|
|
|
9
10
|
filename: { type: 'string', maxLength: 255 },
|
|
10
11
|
git_sha: { type: 'string', minLength: 7, maxLength: 40 }, git_branch: { type: 'string', maxLength: 255 }, git_message: { type: 'string', maxLength: 1000 },
|
|
11
12
|
}, required: ['project_id', 'wasm_base64'], additionalProperties: false };
|
|
12
|
-
const inputSchema = (id, op) => isFoundryBillingOperation(id) ? { type: 'object', properties: ['foundry_ensureBillingProfile', 'foundry_createNativeCreditCheckout'].includes(id) ? { operation_key: { type: 'string', minLength: 1, maxLength: 255, description: 'Persisted original operation key; reconcile unknown outcomes before retrying.' } } : {}, required: ['foundry_ensureBillingProfile', 'foundry_createNativeCreditCheckout'].includes(id) ? ['operation_key'] : [], additionalProperties: false } : id === 'hives_upload_deployment' ? uploadSchema : fleetsInputSchema(id, beaconsInputSchema(id, hivesResourceInputSchema(id, op.inputSchema)));
|
|
13
|
+
const inputSchema = (id, op) => id.startsWith('minds_') ? mindsInputSchema(id, op.inputSchema) : isFoundryBillingOperation(id) ? { type: 'object', properties: ['foundry_ensureBillingProfile', 'foundry_createNativeCreditCheckout'].includes(id) ? { operation_key: { type: 'string', minLength: 1, maxLength: 255, description: 'Persisted original operation key; reconcile unknown outcomes before retrying.' } } : {}, required: ['foundry_ensureBillingProfile', 'foundry_createNativeCreditCheckout'].includes(id) ? ['operation_key'] : [], additionalProperties: false } : id === 'hives_upload_deployment' ? uploadSchema : fleetsInputSchema(id, beaconsInputSchema(id, hivesResourceInputSchema(id, op.inputSchema)));
|
|
13
14
|
const all = Object.entries(operationTable);
|
|
14
15
|
/** Operations callable by agents (everything except gateway-internal ones like credential verify). */
|
|
15
16
|
export const callable = all.filter(([, op]) => !op.internal);
|
|
@@ -18,7 +19,7 @@ function describe(id, op) {
|
|
|
18
19
|
return `${op.summary} (${op.method} ${op.path})${status}`;
|
|
19
20
|
}
|
|
20
21
|
const annotate = (op, id) => ({
|
|
21
|
-
readOnlyHint: op.method === 'GET', destructiveHint: id === 'hives_stop_deployment' || op.method === 'DELETE' || isHivesResourceTool(id) && /^hives_purge/.test(id),
|
|
22
|
+
readOnlyHint: op.method === 'GET' || id === 'minds_searchMemory', destructiveHint: id === 'hives_stop_deployment' || op.method === 'DELETE' || isHivesResourceTool(id) && /^hives_purge/.test(id),
|
|
22
23
|
idempotentHint: isHivesResourceTool(id) && op.method !== 'GET' ? false : ['GET', 'PUT', 'DELETE'].includes(op.method) || id === BEACONS_PROVISION_OPERATION || op.path === '/v1/iam/runner/self-execution-grant', openWorldHint: true,
|
|
23
24
|
});
|
|
24
25
|
/** Curated tools: one per operation tagged x-mcp in the merged spec. */
|
|
@@ -68,7 +69,10 @@ async function invoke(genesis, id, args, signal) {
|
|
|
68
69
|
return text(`Unknown operation "${id}". Use genesis_search_tools to find one.`, true);
|
|
69
70
|
try {
|
|
70
71
|
let r;
|
|
71
|
-
if (
|
|
72
|
+
if (op.service === 'minds') {
|
|
73
|
+
r = await callMindsTool(genesis, id, args, signal);
|
|
74
|
+
}
|
|
75
|
+
else if (isFoundryBillingOperation(id)) {
|
|
72
76
|
const mutation = ['foundry_ensureBillingProfile', 'foundry_createNativeCreditCheckout'].includes(id);
|
|
73
77
|
if (Object.keys(args).some(k => k !== 'operation_key') || (mutation ? typeof args.operation_key !== 'string' : Object.keys(args).length !== 0))
|
|
74
78
|
throw new Error('Native billing accepts only a persisted operation key for mutations.');
|
|
@@ -115,7 +119,7 @@ async function invoke(genesis, id, args, signal) {
|
|
|
115
119
|
}
|
|
116
120
|
catch (e) {
|
|
117
121
|
if (e instanceof GenesisError)
|
|
118
|
-
return text({ error: { type: e.type, status: e.status, message: e.message, request_id: e.requestId, ...(isFoundryBillingOperation(id) && e.body && typeof e.body === 'object' && 'outcome' in e.body ? { outcome: e.body.outcome } : {}) } }, true);
|
|
122
|
+
return text({ error: { type: e.type, status: e.status, message: e.message, request_id: e.requestId, ...((isFoundryBillingOperation(id) || op.service === 'minds') && e.body && typeof e.body === 'object' && 'outcome' in e.body ? { outcome: e.body.outcome } : {}) } }, true);
|
|
119
123
|
return text({ error: { type: 'network', message: e.message, hint: `The ${op.service} service may be unreachable (status: ${op.upstream.status}).` } }, true);
|
|
120
124
|
}
|
|
121
125
|
}
|
|
@@ -131,5 +135,5 @@ export async function callTool(opts, name, args = {}, signal) {
|
|
|
131
135
|
return text(`Unknown operation "${id}". Use genesis_search_tools to find one.`, true);
|
|
132
136
|
const hives = op.service === 'hives';
|
|
133
137
|
const genesis = new Genesis(hives ? { ...opts, fetch: createHivesNodeTransport(opts, signal) } : opts);
|
|
134
|
-
return invoke(genesis, id, input, hives || isFoundryBillingOperation(id) || op.service === 'blinds' || id === 'relays_getEnrollment' || id === 'relays_enroll' || isFleetsLifecycleTool(id) ? signal : undefined);
|
|
138
|
+
return invoke(genesis, id, input, hives || op.service === 'minds' || isFoundryBillingOperation(id) || op.service === 'blinds' || id === 'relays_getEnrollment' || id === 'relays_enroll' || isFleetsLifecycleTool(id) ? signal : undefined);
|
|
135
139
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifesi/genesis-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/l1felabs/genesis-api.git",
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
},
|
|
9
9
|
"description": "Genesis MCP server (stdio + streamable HTTP): tools generated from the Genesis OpenAPI",
|
|
10
10
|
"type": "module",
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
11
19
|
"bin": {
|
|
12
20
|
"genesis-mcp": "bin/genesis-mcp.js"
|
|
13
21
|
},
|
|
@@ -18,7 +26,8 @@
|
|
|
18
26
|
"dependencies": {
|
|
19
27
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
20
28
|
"undici": "6.29.0",
|
|
21
|
-
"@lifesi/genesis": "0.1.
|
|
29
|
+
"@lifesi/genesis": "0.1.8",
|
|
30
|
+
"@lifesi/genesis-cli": "0.1.8"
|
|
22
31
|
},
|
|
23
32
|
"scripts": {
|
|
24
33
|
"build": "tsc -p tsconfig.json"
|