@opsee/mcp-server 0.4.0 → 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.
@@ -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/pCBCoCKAESGgoIdGFza19pZHMYAiADKA1CCPpCBZIBAggBEhwKD2JvYXJkX2NvbHVtbl9pZBgDIAEoDUgAiAEBEh0KEHRhc2tfcHJpb3JpdHlfaWQYBCABKA1IAYgBARIZCgx0YXNrX3R5cGVfaWQYBSABKA1IAogBARIdChBhc3NpZ25lZF91c2VyX2lkGAYgASgNSAOIAQESFQoIY3ljbGVfaWQYByABKA1IBIgBARIWCg5yZXBvc2l0b3J5X2lkcxgIIAMoDUISChBfYm9hcmRfY29sdW1uX2lkQhMKEV90YXNrX3ByaW9yaXR5X2lkQg8KDV90YXNrX3R5cGVfaWRCEwoRX2Fzc2lnbmVkX3VzZXJfaWRCCwoJX2N5Y2xlX2lkIi4KFUJ1bGtFZGl0VGFza3NSZXNwb25zZRIVCg11cGRhdGVkX2NvdW50GAEgASgFInYKEUFkZFdvcmtMb2dSZXF1ZXN0EhgKB3Rhc2tfaWQYASABKA1CB/pCBCoCKAESHQoFaG91cnMYAiABKAFCDvpCCxIJKZqZmZmZmbk/EhgKC2Rlc2NyaXB0aW9uGAMgASgJSACIAQFCDgoMX2Rlc2NyaXB0aW9uIjcKEkFkZFdvcmtMb2dSZXNwb25zZRIhCgh3b3JrX2xvZxgBIAEoCzIPLmFwaS52MS5Xb3JrTG9nIjMKFERlbGV0ZVdvcmtMb2dSZXF1ZXN0Eg8KB3Rhc2tfaWQYASABKA0SCgoCaWQYAiABKA0yrQoKC1Rhc2tTZXJ2aWNlEn0KC0V4cG9ydFRhc2tzEhouYXBpLnYxLkV4cG9ydFRhc2tzUmVxdWVzdBobLmFwaS52MS5FeHBvcnRUYXNrc1Jlc3BvbnNlIjWC0+STAi86ASoiKi9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2V4cG9ydBJ9CgtJbXBvcnRUYXNrcxIaLmFwaS52MS5JbXBvcnRUYXNrc1JlcXVlc3QaGy5hcGkudjEuSW1wb3J0VGFza3NSZXNwb25zZSI1gtPkkwIvOgEqIiovYXBpL3YxL3Byb2plY3RzL3twcm9qZWN0X2lkfS90YXNrcy9pbXBvcnQSVAoHQWRkVGFzaxIWLmFwaS52MS5BZGRUYXNrUmVxdWVzdBoXLmFwaS52MS5BZGRUYXNrUmVzcG9uc2UiGILT5JMCEjoBKiINL2FwaS92MS90YXNrcxJcCghFZGl0VGFzaxIXLmFwaS52MS5FZGl0VGFza1JlcXVlc3QaGC5hcGkudjEuRWRpdFRhc2tSZXNwb25zZSIdgtPkkwIXOgEqGhIvYXBpL3YxL3Rhc2tzL3tpZH0SVgoHR2V0VGFzaxIWLmFwaS52MS5HZXRUYXNrUmVxdWVzdBoXLmFwaS52MS5HZXRUYXNrUmVzcG9uc2UiGoLT5JMCFBISL2FwaS92MS90YXNrcy97aWR9EmkKDUdldFRhc2tCeVVVSUQSHC5hcGkudjEuR2V0VGFza0J5VVVJRFJlcXVlc3QaFy5hcGkudjEuR2V0VGFza1Jlc3BvbnNlIiGC0+STAhsSGS9hcGkvdjEvdGFza3MvdXVpZC97dXVpZH0SVAoIR2V0VGFza3MSFy5hcGkudjEuR2V0VGFza3NSZXF1ZXN0GhguYXBpLnYxLkdldFRhc2tzUmVzcG9uc2UiFYLT5JMCDxINL2FwaS92MS90YXNrcxJbCgpEZWxldGVUYXNrEhkuYXBpLnYxLkRlbGV0ZVRhc2tSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IhqC0+STAhQqEi9hcGkvdjEvdGFza3Mve2lkfRKHAQoRVHJpZ2dlckFJV29ya2Zsb3cSIC5hcGkudjEuVHJpZ2dlckFJV29ya2Zsb3dSZXF1ZXN0GiEuYXBpLnYxLlRyaWdnZXJBSVdvcmtmbG93UmVzcG9uc2UiLYLT5JMCJzoBKiIiL2FwaS92MS90YXNrcy97dGFza19pZH0vdHJpZ2dlci1haRJxCgpBZGRXb3JrTG9nEhkuYXBpLnYxLkFkZFdvcmtMb2dSZXF1ZXN0GhouYXBpLnYxLkFkZFdvcmtMb2dSZXNwb25zZSIsgtPkkwImOgEqIiEvYXBpL3YxL3Rhc2tzL3t0YXNrX2lkfS93b3JrLWxvZ3MSdQoNRGVsZXRlV29ya0xvZxIcLmFwaS52MS5EZWxldGVXb3JrTG9nUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIugtPkkwIoKiYvYXBpL3YxL3Rhc2tzL3t0YXNrX2lkfS93b3JrLWxvZ3Mve2lkfRKBAQoNQnVsa0VkaXRUYXNrcxIcLmFwaS52MS5CdWxrRWRpdFRhc2tzUmVxdWVzdBodLmFwaS52MS5CdWxrRWRpdFRhc2tzUmVzcG9uc2UiM4LT5JMCLToBKhooL2FwaS92MS9wcm9qZWN0cy97cHJvamVjdF9pZH0vdGFza3MvYnVsa0JuCgpjb20uYXBpLnYxQglUYXNrUHJvdG9QAVocb3BzZWUvYmFja2VuZC9nZW4vYXBpL3YxO2dlbqICA0FYWKoCBkFwaS5WMcoCBkFwaVxWMeICEkFwaVxWMVxHUEJNZXRhZGF0YeoCB0FwaTo6VjFiBnByb3RvMw", [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]);
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, 18);
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, 19);
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, 20);
178
+ messageDesc(file_api_v1_task, 22);
165
179
 
166
180
  /**
167
181
  * Service definition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opsee/mcp-server",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Opsee MCP server — manage projects, tasks, docs, and cycles from AI coding environments",
5
5
  "type": "module",
6
6
  "bin": {
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
+ }
@@ -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;