@opsee/mcp-server 0.4.1 → 0.5.1
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/gen/api/v1/dashboard_pb.d.ts +639 -0
- package/gen/api/v1/dashboard_pb.js +148 -0
- package/gen/api/v1/doc_page_pb.d.ts +136 -0
- package/gen/api/v1/doc_page_pb.js +36 -1
- package/gen/api/v1/milestone_doc_page_pb.d.ts +186 -0
- package/gen/api/v1/milestone_doc_page_pb.js +73 -0
- package/gen/api/v1/milestone_document_pb.d.ts +186 -0
- package/gen/api/v1/milestone_document_pb.js +73 -0
- package/gen/api/v1/milestone_pb.d.ts +295 -0
- package/gen/api/v1/milestone_pb.js +94 -0
- package/gen/api/v1/milestone_repository_pb.d.ts +186 -0
- package/gen/api/v1/milestone_repository_pb.js +73 -0
- package/gen/api/v1/milestone_task_pb.d.ts +186 -0
- package/gen/api/v1/milestone_task_pb.js +73 -0
- package/gen/api/v1/models_pb.d.ts +280 -0
- package/gen/api/v1/models_pb.js +36 -1
- package/gen/api/v1/orchestrator_pb.d.ts +388 -0
- package/gen/api/v1/orchestrator_pb.js +85 -1
- package/gen/api/v1/project_pb.js +1 -1
- package/gen/api/v1/task_pb.d.ts +45 -0
- package/gen/api/v1/task_pb.js +18 -4
- package/package.json +1 -1
- package/src/client/api.ts +6 -0
- package/src/server.ts +2 -0
- package/src/tools/milestones.ts +189 -0
- package/src/utils/format.ts +39 -1
package/gen/api/v1/task_pb.js
CHANGED
|
@@ -14,7 +14,7 @@ import { file_api_v1_models } from "./models_pb";
|
|
|
14
14
|
* Describes the file api/v1/task.proto.
|
|
15
15
|
*/
|
|
16
16
|
export const file_api_v1_task = /*@__PURE__*/
|
|
17
|
-
fileDesc("ChFhcGkvdjEvdGFzay5wcm90bxIGYXBpLnYxIvkFCg5BZGRUYXNrUmVxdWVzdBIiCgppZGVudGlmaWVyGAEgASgJQgn6QgZyBBABGDJIAIgBARIZCgV0aXRsZRgCIAEoCUIK+kIHcgUQARjIARIYCgtkZXNjcmlwdGlvbhgDIAEoCUgBiAEBEh4KDWRpc3BsYXlfb3JkZXIYBCABKAVCB/pCBBoCKAASIgoMc3RvcnlfcG9pbnRzGAUgASgFQgf6QgQaAigBSAKIAQESLAoPZXN0aW1hdGVkX2hvdXJzGAYgASgBQg76QgsSCSkAAAAAAAAAAEgDiAEBEikKDGFjdHVhbF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIBIgBARIsCghkdWVfZGF0ZRgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFwoPYWlfbW9kZV9lbmFibGVkGAkgASgIEhoKDW1ldGFkYXRhX2pzb24YCiABKAlIBYgBARIQCghib2FyZF9pZBgLIAEoDRIXCg9ib2FyZF9jb2x1bW5faWQYDCABKA0SEgoKcHJvamVjdF9pZBgNIAEoDRIUCgx0YXNrX3R5cGVfaWQYDiABKA0SGAoQdGFza19wcmlvcml0eV9pZBgPIAEoDRIYChByZXBvcnRlcl91c2VyX2lkGBAgASgNEh0KEGFzc2lnbmVkX3VzZXJfaWQYESABKA1IBogBARIbCg5wYXJlbnRfdGFza19pZBgSIAEoDUgHiAEBEhYKDnJlcG9zaXRvcnlfaWRzGBMgAygNEhUKCGN5Y2xlX2lkGBQgASgNSAiIAQFCDQoLX2lkZW50aWZpZXJCDgoMX2Rlc2NyaXB0aW9uQg8KDV9zdG9yeV9wb2ludHNCEgoQX2VzdGltYXRlZF9ob3Vyc0IPCg1fYWN0dWFsX2hvdXJzQhAKDl9tZXRhZGF0YV9qc29uQhMKEV9hc3NpZ25lZF91c2VyX2lkQhEKD19wYXJlbnRfdGFza19pZEILCglfY3ljbGVfaWQi4gYKD0VkaXRUYXNrUmVxdWVzdBITCgJpZBgBIAEoDUIH+kIEKgIoARIdCgppZGVudGlmaWVyGAIgASgJQgn6QgZyBBABGDISGQoFdGl0bGUYAyABKAlCCvpCB3IFEAEYyAESGAoLZGVzY3JpcHRpb24YBCABKAlIAIgBARIeCg1kaXNwbGF5X29yZGVyGAUgASgFQgf6QgQaAigAEiIKDHN0b3J5X3BvaW50cxgGIAEoBUIH+kIEGgIoAUgBiAEBEiwKD2VzdGltYXRlZF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIAogBARIpCgxhY3R1YWxfaG91cnMYCCABKAFCDvpCCxIJKQAAAAAAAAAASAOIAQESLAoIZHVlX2RhdGUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhcKD2FpX21vZGVfZW5hYmxlZBgKIAEoCBIaCg1tZXRhZGF0YV9qc29uGAsgASgJSASIAQESEAoIYm9hcmRfaWQYDCABKA0SFwoPYm9hcmRfY29sdW1uX2lkGA0gASgNEhIKCnByb2plY3RfaWQYDiABKA0SFAoMdGFza190eXBlX2lkGA8gASgNEhgKEHRhc2tfcHJpb3JpdHlfaWQYECABKA0SGAoQcmVwb3J0ZXJfdXNlcl9pZBgRIAEoDRIdChBhc3NpZ25lZF91c2VyX2lkGBIgASgNSAWIAQESGwoOcGFyZW50X3Rhc2tfaWQYEyABKA1IBogBARIWCg5yZXBvc2l0b3J5X2lkcxgUIAMoDRIVCghjeWNsZV9pZBgVIAEoDUgHiAEBEi8KC3Jlc29sdmVkX2F0GBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIeChFvcmlnaW5hbF9lc3RpbWF0ZRgXIAEoAUgIiAEBQg4KDF9kZXNjcmlwdGlvbkIPCg1fc3RvcnlfcG9pbnRzQhIKEF9lc3RpbWF0ZWRfaG91cnNCDwoNX2FjdHVhbF9ob3Vyc0IQCg5fbWV0YWRhdGFfanNvbkITChFfYXNzaWduZWRfdXNlcl9pZEIRCg9fcGFyZW50X3Rhc2tfaWRCCwoJX2N5Y2xlX2lkQhQKEl9vcmlnaW5hbF9lc3RpbWF0ZSIcCg5HZXRUYXNrUmVxdWVzdBIKCgJpZBgBIAEoDSIuChRHZXRUYXNrQnlVVUlEUmVxdWVzdBIWCgR1dWlkGAEgASgJQgj6QgVyA7ABASKPAQoPR2V0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESMAoKcGFnaW5hdGlvbhgCIAEoCzISLmFwaS52MS5QYWdpbmF0aW9uQgj6QgWKAQIQARItCg5maWx0ZXJfb3B0aW9ucxgDIAEoCzIVLmFwaS52MS5GaWx0ZXJPcHRpb25zIh8KEURlbGV0ZVRhc2tSZXF1ZXN0EgoKAmlkGAEgASgNIlcKEEdldFRhc2tzUmVzcG9uc2USGwoFdGFza3MYASADKAsyDC5hcGkudjEuVGFzaxImCgpwYWdpbmF0aW9uGAIgASgLMhIuYXBpLnYxLlBhZ2luYXRpb24iLQoPQWRkVGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayIuChBFZGl0VGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayItCg9HZXRUYXNrUmVzcG9uc2USGgoEdGFzaxgBIAEoCzIMLmFwaS52MS5UYXNrIjQKGFRyaWdnZXJBSVdvcmtmbG93UmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBIk4KGVRyaWdnZXJBSVdvcmtmbG93UmVzcG9uc2USEAoIam9iX25hbWUYASABKAkSDgoGc3RhdHVzGAIgASgJEg8KB21lc3NhZ2UYAyABKAkicgoSRXhwb3J0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESLQoOZmlsdGVyX29wdGlvbnMYAiABKAsyFS5hcGkudjEuRmlsdGVyT3B0aW9ucxIQCgh0YXNrX2lkcxgDIAMoDSI8ChNFeHBvcnRUYXNrc1Jlc3BvbnNlEhMKC2Nzdl9jb250ZW50GAEgASgMEhAKCGZpbGVuYW1lGAIgASgJIk8KEkltcG9ydFRhc2tzUmVxdWVzdBIbCgpwcm9qZWN0X2lkGAEgASgNQgf6QgQqAigBEhwKC2Nzdl9jb250ZW50GAIgASgMQgf6QgR6AhABImkKE0ltcG9ydFRhc2tzUmVzcG9uc2USFQoNY3JlYXRlZF9jb3VudBgBIAEoBRIVCg11cGRhdGVkX2NvdW50GAIgASgFEhQKDGZhaWxlZF9jb3VudBgDIAEoBRIOCgZlcnJvcnMYBCADKAki0QIKFEJ1bGtFZGl0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/
|
|
17
|
+
fileDesc("ChFhcGkvdjEvdGFzay5wcm90bxIGYXBpLnYxIvkFCg5BZGRUYXNrUmVxdWVzdBIiCgppZGVudGlmaWVyGAEgASgJQgn6QgZyBBABGDJIAIgBARIZCgV0aXRsZRgCIAEoCUIK+kIHcgUQARjIARIYCgtkZXNjcmlwdGlvbhgDIAEoCUgBiAEBEh4KDWRpc3BsYXlfb3JkZXIYBCABKAVCB/pCBBoCKAASIgoMc3RvcnlfcG9pbnRzGAUgASgFQgf6QgQaAigBSAKIAQESLAoPZXN0aW1hdGVkX2hvdXJzGAYgASgBQg76QgsSCSkAAAAAAAAAAEgDiAEBEikKDGFjdHVhbF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIBIgBARIsCghkdWVfZGF0ZRgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFwoPYWlfbW9kZV9lbmFibGVkGAkgASgIEhoKDW1ldGFkYXRhX2pzb24YCiABKAlIBYgBARIQCghib2FyZF9pZBgLIAEoDRIXCg9ib2FyZF9jb2x1bW5faWQYDCABKA0SEgoKcHJvamVjdF9pZBgNIAEoDRIUCgx0YXNrX3R5cGVfaWQYDiABKA0SGAoQdGFza19wcmlvcml0eV9pZBgPIAEoDRIYChByZXBvcnRlcl91c2VyX2lkGBAgASgNEh0KEGFzc2lnbmVkX3VzZXJfaWQYESABKA1IBogBARIbCg5wYXJlbnRfdGFza19pZBgSIAEoDUgHiAEBEhYKDnJlcG9zaXRvcnlfaWRzGBMgAygNEhUKCGN5Y2xlX2lkGBQgASgNSAiIAQFCDQoLX2lkZW50aWZpZXJCDgoMX2Rlc2NyaXB0aW9uQg8KDV9zdG9yeV9wb2ludHNCEgoQX2VzdGltYXRlZF9ob3Vyc0IPCg1fYWN0dWFsX2hvdXJzQhAKDl9tZXRhZGF0YV9qc29uQhMKEV9hc3NpZ25lZF91c2VyX2lkQhEKD19wYXJlbnRfdGFza19pZEILCglfY3ljbGVfaWQi4gYKD0VkaXRUYXNrUmVxdWVzdBITCgJpZBgBIAEoDUIH+kIEKgIoARIdCgppZGVudGlmaWVyGAIgASgJQgn6QgZyBBABGDISGQoFdGl0bGUYAyABKAlCCvpCB3IFEAEYyAESGAoLZGVzY3JpcHRpb24YBCABKAlIAIgBARIeCg1kaXNwbGF5X29yZGVyGAUgASgFQgf6QgQaAigAEiIKDHN0b3J5X3BvaW50cxgGIAEoBUIH+kIEGgIoAUgBiAEBEiwKD2VzdGltYXRlZF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIAogBARIpCgxhY3R1YWxfaG91cnMYCCABKAFCDvpCCxIJKQAAAAAAAAAASAOIAQESLAoIZHVlX2RhdGUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhcKD2FpX21vZGVfZW5hYmxlZBgKIAEoCBIaCg1tZXRhZGF0YV9qc29uGAsgASgJSASIAQESEAoIYm9hcmRfaWQYDCABKA0SFwoPYm9hcmRfY29sdW1uX2lkGA0gASgNEhIKCnByb2plY3RfaWQYDiABKA0SFAoMdGFza190eXBlX2lkGA8gASgNEhgKEHRhc2tfcHJpb3JpdHlfaWQYECABKA0SGAoQcmVwb3J0ZXJfdXNlcl9pZBgRIAEoDRIdChBhc3NpZ25lZF91c2VyX2lkGBIgASgNSAWIAQESGwoOcGFyZW50X3Rhc2tfaWQYEyABKA1IBogBARIWCg5yZXBvc2l0b3J5X2lkcxgUIAMoDRIVCghjeWNsZV9pZBgVIAEoDUgHiAEBEi8KC3Jlc29sdmVkX2F0GBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIeChFvcmlnaW5hbF9lc3RpbWF0ZRgXIAEoAUgIiAEBQg4KDF9kZXNjcmlwdGlvbkIPCg1fc3RvcnlfcG9pbnRzQhIKEF9lc3RpbWF0ZWRfaG91cnNCDwoNX2FjdHVhbF9ob3Vyc0IQCg5fbWV0YWRhdGFfanNvbkITChFfYXNzaWduZWRfdXNlcl9pZEIRCg9fcGFyZW50X3Rhc2tfaWRCCwoJX2N5Y2xlX2lkQhQKEl9vcmlnaW5hbF9lc3RpbWF0ZSIcCg5HZXRUYXNrUmVxdWVzdBIKCgJpZBgBIAEoDSIuChRHZXRUYXNrQnlVVUlEUmVxdWVzdBIWCgR1dWlkGAEgASgJQgj6QgVyA7ABASKPAQoPR2V0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESMAoKcGFnaW5hdGlvbhgCIAEoCzISLmFwaS52MS5QYWdpbmF0aW9uQgj6QgWKAQIQARItCg5maWx0ZXJfb3B0aW9ucxgDIAEoCzIVLmFwaS52MS5GaWx0ZXJPcHRpb25zIh8KEURlbGV0ZVRhc2tSZXF1ZXN0EgoKAmlkGAEgASgNIlcKEEdldFRhc2tzUmVzcG9uc2USGwoFdGFza3MYASADKAsyDC5hcGkudjEuVGFzaxImCgpwYWdpbmF0aW9uGAIgASgLMhIuYXBpLnYxLlBhZ2luYXRpb24iLQoPQWRkVGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayIuChBFZGl0VGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayItCg9HZXRUYXNrUmVzcG9uc2USGgoEdGFzaxgBIAEoCzIMLmFwaS52MS5UYXNrIjQKGFRyaWdnZXJBSVdvcmtmbG93UmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBIk4KGVRyaWdnZXJBSVdvcmtmbG93UmVzcG9uc2USEAoIam9iX25hbWUYASABKAkSDgoGc3RhdHVzGAIgASgJEg8KB21lc3NhZ2UYAyABKAkicgoSRXhwb3J0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESLQoOZmlsdGVyX29wdGlvbnMYAiABKAsyFS5hcGkudjEuRmlsdGVyT3B0aW9ucxIQCgh0YXNrX2lkcxgDIAMoDSI8ChNFeHBvcnRUYXNrc1Jlc3BvbnNlEhMKC2Nzdl9jb250ZW50GAEgASgMEhAKCGZpbGVuYW1lGAIgASgJIk8KEkltcG9ydFRhc2tzUmVxdWVzdBIbCgpwcm9qZWN0X2lkGAEgASgNQgf6QgQqAigBEhwKC2Nzdl9jb250ZW50GAIgASgMQgf6QgR6AhABImkKE0ltcG9ydFRhc2tzUmVzcG9uc2USFQoNY3JlYXRlZF9jb3VudBgBIAEoBRIVCg11cGRhdGVkX2NvdW50GAIgASgFEhQKDGZhaWxlZF9jb3VudBgDIAEoBRIOCgZlcnJvcnMYBCADKAki0QIKFEJ1bGtFZGl0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESGgoIdGFza19pZHMYAiADKA1CCPpCBZIBAggBEhwKD2JvYXJkX2NvbHVtbl9pZBgDIAEoDUgAiAEBEh0KEHRhc2tfcHJpb3JpdHlfaWQYBCABKA1IAYgBARIZCgx0YXNrX3R5cGVfaWQYBSABKA1IAogBARIdChBhc3NpZ25lZF91c2VyX2lkGAYgASgNSAOIAQESFQoIY3ljbGVfaWQYByABKA1IBIgBARIWCg5yZXBvc2l0b3J5X2lkcxgIIAMoDUISChBfYm9hcmRfY29sdW1uX2lkQhMKEV90YXNrX3ByaW9yaXR5X2lkQg8KDV90YXNrX3R5cGVfaWRCEwoRX2Fzc2lnbmVkX3VzZXJfaWRCCwoJX2N5Y2xlX2lkIi4KFUJ1bGtFZGl0VGFza3NSZXNwb25zZRIVCg11cGRhdGVkX2NvdW50GAEgASgFIlEKFkJ1bGtEZWxldGVUYXNrc1JlcXVlc3QSGwoKcHJvamVjdF9pZBgBIAEoDUIH+kIEKgIoARIaCgh0YXNrX2lkcxgCIAMoDUII+kIFkgECCAEiMAoXQnVsa0RlbGV0ZVRhc2tzUmVzcG9uc2USFQoNZGVsZXRlZF9jb3VudBgBIAEoBSJ2ChFBZGRXb3JrTG9nUmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBEh0KBWhvdXJzGAIgASgBQg76QgsSCSmamZmZmZm5PxIYCgtkZXNjcmlwdGlvbhgDIAEoCUgAiAEBQg4KDF9kZXNjcmlwdGlvbiI3ChJBZGRXb3JrTG9nUmVzcG9uc2USIQoId29ya19sb2cYASABKAsyDy5hcGkudjEuV29ya0xvZyIzChREZWxldGVXb3JrTG9nUmVxdWVzdBIPCgd0YXNrX2lkGAEgASgNEgoKAmlkGAIgASgNMr4LCgtUYXNrU2VydmljZRJ9CgtFeHBvcnRUYXNrcxIaLmFwaS52MS5FeHBvcnRUYXNrc1JlcXVlc3QaGy5hcGkudjEuRXhwb3J0VGFza3NSZXNwb25zZSI1gtPkkwIvOgEqIiovYXBpL3YxL3Byb2plY3RzL3twcm9qZWN0X2lkfS90YXNrcy9leHBvcnQSfQoLSW1wb3J0VGFza3MSGi5hcGkudjEuSW1wb3J0VGFza3NSZXF1ZXN0GhsuYXBpLnYxLkltcG9ydFRhc2tzUmVzcG9uc2UiNYLT5JMCLzoBKiIqL2FwaS92MS9wcm9qZWN0cy97cHJvamVjdF9pZH0vdGFza3MvaW1wb3J0ElQKB0FkZFRhc2sSFi5hcGkudjEuQWRkVGFza1JlcXVlc3QaFy5hcGkudjEuQWRkVGFza1Jlc3BvbnNlIhiC0+STAhI6ASoiDS9hcGkvdjEvdGFza3MSXAoIRWRpdFRhc2sSFy5hcGkudjEuRWRpdFRhc2tSZXF1ZXN0GhguYXBpLnYxLkVkaXRUYXNrUmVzcG9uc2UiHYLT5JMCFzoBKhoSL2FwaS92MS90YXNrcy97aWR9ElYKB0dldFRhc2sSFi5hcGkudjEuR2V0VGFza1JlcXVlc3QaFy5hcGkudjEuR2V0VGFza1Jlc3BvbnNlIhqC0+STAhQSEi9hcGkvdjEvdGFza3Mve2lkfRJpCg1HZXRUYXNrQnlVVUlEEhwuYXBpLnYxLkdldFRhc2tCeVVVSURSZXF1ZXN0GhcuYXBpLnYxLkdldFRhc2tSZXNwb25zZSIhgtPkkwIbEhkvYXBpL3YxL3Rhc2tzL3V1aWQve3V1aWR9ElQKCEdldFRhc2tzEhcuYXBpLnYxLkdldFRhc2tzUmVxdWVzdBoYLmFwaS52MS5HZXRUYXNrc1Jlc3BvbnNlIhWC0+STAg8SDS9hcGkvdjEvdGFza3MSWwoKRGVsZXRlVGFzaxIZLmFwaS52MS5EZWxldGVUYXNrUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIagtPkkwIUKhIvYXBpL3YxL3Rhc2tzL3tpZH0ShwEKEVRyaWdnZXJBSVdvcmtmbG93EiAuYXBpLnYxLlRyaWdnZXJBSVdvcmtmbG93UmVxdWVzdBohLmFwaS52MS5UcmlnZ2VyQUlXb3JrZmxvd1Jlc3BvbnNlIi2C0+STAic6ASoiIi9hcGkvdjEvdGFza3Mve3Rhc2tfaWR9L3RyaWdnZXItYWkScQoKQWRkV29ya0xvZxIZLmFwaS52MS5BZGRXb3JrTG9nUmVxdWVzdBoaLmFwaS52MS5BZGRXb3JrTG9nUmVzcG9uc2UiLILT5JMCJjoBKiIhL2FwaS92MS90YXNrcy97dGFza19pZH0vd29yay1sb2dzEnUKDURlbGV0ZVdvcmtMb2cSHC5hcGkudjEuRGVsZXRlV29ya0xvZ1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiLoLT5JMCKComL2FwaS92MS90YXNrcy97dGFza19pZH0vd29yay1sb2dzL3tpZH0SgQEKDUJ1bGtFZGl0VGFza3MSHC5hcGkudjEuQnVsa0VkaXRUYXNrc1JlcXVlc3QaHS5hcGkudjEuQnVsa0VkaXRUYXNrc1Jlc3BvbnNlIjOC0+STAi06ASoaKC9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2J1bGsSjgEKD0J1bGtEZWxldGVUYXNrcxIeLmFwaS52MS5CdWxrRGVsZXRlVGFza3NSZXF1ZXN0Gh8uYXBpLnYxLkJ1bGtEZWxldGVUYXNrc1Jlc3BvbnNlIjqC0+STAjQ6ASoiLy9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2J1bGstZGVsZXRlQm4KCmNvbS5hcGkudjFCCVRhc2tQcm90b1ABWhxvcHNlZS9iYWNrZW5kL2dlbi9hcGkvdjE7Z2VuogIDQVhYqgIGQXBpLlYxygIGQXBpXFYx4gISQXBpXFYxXEdQQk1ldGFkYXRh6gIHQXBpOjpWMWIGcHJvdG8z", [file_google_protobuf_empty, file_google_protobuf_timestamp, file_google_api_annotations, file_validate_validate, file_api_v1_pagination, file_api_v1_filter, file_api_v1_models]);
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Describes the message api.v1.AddTaskRequest.
|
|
@@ -142,26 +142,40 @@ export const BulkEditTasksRequestSchema = /*@__PURE__*/
|
|
|
142
142
|
export const BulkEditTasksResponseSchema = /*@__PURE__*/
|
|
143
143
|
messageDesc(file_api_v1_task, 17);
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Describes the message api.v1.BulkDeleteTasksRequest.
|
|
147
|
+
* Use `create(BulkDeleteTasksRequestSchema)` to create a new message.
|
|
148
|
+
*/
|
|
149
|
+
export const BulkDeleteTasksRequestSchema = /*@__PURE__*/
|
|
150
|
+
messageDesc(file_api_v1_task, 18);
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Describes the message api.v1.BulkDeleteTasksResponse.
|
|
154
|
+
* Use `create(BulkDeleteTasksResponseSchema)` to create a new message.
|
|
155
|
+
*/
|
|
156
|
+
export const BulkDeleteTasksResponseSchema = /*@__PURE__*/
|
|
157
|
+
messageDesc(file_api_v1_task, 19);
|
|
158
|
+
|
|
145
159
|
/**
|
|
146
160
|
* Describes the message api.v1.AddWorkLogRequest.
|
|
147
161
|
* Use `create(AddWorkLogRequestSchema)` to create a new message.
|
|
148
162
|
*/
|
|
149
163
|
export const AddWorkLogRequestSchema = /*@__PURE__*/
|
|
150
|
-
messageDesc(file_api_v1_task,
|
|
164
|
+
messageDesc(file_api_v1_task, 20);
|
|
151
165
|
|
|
152
166
|
/**
|
|
153
167
|
* Describes the message api.v1.AddWorkLogResponse.
|
|
154
168
|
* Use `create(AddWorkLogResponseSchema)` to create a new message.
|
|
155
169
|
*/
|
|
156
170
|
export const AddWorkLogResponseSchema = /*@__PURE__*/
|
|
157
|
-
messageDesc(file_api_v1_task,
|
|
171
|
+
messageDesc(file_api_v1_task, 21);
|
|
158
172
|
|
|
159
173
|
/**
|
|
160
174
|
* Describes the message api.v1.DeleteWorkLogRequest.
|
|
161
175
|
* Use `create(DeleteWorkLogRequestSchema)` to create a new message.
|
|
162
176
|
*/
|
|
163
177
|
export const DeleteWorkLogRequestSchema = /*@__PURE__*/
|
|
164
|
-
messageDesc(file_api_v1_task,
|
|
178
|
+
messageDesc(file_api_v1_task, 22);
|
|
165
179
|
|
|
166
180
|
/**
|
|
167
181
|
* Service definition
|
package/package.json
CHANGED
package/src/client/api.ts
CHANGED
|
@@ -20,6 +20,8 @@ import { TaskTypeService } from "../../gen/api/v1/task_type_pb.js";
|
|
|
20
20
|
import { TaskPriorityService } from "../../gen/api/v1/task_priority_pb.js";
|
|
21
21
|
import { UserService } from "../../gen/api/v1/user_pb.js";
|
|
22
22
|
import { VCSIntegrationService } from "../../gen/api/v1/vcs_integration_pb.js";
|
|
23
|
+
import { MilestoneService } from "../../gen/api/v1/milestone_pb.js";
|
|
24
|
+
import { MilestoneTaskService } from "../../gen/api/v1/milestone_task_pb.js";
|
|
23
25
|
|
|
24
26
|
const authInterceptor: Interceptor = (next) => async (req) => {
|
|
25
27
|
// Remote mode: token from AsyncLocalStorage (per-request)
|
|
@@ -93,6 +95,8 @@ export type ApiClients = {
|
|
|
93
95
|
taskPriorities: Client<typeof TaskPriorityService>;
|
|
94
96
|
users: Client<typeof UserService>;
|
|
95
97
|
vcsIntegrations: Client<typeof VCSIntegrationService>;
|
|
98
|
+
milestones: Client<typeof MilestoneService>;
|
|
99
|
+
milestoneTasks: Client<typeof MilestoneTaskService>;
|
|
96
100
|
};
|
|
97
101
|
|
|
98
102
|
export function getClients(): ApiClients {
|
|
@@ -109,6 +113,8 @@ export function getClients(): ApiClients {
|
|
|
109
113
|
taskPriorities: makeClient(TaskPriorityService),
|
|
110
114
|
users: makeClient(UserService),
|
|
111
115
|
vcsIntegrations: makeClient(VCSIntegrationService),
|
|
116
|
+
milestones: makeClient(MilestoneService),
|
|
117
|
+
milestoneTasks: makeClient(MilestoneTaskService),
|
|
112
118
|
};
|
|
113
119
|
}
|
|
114
120
|
return cachedClients;
|
package/src/server.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { registerTaskMetadataTools } from "./tools/task-metadata.js";
|
|
|
7
7
|
import { registerCycleTools } from "./tools/cycles.js";
|
|
8
8
|
import { registerDocTools } from "./tools/docs.js";
|
|
9
9
|
import { registerRepositoryTools } from "./tools/repositories.js";
|
|
10
|
+
import { registerMilestoneTools } from "./tools/milestones.js";
|
|
10
11
|
|
|
11
12
|
export function createServer(clientFactory?: () => ApiClients): McpServer {
|
|
12
13
|
const factory = clientFactory ?? getClients;
|
|
@@ -23,6 +24,7 @@ export function createServer(clientFactory?: () => ApiClients): McpServer {
|
|
|
23
24
|
registerCycleTools(server, factory);
|
|
24
25
|
registerDocTools(server, factory);
|
|
25
26
|
registerRepositoryTools(server, factory);
|
|
27
|
+
registerMilestoneTools(server, factory);
|
|
26
28
|
|
|
27
29
|
return server;
|
|
28
30
|
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
|
|
3
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import type { ApiClients } from "../client/api.js";
|
|
5
|
+
import { overridePagination } from "../client/api.js";
|
|
6
|
+
import {
|
|
7
|
+
formatMilestone,
|
|
8
|
+
formatMilestoneList,
|
|
9
|
+
formatMilestoneTask,
|
|
10
|
+
formatMilestoneTaskList,
|
|
11
|
+
formatError,
|
|
12
|
+
} from "../utils/format.js";
|
|
13
|
+
|
|
14
|
+
const MILESTONE_STATUSES = ["not_started", "in_progress", "at_risk", "completed"] as const;
|
|
15
|
+
|
|
16
|
+
export function registerMilestoneTools(
|
|
17
|
+
server: McpServer,
|
|
18
|
+
getClients: () => ApiClients,
|
|
19
|
+
): void {
|
|
20
|
+
server.tool(
|
|
21
|
+
"opsee_list_milestones",
|
|
22
|
+
"List milestones in an Opsee project.",
|
|
23
|
+
{ projectId: z.number().describe("The project ID") },
|
|
24
|
+
{ readOnlyHint: true, destructiveHint: false },
|
|
25
|
+
async ({ projectId }) => {
|
|
26
|
+
try {
|
|
27
|
+
const clients = getClients();
|
|
28
|
+
const res = await clients.milestones.getMilestones({
|
|
29
|
+
projectId,
|
|
30
|
+
pagination: overridePagination(),
|
|
31
|
+
});
|
|
32
|
+
return { content: [{ type: "text", text: formatMilestoneList(res.milestones) }] };
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
server.tool(
|
|
40
|
+
"opsee_get_milestone",
|
|
41
|
+
"Get details of a specific milestone by ID.",
|
|
42
|
+
{ milestoneId: z.number().describe("The milestone ID") },
|
|
43
|
+
{ readOnlyHint: true, destructiveHint: false },
|
|
44
|
+
async ({ milestoneId }) => {
|
|
45
|
+
try {
|
|
46
|
+
const clients = getClients();
|
|
47
|
+
const res = await clients.milestones.getMilestone({ id: milestoneId });
|
|
48
|
+
if (!res.milestone) return { content: [{ type: "text", text: "Milestone not found." }] };
|
|
49
|
+
return { content: [{ type: "text", text: formatMilestone(res.milestone) }] };
|
|
50
|
+
} catch (error) {
|
|
51
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
server.tool(
|
|
57
|
+
"opsee_create_milestone",
|
|
58
|
+
"Create a new milestone in an Opsee project.",
|
|
59
|
+
{
|
|
60
|
+
projectId: z.number().describe("The project ID"),
|
|
61
|
+
name: z.string().describe("Milestone name"),
|
|
62
|
+
status: z.enum(MILESTONE_STATUSES).optional().describe("Milestone status. Defaults to 'not_started'"),
|
|
63
|
+
description: z.string().optional().describe("Milestone description"),
|
|
64
|
+
startDate: z.string().optional().describe("Start date (ISO 8601, e.g. 2026-04-01)"),
|
|
65
|
+
endDate: z.string().optional().describe("End date (ISO 8601, e.g. 2026-04-08)"),
|
|
66
|
+
},
|
|
67
|
+
{ readOnlyHint: false, destructiveHint: false },
|
|
68
|
+
async ({ projectId, name, status, description, startDate, endDate }) => {
|
|
69
|
+
try {
|
|
70
|
+
const clients = getClients();
|
|
71
|
+
const res = await clients.milestones.addMilestone({
|
|
72
|
+
projectId,
|
|
73
|
+
name,
|
|
74
|
+
status: status ?? "not_started",
|
|
75
|
+
description,
|
|
76
|
+
startDate: startDate ? timestampFromDate(new Date(startDate)) : undefined,
|
|
77
|
+
endDate: endDate ? timestampFromDate(new Date(endDate)) : undefined,
|
|
78
|
+
});
|
|
79
|
+
if (!res.milestone)
|
|
80
|
+
return { content: [{ type: "text", text: "Failed to create milestone." }] };
|
|
81
|
+
return {
|
|
82
|
+
content: [{ type: "text", text: `Milestone created:\n${formatMilestone(res.milestone)}` }],
|
|
83
|
+
};
|
|
84
|
+
} catch (error) {
|
|
85
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
server.tool(
|
|
91
|
+
"opsee_update_milestone",
|
|
92
|
+
"Update a milestone's fields. Fetches the current milestone first, then applies only the provided changes.",
|
|
93
|
+
{
|
|
94
|
+
milestoneId: z.number().describe("The milestone ID to update"),
|
|
95
|
+
name: z.string().optional().describe("New name"),
|
|
96
|
+
status: z.enum(MILESTONE_STATUSES).optional().describe("New status"),
|
|
97
|
+
description: z.string().optional().describe("New description"),
|
|
98
|
+
startDate: z.string().optional().describe("New start date (ISO 8601)"),
|
|
99
|
+
endDate: z.string().optional().describe("New end date (ISO 8601)"),
|
|
100
|
+
},
|
|
101
|
+
{ readOnlyHint: false, destructiveHint: false },
|
|
102
|
+
async ({ milestoneId, name, status, description, startDate, endDate }) => {
|
|
103
|
+
try {
|
|
104
|
+
const clients = getClients();
|
|
105
|
+
const current = await clients.milestones.getMilestone({ id: milestoneId });
|
|
106
|
+
if (!current.milestone)
|
|
107
|
+
return { content: [{ type: "text", text: "Milestone not found." }] };
|
|
108
|
+
const m = current.milestone;
|
|
109
|
+
const res = await clients.milestones.editMilestone({
|
|
110
|
+
id: milestoneId,
|
|
111
|
+
name: name ?? m.name,
|
|
112
|
+
status: status ?? m.status,
|
|
113
|
+
description: description !== undefined ? description : m.description,
|
|
114
|
+
startDate: startDate ? timestampFromDate(new Date(startDate)) : m.startDate,
|
|
115
|
+
endDate: endDate ? timestampFromDate(new Date(endDate)) : m.endDate,
|
|
116
|
+
});
|
|
117
|
+
if (!res.milestone)
|
|
118
|
+
return { content: [{ type: "text", text: "Failed to update milestone." }] };
|
|
119
|
+
return {
|
|
120
|
+
content: [{ type: "text", text: `Milestone updated:\n${formatMilestone(res.milestone)}` }],
|
|
121
|
+
};
|
|
122
|
+
} catch (error) {
|
|
123
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
server.tool(
|
|
129
|
+
"opsee_list_milestone_tasks",
|
|
130
|
+
"List tasks attached to a specific milestone.",
|
|
131
|
+
{ milestoneId: z.number().describe("The milestone ID") },
|
|
132
|
+
{ readOnlyHint: true, destructiveHint: false },
|
|
133
|
+
async ({ milestoneId }) => {
|
|
134
|
+
try {
|
|
135
|
+
const clients = getClients();
|
|
136
|
+
const res = await clients.milestoneTasks.getMilestoneTasks({
|
|
137
|
+
milestoneId,
|
|
138
|
+
pagination: overridePagination(),
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
content: [{ type: "text", text: formatMilestoneTaskList(res.milestoneTasks) }],
|
|
142
|
+
};
|
|
143
|
+
} catch (error) {
|
|
144
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
server.tool(
|
|
150
|
+
"opsee_attach_task_to_milestone",
|
|
151
|
+
"Attach an existing task to a milestone.",
|
|
152
|
+
{
|
|
153
|
+
milestoneId: z.number().describe("The milestone ID"),
|
|
154
|
+
taskId: z.number().describe("The task ID to attach"),
|
|
155
|
+
},
|
|
156
|
+
{ readOnlyHint: false, destructiveHint: false },
|
|
157
|
+
async ({ milestoneId, taskId }) => {
|
|
158
|
+
try {
|
|
159
|
+
const clients = getClients();
|
|
160
|
+
const res = await clients.milestoneTasks.addMilestoneTask({ milestoneId, taskId });
|
|
161
|
+
if (!res.milestoneTask)
|
|
162
|
+
return { content: [{ type: "text", text: "Failed to attach task." }] };
|
|
163
|
+
return {
|
|
164
|
+
content: [{ type: "text", text: `Task attached:\n${formatMilestoneTask(res.milestoneTask)}` }],
|
|
165
|
+
};
|
|
166
|
+
} catch (error) {
|
|
167
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
server.tool(
|
|
173
|
+
"opsee_detach_task_from_milestone",
|
|
174
|
+
"Detach a task from a milestone. Requires the MilestoneTask ID (not the task ID) — use opsee_list_milestone_tasks to find it.",
|
|
175
|
+
{
|
|
176
|
+
milestoneTaskId: z.number().describe("The MilestoneTask ID (from opsee_list_milestone_tasks)"),
|
|
177
|
+
},
|
|
178
|
+
{ readOnlyHint: false, destructiveHint: true },
|
|
179
|
+
async ({ milestoneTaskId }) => {
|
|
180
|
+
try {
|
|
181
|
+
const clients = getClients();
|
|
182
|
+
await clients.milestoneTasks.deleteMilestoneTask({ id: milestoneTaskId });
|
|
183
|
+
return { content: [{ type: "text", text: "Task detached from milestone." }] };
|
|
184
|
+
} catch (error) {
|
|
185
|
+
return { content: [{ type: "text", text: formatError(error) }], isError: true };
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
);
|
|
189
|
+
}
|
package/src/utils/format.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Task, Project, Cycle, DocPage, DocSpace } from "../../gen/api/v1/models_pb.js";
|
|
1
|
+
import type { Task, Project, Cycle, DocPage, DocSpace, Milestone, MilestoneTask } from "../../gen/api/v1/models_pb.js";
|
|
2
2
|
|
|
3
3
|
export function formatProject(p: Project): string {
|
|
4
4
|
const lines = [
|
|
@@ -124,6 +124,44 @@ export function formatDocPageList(pages: DocPage[]): string {
|
|
|
124
124
|
);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
function formatTimestamp(ts: { seconds: bigint | number } | undefined): string {
|
|
128
|
+
if (!ts) return "—";
|
|
129
|
+
const ms = typeof ts.seconds === "bigint" ? Number(ts.seconds) * 1000 : ts.seconds * 1000;
|
|
130
|
+
return new Date(ms).toISOString().split("T")[0];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function formatMilestone(m: Milestone): string {
|
|
134
|
+
const lines = [`${m.name}`];
|
|
135
|
+
if (m.description) lines.push(` Description: ${m.description}`);
|
|
136
|
+
lines.push(` Status: ${m.status}`);
|
|
137
|
+
lines.push(` Start: ${formatTimestamp(m.startDate)} | End: ${formatTimestamp(m.endDate)}`);
|
|
138
|
+
lines.push(` Project ID: ${m.projectId}`);
|
|
139
|
+
lines.push(` ID: ${m.id} | UUID: ${m.uuid}`);
|
|
140
|
+
return lines.join("\n");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function formatMilestoneList(milestones: Milestone[]): string {
|
|
144
|
+
if (milestones.length === 0) return "No milestones found.";
|
|
145
|
+
const header = `Found ${milestones.length} milestone(s):\n`;
|
|
146
|
+
return header + milestones.map((m, i) => `${i + 1}. ${formatMilestone(m)}`).join("\n\n");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function formatMilestoneTask(mt: MilestoneTask): string {
|
|
150
|
+
const t = mt.task;
|
|
151
|
+
if (!t) return ` Task ID: ${mt.taskId} (MilestoneTask ID: ${mt.id})`;
|
|
152
|
+
const parts = [`${t.identifier ? `${t.identifier} ` : ""}${t.title || `Task #${mt.taskId}`}`];
|
|
153
|
+
if (t.boardColumn?.name) parts.push(` Status: ${t.boardColumn.name}`);
|
|
154
|
+
if (t.taskPriority?.name) parts.push(` Priority: ${t.taskPriority.name}`);
|
|
155
|
+
parts.push(` Task ID: ${mt.taskId} | MilestoneTask ID: ${mt.id}`);
|
|
156
|
+
return parts.join("\n");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function formatMilestoneTaskList(milestoneTasks: MilestoneTask[]): string {
|
|
160
|
+
if (milestoneTasks.length === 0) return "No tasks attached to this milestone.";
|
|
161
|
+
const header = `Found ${milestoneTasks.length} task(s):\n`;
|
|
162
|
+
return header + milestoneTasks.map((mt, i) => `${i + 1}. ${formatMilestoneTask(mt)}`).join("\n\n");
|
|
163
|
+
}
|
|
164
|
+
|
|
127
165
|
export function formatError(error: unknown): string {
|
|
128
166
|
if (error instanceof Error) {
|
|
129
167
|
const msg = error.message;
|