@enfyra/mcp-server 0.0.94 → 0.0.95
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/package.json +1 -1
- package/src/mcp-server-entry.mjs +33 -6
package/package.json
CHANGED
package/src/mcp-server-entry.mjs
CHANGED
|
@@ -192,6 +192,21 @@ function getMetadataDatabaseContext(metadata, tables) {
|
|
|
192
192
|
|
|
193
193
|
function summarizeTable(table) {
|
|
194
194
|
if (!table) return null;
|
|
195
|
+
const relationFkColumnNames = new Set((table.relations || []).flatMap((relation) => {
|
|
196
|
+
const propertyName = relation.propertyName;
|
|
197
|
+
return propertyName
|
|
198
|
+
? [
|
|
199
|
+
`${propertyName}Id`,
|
|
200
|
+
`${propertyName}_id`,
|
|
201
|
+
relation.fkCol,
|
|
202
|
+
relation.fkColumn,
|
|
203
|
+
relation.foreignKeyColumn,
|
|
204
|
+
].filter(Boolean).map((name) => String(name).toLowerCase())
|
|
205
|
+
: [];
|
|
206
|
+
}));
|
|
207
|
+
const modelFacingColumns = (table.columns || []).filter((column) => (
|
|
208
|
+
column.isPrimary || !relationFkColumnNames.has(String(column.name || '').toLowerCase())
|
|
209
|
+
));
|
|
195
210
|
return {
|
|
196
211
|
id: table.id ?? table._id,
|
|
197
212
|
name: table.name,
|
|
@@ -199,7 +214,7 @@ function summarizeTable(table) {
|
|
|
199
214
|
primaryKey: getPrimaryColumn(table)?.name || null,
|
|
200
215
|
validateBody: table.validateBody,
|
|
201
216
|
graphqlEnabled: table.graphqlEnabled,
|
|
202
|
-
columns:
|
|
217
|
+
columns: modelFacingColumns.map((column) => ({
|
|
203
218
|
id: column.id ?? column._id,
|
|
204
219
|
name: column.name,
|
|
205
220
|
type: column.type,
|
|
@@ -209,6 +224,7 @@ function summarizeTable(table) {
|
|
|
209
224
|
isUpdatable: column.isUpdatable !== false,
|
|
210
225
|
isEncrypted: column.isEncrypted === true,
|
|
211
226
|
})),
|
|
227
|
+
hiddenRelationColumnCount: (table.columns || []).length - modelFacingColumns.length,
|
|
212
228
|
relations: (table.relations || []).map((relation) => ({
|
|
213
229
|
id: relation.id ?? relation._id,
|
|
214
230
|
propertyName: relation.propertyName,
|
|
@@ -844,12 +860,21 @@ server.tool(
|
|
|
844
860
|
tableName: z.string().optional().describe('Optional table name to summarize query fields and relation/deep capabilities.'),
|
|
845
861
|
},
|
|
846
862
|
async ({ tableName }) => {
|
|
847
|
-
const metadata =
|
|
848
|
-
|
|
849
|
-
|
|
863
|
+
const metadata = tableName
|
|
864
|
+
? await discoveryFetch(`/metadata/${encodeURIComponent(tableName)}`)
|
|
865
|
+
: null;
|
|
866
|
+
const routesResult = tableName
|
|
867
|
+
? await discoveryFetch('/enfyra_route?fields=path,mainTable.name,availableMethods.*,publicMethods.*,isEnabled&limit=1000')
|
|
868
|
+
: { data: [] };
|
|
869
|
+
const tableFromMetadata = tableName && !metadata?.error
|
|
870
|
+
? metadata?.data?.table || metadata?.data || metadata?.table || metadata
|
|
871
|
+
: null;
|
|
872
|
+
const tables = tableName
|
|
873
|
+
? (tableFromMetadata ? [tableFromMetadata] : [])
|
|
874
|
+
: [];
|
|
850
875
|
const routes = summarizeRoutes(routesResult);
|
|
851
876
|
const table = tableName ? tables.find((item) => item.name === tableName) : null;
|
|
852
|
-
const primaryKey = table ? getPrimaryColumn(table)?.name || 'id' :
|
|
877
|
+
const primaryKey = table ? getPrimaryColumn(table)?.name || 'id' : 'id';
|
|
853
878
|
const tableRoutes = tableName
|
|
854
879
|
? routes.filter((route) => route.mainTable === tableName)
|
|
855
880
|
: [];
|
|
@@ -885,7 +910,9 @@ server.tool(
|
|
|
885
910
|
],
|
|
886
911
|
},
|
|
887
912
|
backendNotes: {
|
|
888
|
-
primaryKey:
|
|
913
|
+
primaryKey: tableName
|
|
914
|
+
? 'Use this table metadata primary column when available.'
|
|
915
|
+
: 'SQL commonly uses id; Mongo uses _id. Use table metadata primary column when available.',
|
|
889
916
|
relationNames: 'API relation operations use relation propertyName, not physical FK column names.',
|
|
890
917
|
relationCascadeFkContract: 'When creating relations through create_table/create_relation/enfyra_table PATCH, never provide fkCol/fkColumn/foreignKeyColumn/sourceColumn/targetColumn/junction*Column. These are physical implementation details derived by Enfyra and hidden from app schema/forms.',
|
|
891
918
|
graphql: 'GraphQL query args also accept filter/sort/page/limit, but GraphQL requires Bearer auth and table enablement via enfyra_graphql.',
|