@tiangong-lca/mcp-server 0.0.8 → 0.0.10
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 +8 -68
- package/dist/public/oauth-demo.html +371 -0
- package/dist/public/oauth-index.html +134 -0
- package/dist/src/_shared/auth_middleware.js +55 -5
- package/dist/src/_shared/cognito_auth.js +33 -0
- package/dist/src/_shared/config.js +13 -4
- package/dist/src/_shared/init_server.js +7 -1
- package/dist/src/_shared/init_server_http.js +7 -4
- package/dist/src/auth_app.js +356 -0
- package/dist/src/index_server.js +29 -0
- package/dist/src/prompts/lca_calculation.js +19 -0
- package/dist/src/resources/lca_calculation.js +16 -0
- package/dist/src/tools/flow_hybrid_search.js +12 -5
- package/dist/src/tools/lca_calculation_guidance.js +19 -0
- package/dist/src/tools/process_hybrid_search.js +5 -5
- package/package.json +13 -12
- package/dist/src/tools/_shared/clean_object.js +0 -22
- package/dist/src/tools/_shared/config.js +0 -4
- package/dist/src/tools/openlca_ipc copy.js +0 -1
- package/dist/src/tools/openlca_ipc.js +0 -57
|
@@ -4,15 +4,22 @@ import { supabase_anon_key, supabase_base_url, x_region } from '../_shared/confi
|
|
|
4
4
|
const input_schema = {
|
|
5
5
|
query: z.string().min(1).describe('Queries from user'),
|
|
6
6
|
};
|
|
7
|
-
async function searchFlows({ query }, bearerKey) {
|
|
7
|
+
async function searchFlows({ query }, bearerKey, xApiKey) {
|
|
8
8
|
const url = `${supabase_base_url}/functions/v1/flow_hybrid_search`;
|
|
9
|
+
const headers = {
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
Authorization: `Bearer ${bearerKey || supabase_anon_key}`,
|
|
12
|
+
...(xApiKey && { 'x-api-key': xApiKey }),
|
|
13
|
+
'x-region': x_region,
|
|
14
|
+
};
|
|
15
|
+
console.error('Headers:', headers);
|
|
9
16
|
try {
|
|
10
17
|
const response = await fetch(url, {
|
|
11
18
|
method: 'POST',
|
|
12
19
|
headers: {
|
|
13
20
|
'Content-Type': 'application/json',
|
|
14
|
-
Authorization: `Bearer ${supabase_anon_key}`,
|
|
15
|
-
...(
|
|
21
|
+
Authorization: `Bearer ${bearerKey || supabase_anon_key}`,
|
|
22
|
+
...(xApiKey && { 'x-api-key': xApiKey }),
|
|
16
23
|
'x-region': x_region,
|
|
17
24
|
},
|
|
18
25
|
body: JSON.stringify(cleanObject({
|
|
@@ -30,11 +37,11 @@ async function searchFlows({ query }, bearerKey) {
|
|
|
30
37
|
throw error;
|
|
31
38
|
}
|
|
32
39
|
}
|
|
33
|
-
export function regFlowSearchTool(server, bearerKey) {
|
|
40
|
+
export function regFlowSearchTool(server, bearerKey, xApiKey) {
|
|
34
41
|
server.tool('Search_flows_Tool', 'Search LCA flows data.', input_schema, async ({ query }) => {
|
|
35
42
|
const result = await searchFlows({
|
|
36
43
|
query,
|
|
37
|
-
}, bearerKey);
|
|
44
|
+
}, bearerKey, xApiKey);
|
|
38
45
|
return {
|
|
39
46
|
content: [
|
|
40
47
|
{
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
async function getLcaCalculationGuidance() {
|
|
2
|
+
const prompt = `The workflow to perform LCA calculations using the MCP tool is as follows:
|
|
3
|
+
1. Use the OpenLCA_Impact_Assessment_Tool to list all LCIA (Life Cycle Impact Assessment) method UUIDs and their corresponding names.
|
|
4
|
+
2. Use the OpenLCA_List_System_Processes_Tool to list all system process UUIDs and their corresponding names.
|
|
5
|
+
3. Use the OpenLCA_Impact_Assessment_Tool to perform LCA calculations.`;
|
|
6
|
+
return prompt;
|
|
7
|
+
}
|
|
8
|
+
export function regLcaCalculationGuidanceTool(server) {
|
|
9
|
+
server.tool('LCA_Calculation_Guidance_Tool', 'Get the workflow, which should be followed for Life Cycle Assessment (LCA) Calculations to Obtain Life Cycle Impact Assessment (LCIA) Results', async () => {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: 'text',
|
|
14
|
+
text: await getLcaCalculationGuidance(),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -4,15 +4,15 @@ import { supabase_anon_key, supabase_base_url, x_region } from '../_shared/confi
|
|
|
4
4
|
const input_schema = {
|
|
5
5
|
query: z.string().min(1).describe('Queries from user'),
|
|
6
6
|
};
|
|
7
|
-
async function searchProcesses({ query }, bearerKey) {
|
|
7
|
+
async function searchProcesses({ query }, bearerKey, xApiKey) {
|
|
8
8
|
const url = `${supabase_base_url}/functions/v1/process_hybrid_search`;
|
|
9
9
|
try {
|
|
10
10
|
const response = await fetch(url, {
|
|
11
11
|
method: 'POST',
|
|
12
12
|
headers: {
|
|
13
13
|
'Content-Type': 'application/json',
|
|
14
|
-
Authorization: `Bearer ${supabase_anon_key}`,
|
|
15
|
-
...(
|
|
14
|
+
Authorization: `Bearer ${bearerKey || supabase_anon_key}`,
|
|
15
|
+
...(xApiKey && { 'x-api-key': xApiKey }),
|
|
16
16
|
'x-region': x_region,
|
|
17
17
|
},
|
|
18
18
|
body: JSON.stringify(cleanObject({
|
|
@@ -30,11 +30,11 @@ async function searchProcesses({ query }, bearerKey) {
|
|
|
30
30
|
throw error;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
export function regProcessSearchTool(server, bearerKey) {
|
|
33
|
+
export function regProcessSearchTool(server, bearerKey, xApiKey) {
|
|
34
34
|
server.tool('Search_processes_Tool', 'Search LCA processes data.', input_schema, async ({ query }) => {
|
|
35
35
|
const result = await searchProcesses({
|
|
36
36
|
query,
|
|
37
|
-
}, bearerKey);
|
|
37
|
+
}, bearerKey, xApiKey);
|
|
38
38
|
return {
|
|
39
39
|
content: [
|
|
40
40
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiangong-lca/mcp-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "TianGong LCA MCP Server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nan LI",
|
|
@@ -16,27 +16,28 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsc && shx chmod +x dist/src/*.js",
|
|
19
|
+
"build": "shx rm -rf dist && tsc && shx cp -r public dist/ && shx chmod +x dist/src/*.js",
|
|
20
|
+
"build:clean": "shx rm -rf dist",
|
|
20
21
|
"start": "npm run build && npx dotenv -e .env -- npx @modelcontextprotocol/inspector node dist/src/index.js",
|
|
21
|
-
"start:server": "npm run build && concurrently \"npx dotenv -e .env -- node dist/src/index_server.js\" \"npx @modelcontextprotocol/inspector\"",
|
|
22
|
+
"start:server": "npm run build && concurrently \"npx dotenv -e .env -- node dist/src/index_server.js\" \"DANGEROUSLY_OMIT_AUTH=true npx @modelcontextprotocol/inspector\"",
|
|
22
23
|
"lint": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\""
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
|
-
"
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
27
|
+
"@supabase/supabase-js": "^2.51.0",
|
|
26
28
|
"@types/express": "^5.0.3",
|
|
27
|
-
"@
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"zod": "^3.25.
|
|
29
|
+
"@upstash/redis": "^1.35.1",
|
|
30
|
+
"aws-jwt-verify": "^5.1.0",
|
|
31
|
+
"olca-ipc": "^2.2.1",
|
|
32
|
+
"zod": "^3.25.76"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
|
-
"@modelcontextprotocol/inspector": "^0.
|
|
35
|
+
"@modelcontextprotocol/inspector": "^0.16.1",
|
|
34
36
|
"dotenv-cli": "^8.0.0",
|
|
35
|
-
"prettier": "^3.
|
|
37
|
+
"prettier": "^3.6.2",
|
|
36
38
|
"prettier-plugin-organize-imports": "^4.1.0",
|
|
37
39
|
"shx": "^0.4.0",
|
|
38
|
-
"
|
|
39
|
-
"tsx": "^4.19.4",
|
|
40
|
+
"tsx": "^4.20.3",
|
|
40
41
|
"typescript": "^5.8.3"
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const cleanObject = (obj) => {
|
|
2
|
-
if (Array.isArray(obj)) {
|
|
3
|
-
return obj
|
|
4
|
-
.map((v) => (typeof v === 'object' ? cleanObject(v) : v))
|
|
5
|
-
.filter((v) => v !== undefined && v !== null);
|
|
6
|
-
}
|
|
7
|
-
else if (typeof obj === 'object' && obj !== null) {
|
|
8
|
-
const cleanedObj = Object.entries(obj)
|
|
9
|
-
.map(([k, v]) => [k, cleanObject(v)])
|
|
10
|
-
.reduce((acc, [k, v]) => {
|
|
11
|
-
if (v !== undefined &&
|
|
12
|
-
v !== null &&
|
|
13
|
-
(typeof v !== 'object' || (typeof v === 'object' && Object.keys(v).length > 0))) {
|
|
14
|
-
acc[k] = v;
|
|
15
|
-
}
|
|
16
|
-
return acc;
|
|
17
|
-
}, {});
|
|
18
|
-
return cleanedObj;
|
|
19
|
-
}
|
|
20
|
-
return obj;
|
|
21
|
-
};
|
|
22
|
-
export default cleanObject;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import * as o from 'olca-ipc';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
const input_schema = {
|
|
4
|
-
systemProcess: z.string().min(1).describe('OpenLCA product system ID'),
|
|
5
|
-
impactMethod: z.string().min(1).describe('OpenLCA impact method ID'),
|
|
6
|
-
serverUrl: z.string().default('http://localhost:8080').describe('OpenLCA IPC server URL'),
|
|
7
|
-
};
|
|
8
|
-
async function calculateLcaImpacts({ systemProcess, impactMethod, serverUrl = 'http://localhost:8080', }) {
|
|
9
|
-
if (!systemProcess) {
|
|
10
|
-
throw new Error('No systemProcess provided');
|
|
11
|
-
}
|
|
12
|
-
if (!impactMethod) {
|
|
13
|
-
throw new Error('No impactMethod provided');
|
|
14
|
-
}
|
|
15
|
-
const client = o.IpcClient.on(serverUrl);
|
|
16
|
-
const selectedSystemProcess = await client.get(o.RefType.ProductSystem, systemProcess);
|
|
17
|
-
if (!selectedSystemProcess)
|
|
18
|
-
throw new Error('Product system not found');
|
|
19
|
-
const selectedMethod = await client.get(o.RefType.ImpactMethod, impactMethod);
|
|
20
|
-
if (!selectedMethod)
|
|
21
|
-
throw new Error('Impact method not found');
|
|
22
|
-
console.log('Calculating LCA impacts...');
|
|
23
|
-
const setup = o.CalculationSetup.of({
|
|
24
|
-
target: selectedSystemProcess,
|
|
25
|
-
impactMethod: selectedMethod,
|
|
26
|
-
});
|
|
27
|
-
const result = await client.calculate(setup);
|
|
28
|
-
const state = await result.untilReady();
|
|
29
|
-
if (state.error) {
|
|
30
|
-
throw new Error(`Calculation failed: ${state.error}`);
|
|
31
|
-
}
|
|
32
|
-
const impacts = await result.getTotalImpacts();
|
|
33
|
-
const resultsObj = impacts.map((impact) => ({
|
|
34
|
-
name: impact.impactCategory?.name,
|
|
35
|
-
value: impact.amount,
|
|
36
|
-
unit: impact.impactCategory?.refUnit,
|
|
37
|
-
}));
|
|
38
|
-
result.dispose();
|
|
39
|
-
return JSON.stringify(resultsObj);
|
|
40
|
-
}
|
|
41
|
-
export function regOpenLcaTool(server) {
|
|
42
|
-
server.tool('OpenLCA_Impact_Assessment_Tool', 'Calculate life cycle impact assessment using OpenLCA.', input_schema, async ({ systemProcess, impactMethod, serverUrl }) => {
|
|
43
|
-
const result = await calculateLcaImpacts({
|
|
44
|
-
systemProcess: systemProcess,
|
|
45
|
-
impactMethod: impactMethod,
|
|
46
|
-
serverUrl: serverUrl,
|
|
47
|
-
});
|
|
48
|
-
return {
|
|
49
|
-
content: [
|
|
50
|
-
{
|
|
51
|
-
type: 'text',
|
|
52
|
-
text: result,
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
}
|