mcp-quickbase 2.1.0 → 2.2.0

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.
Files changed (38) hide show
  1. package/.sdd/tickets/RELS_relationship-management/README.md +98 -0
  2. package/.sdd/tickets/RELS_relationship-management/planning/analysis.md +190 -0
  3. package/.sdd/tickets/RELS_relationship-management/planning/architecture.md +413 -0
  4. package/.sdd/tickets/RELS_relationship-management/planning/plan.md +177 -0
  5. package/.sdd/tickets/RELS_relationship-management/planning/quality-strategy.md +335 -0
  6. package/.sdd/tickets/RELS_relationship-management/planning/review-updates.md +95 -0
  7. package/.sdd/tickets/RELS_relationship-management/planning/security-review.md +213 -0
  8. package/.sdd/tickets/RELS_relationship-management/planning/ticket-review.md +885 -0
  9. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1001_domain-setup.md +96 -0
  10. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1002_get-relationships-tool.md +142 -0
  11. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1003_register-phase1-tools.md +105 -0
  12. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.2001_create-relationship-tool.md +151 -0
  13. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.2002_update-relationship-tool.md +145 -0
  14. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.3001_delete-relationship-tool.md +154 -0
  15. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.4001_integration-testing.md +159 -0
  16. package/.sdd/tickets/RELS_relationship-management/tasks/RELS.4002_final-verification.md +182 -0
  17. package/.sdd/tickets/RELS_relationship-management/tasks/RELS_TASK_INDEX.md +179 -0
  18. package/dist/tools/apps/list_tables.d.ts +5 -5
  19. package/dist/tools/apps/list_tables.js +1 -1
  20. package/dist/tools/index.d.ts +1 -0
  21. package/dist/tools/index.js +4 -1
  22. package/dist/tools/index.js.map +1 -1
  23. package/dist/tools/relationships/create_relationship.d.ts +150 -0
  24. package/dist/tools/relationships/create_relationship.js +181 -0
  25. package/dist/tools/relationships/create_relationship.js.map +1 -0
  26. package/dist/tools/relationships/delete_relationship.d.ts +66 -0
  27. package/dist/tools/relationships/delete_relationship.js +85 -0
  28. package/dist/tools/relationships/delete_relationship.js.map +1 -0
  29. package/dist/tools/relationships/get_relationships.d.ts +126 -0
  30. package/dist/tools/relationships/get_relationships.js +126 -0
  31. package/dist/tools/relationships/get_relationships.js.map +1 -0
  32. package/dist/tools/relationships/index.d.ts +14 -0
  33. package/dist/tools/relationships/index.js +37 -0
  34. package/dist/tools/relationships/index.js.map +1 -0
  35. package/dist/tools/relationships/update_relationship.d.ts +139 -0
  36. package/dist/tools/relationships/update_relationship.js +168 -0
  37. package/dist/tools/relationships/update_relationship.js.map +1 -0
  38. package/package.json +1 -1
@@ -0,0 +1,126 @@
1
+ import { BaseTool } from "../base";
2
+ import { QuickbaseClient } from "../../client/quickbase";
3
+ /**
4
+ * Field information in a relationship
5
+ */
6
+ export interface RelationshipFieldInfo {
7
+ /**
8
+ * The ID of the field
9
+ */
10
+ id: number;
11
+ /**
12
+ * The label (display name) of the field
13
+ */
14
+ label: string;
15
+ /**
16
+ * The type of the field
17
+ */
18
+ type: string;
19
+ }
20
+ /**
21
+ * Relationship between two tables
22
+ */
23
+ export interface Relationship {
24
+ /**
25
+ * The ID of the relationship (same as the foreign key field ID)
26
+ */
27
+ id: number;
28
+ /**
29
+ * The ID of the parent table
30
+ */
31
+ parentTableId: string;
32
+ /**
33
+ * The ID of the child table
34
+ */
35
+ childTableId: string;
36
+ /**
37
+ * The foreign key field in the child table
38
+ */
39
+ foreignKeyField: RelationshipFieldInfo;
40
+ /**
41
+ * Whether this is a cross-app relationship
42
+ */
43
+ isCrossApp: boolean;
44
+ /**
45
+ * Lookup fields in the child table that pull data from the parent
46
+ */
47
+ lookupFields: RelationshipFieldInfo[];
48
+ /**
49
+ * Summary fields in the parent table that aggregate data from the child
50
+ */
51
+ summaryFields: RelationshipFieldInfo[];
52
+ }
53
+ /**
54
+ * Parameters for get_relationships tool
55
+ */
56
+ export interface GetRelationshipsParams {
57
+ /**
58
+ * The ID of the table to get relationships for
59
+ */
60
+ table_id: string;
61
+ /**
62
+ * Number of relationships to skip (for pagination)
63
+ */
64
+ skip?: number;
65
+ }
66
+ /**
67
+ * Response from getting relationships
68
+ */
69
+ export interface GetRelationshipsResult {
70
+ /**
71
+ * Array of relationships
72
+ */
73
+ relationships: Relationship[];
74
+ /**
75
+ * Metadata about the response
76
+ */
77
+ metadata: {
78
+ /**
79
+ * Total number of relationships for the table
80
+ */
81
+ totalRelationships: number;
82
+ /**
83
+ * Number of relationships returned in this response
84
+ */
85
+ numRelationships: number;
86
+ /**
87
+ * Number of relationships skipped
88
+ */
89
+ skip: number;
90
+ };
91
+ }
92
+ /**
93
+ * Tool for retrieving all table-to-table relationships for a specified table
94
+ */
95
+ export declare class GetRelationshipsTool extends BaseTool<GetRelationshipsParams, GetRelationshipsResult> {
96
+ name: string;
97
+ description: string;
98
+ /**
99
+ * Parameter schema for get_relationships
100
+ */
101
+ paramSchema: {
102
+ type: string;
103
+ properties: {
104
+ table_id: {
105
+ type: string;
106
+ description: string;
107
+ };
108
+ skip: {
109
+ type: string;
110
+ description: string;
111
+ };
112
+ };
113
+ required: string[];
114
+ };
115
+ /**
116
+ * Constructor
117
+ * @param client Quickbase client
118
+ */
119
+ constructor(client: QuickbaseClient);
120
+ /**
121
+ * Run the get_relationships tool
122
+ * @param params Tool parameters
123
+ * @returns Relationships for the table
124
+ */
125
+ protected run(params: GetRelationshipsParams): Promise<GetRelationshipsResult>;
126
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetRelationshipsTool = void 0;
4
+ const base_1 = require("../base");
5
+ const logger_1 = require("../../utils/logger");
6
+ const logger = (0, logger_1.createLogger)("GetRelationshipsTool");
7
+ /**
8
+ * Tool for retrieving all table-to-table relationships for a specified table
9
+ */
10
+ class GetRelationshipsTool extends base_1.BaseTool {
11
+ /**
12
+ * Constructor
13
+ * @param client Quickbase client
14
+ */
15
+ constructor(client) {
16
+ super(client);
17
+ this.name = "get_relationships";
18
+ this.description = "Gets all table-to-table relationships for a specified table. Returns both relationships " +
19
+ "where this table is the child (has reference fields pointing to parents) and where this " +
20
+ "table is the parent (has child tables referencing it). Use this tool to explore table " +
21
+ "structure and understand data connections before modifying relationships.";
22
+ /**
23
+ * Parameter schema for get_relationships
24
+ */
25
+ this.paramSchema = {
26
+ type: "object",
27
+ properties: {
28
+ table_id: {
29
+ type: "string",
30
+ description: "The ID of the Quickbase table (DBID)",
31
+ },
32
+ skip: {
33
+ type: "number",
34
+ description: "Number of relationships to skip for pagination (default: 0)",
35
+ },
36
+ },
37
+ required: ["table_id"],
38
+ };
39
+ }
40
+ /**
41
+ * Run the get_relationships tool
42
+ * @param params Tool parameters
43
+ * @returns Relationships for the table
44
+ */
45
+ async run(params) {
46
+ const { table_id, skip = 0 } = params;
47
+ logger.info("Getting relationships for table", { tableId: table_id, skip });
48
+ // Prepare query parameters
49
+ const queryParams = {};
50
+ if (skip > 0) {
51
+ queryParams.skip = skip.toString();
52
+ }
53
+ // Get relationships for the table
54
+ const response = await this.client.request({
55
+ method: "GET",
56
+ path: `/tables/${table_id}/relationships`,
57
+ params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
58
+ });
59
+ if (!response.success || !response.data) {
60
+ logger.error("Failed to get relationships", {
61
+ error: response.error,
62
+ tableId: table_id,
63
+ });
64
+ throw new Error(response.error?.message || "Failed to get relationships");
65
+ }
66
+ // Parse and validate the API response
67
+ const data = response.data;
68
+ // Validate relationships array exists
69
+ const rawRelationships = data.relationships;
70
+ if (!Array.isArray(rawRelationships)) {
71
+ logger.error("Relationships response missing relationships array", {
72
+ data,
73
+ });
74
+ throw new Error("Relationships response does not contain relationships array");
75
+ }
76
+ // Transform API response to our interface
77
+ const relationships = rawRelationships.map((rel) => {
78
+ const foreignKeyField = rel.foreignKeyField;
79
+ const lookupFields = rel.lookupFields;
80
+ const summaryFields = rel.summaryFields;
81
+ return {
82
+ id: rel.id,
83
+ parentTableId: rel.parentTableId,
84
+ childTableId: rel.childTableId,
85
+ foreignKeyField: foreignKeyField
86
+ ? {
87
+ id: foreignKeyField.id,
88
+ label: foreignKeyField.label,
89
+ type: foreignKeyField.type,
90
+ }
91
+ : { id: 0, label: "", type: "" },
92
+ isCrossApp: rel.isCrossApp || false,
93
+ lookupFields: (lookupFields || []).map((field) => ({
94
+ id: field.id,
95
+ label: field.label,
96
+ type: field.type,
97
+ })),
98
+ summaryFields: (summaryFields || []).map((field) => ({
99
+ id: field.id,
100
+ label: field.label,
101
+ type: field.type,
102
+ })),
103
+ };
104
+ });
105
+ // Extract metadata from response
106
+ const metadata = data.metadata;
107
+ const totalRelationships = metadata?.totalRelationships ?? relationships.length;
108
+ const numRelationships = metadata?.numRelationships ?? relationships.length;
109
+ logger.info(`Found ${relationships.length} relationships for table`, {
110
+ tableId: table_id,
111
+ totalRelationships,
112
+ numRelationships,
113
+ skip,
114
+ });
115
+ return {
116
+ relationships,
117
+ metadata: {
118
+ totalRelationships,
119
+ numRelationships,
120
+ skip,
121
+ },
122
+ };
123
+ }
124
+ }
125
+ exports.GetRelationshipsTool = GetRelationshipsTool;
126
+ //# sourceMappingURL=get_relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_relationships.js","sourceRoot":"","sources":["../../../src/tools/relationships/get_relationships.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { QuickbaseClient } from "../../client/quickbase";
2
+ /**
3
+ * Register all relationship management tools with the registry
4
+ * @param client Quickbase client
5
+ */
6
+ export declare function registerRelationshipTools(client: QuickbaseClient): void;
7
+ export { GetRelationshipsTool } from "./get_relationships";
8
+ export type { GetRelationshipsParams, GetRelationshipsResult, Relationship, RelationshipFieldInfo, } from "./get_relationships";
9
+ export { CreateRelationshipTool } from "./create_relationship";
10
+ export type { CreateRelationshipParams, CreateRelationshipResult, SummaryAccumulationType, } from "./create_relationship";
11
+ export { UpdateRelationshipTool } from "./update_relationship";
12
+ export type { UpdateRelationshipParams, UpdateRelationshipResult, } from "./update_relationship";
13
+ export { DeleteRelationshipTool } from "./delete_relationship";
14
+ export type { DeleteRelationshipParams, DeleteRelationshipResult, } from "./delete_relationship";
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeleteRelationshipTool = exports.UpdateRelationshipTool = exports.CreateRelationshipTool = exports.GetRelationshipsTool = void 0;
4
+ exports.registerRelationshipTools = registerRelationshipTools;
5
+ const registry_1 = require("../registry");
6
+ const logger_1 = require("../../utils/logger");
7
+ const get_relationships_1 = require("./get_relationships");
8
+ const create_relationship_1 = require("./create_relationship");
9
+ const update_relationship_1 = require("./update_relationship");
10
+ const delete_relationship_1 = require("./delete_relationship");
11
+ const logger = (0, logger_1.createLogger)("RelationshipTools");
12
+ /**
13
+ * Register all relationship management tools with the registry
14
+ * @param client Quickbase client
15
+ */
16
+ function registerRelationshipTools(client) {
17
+ logger.info("Registering relationship management tools");
18
+ // Register get_relationships tool (RELS.1002)
19
+ registry_1.toolRegistry.registerTool(new get_relationships_1.GetRelationshipsTool(client));
20
+ // Register create_relationship tool (RELS.2001)
21
+ registry_1.toolRegistry.registerTool(new create_relationship_1.CreateRelationshipTool(client));
22
+ // Register update_relationship tool (RELS.2002)
23
+ registry_1.toolRegistry.registerTool(new update_relationship_1.UpdateRelationshipTool(client));
24
+ // Register delete_relationship tool (RELS.3001)
25
+ registry_1.toolRegistry.registerTool(new delete_relationship_1.DeleteRelationshipTool(client));
26
+ logger.info("Relationship management tools registered");
27
+ }
28
+ // Export relationship tools
29
+ var get_relationships_2 = require("./get_relationships");
30
+ Object.defineProperty(exports, "GetRelationshipsTool", { enumerable: true, get: function () { return get_relationships_2.GetRelationshipsTool; } });
31
+ var create_relationship_2 = require("./create_relationship");
32
+ Object.defineProperty(exports, "CreateRelationshipTool", { enumerable: true, get: function () { return create_relationship_2.CreateRelationshipTool; } });
33
+ var update_relationship_2 = require("./update_relationship");
34
+ Object.defineProperty(exports, "UpdateRelationshipTool", { enumerable: true, get: function () { return update_relationship_2.UpdateRelationshipTool; } });
35
+ var delete_relationship_2 = require("./delete_relationship");
36
+ Object.defineProperty(exports, "DeleteRelationshipTool", { enumerable: true, get: function () { return delete_relationship_2.DeleteRelationshipTool; } });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/relationships/index.ts"],"names":[],"mappings":";;;AAcA,8DAgBC;AA7BD,0CAA2C;AAC3C,+CAAkD;AAClD,2DAA2D;AAC3D,+DAA+D;AAC/D,+DAA+D;AAC/D,+DAA+D;AAE/D,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,mBAAmB,CAAC,CAAC;AAEjD;;;GAGG;AACH,SAAgB,yBAAyB,CAAC,MAAuB;IAC/D,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAEzD,8CAA8C;IAC9C,uBAAY,CAAC,YAAY,CAAC,IAAI,wCAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE5D,gDAAgD;IAChD,uBAAY,CAAC,YAAY,CAAC,IAAI,4CAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9D,gDAAgD;IAChD,uBAAY,CAAC,YAAY,CAAC,IAAI,4CAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9D,gDAAgD;IAChD,uBAAY,CAAC,YAAY,CAAC,IAAI,4CAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9D,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;AAC1D,CAAC;AAED,4BAA4B;AAC5B,yDAA2D;AAAlD,yHAAA,oBAAoB,OAAA;AAQ7B,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAO/B,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAM/B,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA"}
@@ -0,0 +1,139 @@
1
+ import { BaseTool } from "../base";
2
+ import { QuickbaseClient } from "../../client/quickbase";
3
+ import { RelationshipFieldInfo } from "./get_relationships";
4
+ import { SummaryAccumulationType } from "./create_relationship";
5
+ /**
6
+ * Parameters for update_relationship tool
7
+ */
8
+ export interface UpdateRelationshipParams {
9
+ /**
10
+ * The ID of the child table (DBID) containing the relationship
11
+ */
12
+ table_id: string;
13
+ /**
14
+ * The ID of the relationship (same as the foreign key field ID)
15
+ */
16
+ relationship_id: number;
17
+ /**
18
+ * Optional array of parent field IDs to add as lookup fields in the child table
19
+ */
20
+ lookup_field_ids?: number[];
21
+ /**
22
+ * Optional child field ID to summarize in the parent table
23
+ */
24
+ summary_field_id?: number;
25
+ /**
26
+ * Optional label for the summary field created in the parent table
27
+ */
28
+ summary_label?: string;
29
+ /**
30
+ * Accumulation type for the summary field (required if summary_field_id is provided)
31
+ */
32
+ summary_accumulation_type?: SummaryAccumulationType;
33
+ /**
34
+ * Optional Quickbase query filter for the summary field
35
+ */
36
+ summary_where?: string;
37
+ }
38
+ /**
39
+ * Result from updating a relationship
40
+ */
41
+ export interface UpdateRelationshipResult {
42
+ /**
43
+ * The ID of the relationship (same as the foreign key field ID)
44
+ */
45
+ id: number;
46
+ /**
47
+ * The ID of the parent table
48
+ */
49
+ parentTableId: string;
50
+ /**
51
+ * The ID of the child table
52
+ */
53
+ childTableId: string;
54
+ /**
55
+ * The foreign key field in the child table
56
+ */
57
+ foreignKeyField: RelationshipFieldInfo;
58
+ /**
59
+ * All lookup fields in the child table (existing + newly added)
60
+ */
61
+ lookupFields: RelationshipFieldInfo[];
62
+ /**
63
+ * All summary fields in the parent table (existing + newly added)
64
+ */
65
+ summaryFields: RelationshipFieldInfo[];
66
+ }
67
+ /**
68
+ * Tool for updating an existing table-to-table relationship in Quickbase.
69
+ *
70
+ * ADDITIVE ONLY - adds lookup fields and/or summary fields to existing relationships.
71
+ * Does not delete existing fields from the relationship.
72
+ */
73
+ export declare class UpdateRelationshipTool extends BaseTool<UpdateRelationshipParams, UpdateRelationshipResult> {
74
+ name: string;
75
+ description: string;
76
+ /**
77
+ * Parameter schema for update_relationship with conditional validation
78
+ */
79
+ paramSchema: {
80
+ type: string;
81
+ properties: {
82
+ table_id: {
83
+ type: string;
84
+ description: string;
85
+ };
86
+ relationship_id: {
87
+ type: string;
88
+ description: string;
89
+ };
90
+ lookup_field_ids: {
91
+ type: string;
92
+ items: {
93
+ type: string;
94
+ };
95
+ description: string;
96
+ };
97
+ summary_field_id: {
98
+ type: string;
99
+ description: string;
100
+ };
101
+ summary_label: {
102
+ type: string;
103
+ description: string;
104
+ };
105
+ summary_accumulation_type: {
106
+ type: string;
107
+ enum: string[];
108
+ description: string;
109
+ };
110
+ summary_where: {
111
+ type: string;
112
+ description: string;
113
+ };
114
+ };
115
+ required: string[];
116
+ if: {
117
+ properties: {
118
+ summary_field_id: {
119
+ type: string;
120
+ };
121
+ };
122
+ required: string[];
123
+ };
124
+ then: {
125
+ required: string[];
126
+ };
127
+ };
128
+ /**
129
+ * Constructor
130
+ * @param client Quickbase client
131
+ */
132
+ constructor(client: QuickbaseClient);
133
+ /**
134
+ * Run the update_relationship tool
135
+ * @param params Tool parameters
136
+ * @returns Updated relationship details
137
+ */
138
+ protected run(params: UpdateRelationshipParams): Promise<UpdateRelationshipResult>;
139
+ }
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UpdateRelationshipTool = void 0;
4
+ const base_1 = require("../base");
5
+ const logger_1 = require("../../utils/logger");
6
+ const logger = (0, logger_1.createLogger)("UpdateRelationshipTool");
7
+ /**
8
+ * Tool for updating an existing table-to-table relationship in Quickbase.
9
+ *
10
+ * ADDITIVE ONLY - adds lookup fields and/or summary fields to existing relationships.
11
+ * Does not delete existing fields from the relationship.
12
+ */
13
+ class UpdateRelationshipTool extends base_1.BaseTool {
14
+ /**
15
+ * Constructor
16
+ * @param client Quickbase client
17
+ */
18
+ constructor(client) {
19
+ super(client);
20
+ this.name = "update_relationship";
21
+ this.description = "Adds lookup fields and/or summary fields to an existing relationship. This operation " +
22
+ "is ADDITIVE ONLY - it will not delete existing lookup or summary fields. Use this to " +
23
+ "enhance relationships with additional calculated fields. To remove fields from a " +
24
+ "relationship, you must delete them individually using the field deletion tools.";
25
+ /**
26
+ * Parameter schema for update_relationship with conditional validation
27
+ */
28
+ this.paramSchema = {
29
+ type: "object",
30
+ properties: {
31
+ table_id: {
32
+ type: "string",
33
+ description: "The ID of the child Quickbase table (DBID) containing the relationship",
34
+ },
35
+ relationship_id: {
36
+ type: "number",
37
+ description: "The ID of the relationship to update (same as the foreign key field ID)",
38
+ },
39
+ lookup_field_ids: {
40
+ type: "array",
41
+ items: {
42
+ type: "number",
43
+ },
44
+ description: "Optional array of parent field IDs to add as lookup fields in the child table",
45
+ },
46
+ summary_field_id: {
47
+ type: "number",
48
+ description: "Optional child field ID to summarize in the parent table",
49
+ },
50
+ summary_label: {
51
+ type: "string",
52
+ description: "Optional label for the summary field created in the parent table",
53
+ },
54
+ summary_accumulation_type: {
55
+ type: "string",
56
+ enum: ["SUM", "COUNT", "AVG", "MAX", "MIN"],
57
+ description: "Accumulation type for the summary field. Required when summary_field_id is provided. " +
58
+ "Valid values: SUM, COUNT, AVG, MAX, MIN",
59
+ },
60
+ summary_where: {
61
+ type: "string",
62
+ description: "Optional Quickbase query filter for the summary field (e.g., \"{6.EX.'Active'}\")",
63
+ },
64
+ },
65
+ required: ["table_id", "relationship_id"],
66
+ // Conditional validation: summary_accumulation_type is required when summary_field_id is provided
67
+ if: {
68
+ properties: { summary_field_id: { type: "number" } },
69
+ required: ["summary_field_id"],
70
+ },
71
+ then: {
72
+ required: ["summary_accumulation_type"],
73
+ },
74
+ };
75
+ }
76
+ /**
77
+ * Run the update_relationship tool
78
+ * @param params Tool parameters
79
+ * @returns Updated relationship details
80
+ */
81
+ async run(params) {
82
+ const { table_id, relationship_id, lookup_field_ids, summary_field_id, summary_label, summary_accumulation_type, summary_where, } = params;
83
+ logger.info("Updating relationship", {
84
+ childTableId: table_id,
85
+ relationshipId: relationship_id,
86
+ hasLookupFields: !!lookup_field_ids?.length,
87
+ hasSummaryField: !!summary_field_id,
88
+ });
89
+ // Validate conditional requirement: summary_accumulation_type required when summary_field_id is provided
90
+ if (summary_field_id !== undefined && !summary_accumulation_type) {
91
+ const errorMessage = "summary_accumulation_type is required when summary_field_id is provided. " +
92
+ "Valid values: SUM, COUNT, AVG, MAX, MIN";
93
+ logger.error("Validation failed", { error: errorMessage });
94
+ throw new Error(errorMessage);
95
+ }
96
+ // Build the request body according to Quickbase API format
97
+ const body = {};
98
+ // Add lookup fields if provided
99
+ if (lookup_field_ids && lookup_field_ids.length > 0) {
100
+ body.lookupFieldIds = lookup_field_ids;
101
+ }
102
+ // Add summary field configuration if provided
103
+ if (summary_field_id !== undefined && summary_accumulation_type) {
104
+ const summaryField = {
105
+ summaryFid: summary_field_id,
106
+ accumulationType: summary_accumulation_type,
107
+ };
108
+ if (summary_label) {
109
+ summaryField.label = summary_label;
110
+ }
111
+ if (summary_where) {
112
+ summaryField.where = summary_where;
113
+ }
114
+ body.summaryFields = [summaryField];
115
+ }
116
+ // Update the relationship
117
+ const response = await this.client.request({
118
+ method: "POST",
119
+ path: `/tables/${table_id}/relationship/${relationship_id}`,
120
+ body,
121
+ });
122
+ if (!response.success || !response.data) {
123
+ logger.error("Failed to update relationship", {
124
+ error: response.error,
125
+ childTableId: table_id,
126
+ relationshipId: relationship_id,
127
+ });
128
+ throw new Error(response.error?.message || "Failed to update relationship");
129
+ }
130
+ // Parse and transform the API response
131
+ const data = response.data;
132
+ const foreignKeyField = data.foreignKeyField;
133
+ const lookupFields = data.lookupFields;
134
+ const summaryFields = data.summaryFields;
135
+ const result = {
136
+ id: data.id,
137
+ parentTableId: data.parentTableId,
138
+ childTableId: data.childTableId,
139
+ foreignKeyField: foreignKeyField
140
+ ? {
141
+ id: foreignKeyField.id,
142
+ label: foreignKeyField.label,
143
+ type: foreignKeyField.type,
144
+ }
145
+ : { id: 0, label: "", type: "" },
146
+ lookupFields: (lookupFields || []).map((field) => ({
147
+ id: field.id,
148
+ label: field.label,
149
+ type: field.type,
150
+ })),
151
+ summaryFields: (summaryFields || []).map((field) => ({
152
+ id: field.id,
153
+ label: field.label,
154
+ type: field.type,
155
+ })),
156
+ };
157
+ logger.info("Successfully updated relationship", {
158
+ relationshipId: result.id,
159
+ childTableId: result.childTableId,
160
+ parentTableId: result.parentTableId,
161
+ totalLookupFields: result.lookupFields.length,
162
+ totalSummaryFields: result.summaryFields.length,
163
+ });
164
+ return result;
165
+ }
166
+ }
167
+ exports.UpdateRelationshipTool = UpdateRelationshipTool;
168
+ //# sourceMappingURL=update_relationship.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update_relationship.js","sourceRoot":"","sources":["../../../src/tools/relationships/update_relationship.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-quickbase",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Work with Quickbase via Model Context Protocol",
5
5
  "main": "dist/mcp-stdio-server.js",
6
6
  "types": "dist/mcp-stdio-server.d.ts",