acuity-mcp-server 1.0.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 (99) hide show
  1. package/README.md +541 -0
  2. package/dist/auth/device-flow.d.ts +46 -0
  3. package/dist/auth/device-flow.d.ts.map +1 -0
  4. package/dist/auth/device-flow.js +141 -0
  5. package/dist/auth/device-flow.js.map +1 -0
  6. package/dist/auth/http-auth.d.ts +25 -0
  7. package/dist/auth/http-auth.d.ts.map +1 -0
  8. package/dist/auth/http-auth.js +101 -0
  9. package/dist/auth/http-auth.js.map +1 -0
  10. package/dist/auth/jwt-validator.d.ts +20 -0
  11. package/dist/auth/jwt-validator.d.ts.map +1 -0
  12. package/dist/auth/jwt-validator.js +83 -0
  13. package/dist/auth/jwt-validator.js.map +1 -0
  14. package/dist/auth/token-storage.d.ts +88 -0
  15. package/dist/auth/token-storage.d.ts.map +1 -0
  16. package/dist/auth/token-storage.js +273 -0
  17. package/dist/auth/token-storage.js.map +1 -0
  18. package/dist/clients/hasura-client.d.ts +33 -0
  19. package/dist/clients/hasura-client.d.ts.map +1 -0
  20. package/dist/clients/hasura-client.js +79 -0
  21. package/dist/clients/hasura-client.js.map +1 -0
  22. package/dist/config/environments.d.ts +51 -0
  23. package/dist/config/environments.d.ts.map +1 -0
  24. package/dist/config/environments.js +183 -0
  25. package/dist/config/environments.js.map +1 -0
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +593 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/server/http-server.d.ts +14 -0
  31. package/dist/server/http-server.d.ts.map +1 -0
  32. package/dist/server/http-server.js +167 -0
  33. package/dist/server/http-server.js.map +1 -0
  34. package/dist/server/mcp-core.d.ts +12 -0
  35. package/dist/server/mcp-core.d.ts.map +1 -0
  36. package/dist/server/mcp-core.js +200 -0
  37. package/dist/server/mcp-core.js.map +1 -0
  38. package/dist/tools/acuity-init.d.ts +84 -0
  39. package/dist/tools/acuity-init.d.ts.map +1 -0
  40. package/dist/tools/acuity-init.js +239 -0
  41. package/dist/tools/acuity-init.js.map +1 -0
  42. package/dist/tools/get-dashboard-summary.d.ts +96 -0
  43. package/dist/tools/get-dashboard-summary.d.ts.map +1 -0
  44. package/dist/tools/get-dashboard-summary.js +264 -0
  45. package/dist/tools/get-dashboard-summary.js.map +1 -0
  46. package/dist/tools/get-issue.d.ts +62 -0
  47. package/dist/tools/get-issue.d.ts.map +1 -0
  48. package/dist/tools/get-issue.js +150 -0
  49. package/dist/tools/get-issue.js.map +1 -0
  50. package/dist/tools/get-lesson-learned.d.ts +53 -0
  51. package/dist/tools/get-lesson-learned.d.ts.map +1 -0
  52. package/dist/tools/get-lesson-learned.js +117 -0
  53. package/dist/tools/get-lesson-learned.js.map +1 -0
  54. package/dist/tools/get-lookup-values.d.ts +41 -0
  55. package/dist/tools/get-lookup-values.d.ts.map +1 -0
  56. package/dist/tools/get-lookup-values.js +127 -0
  57. package/dist/tools/get-lookup-values.js.map +1 -0
  58. package/dist/tools/get-project.d.ts +131 -0
  59. package/dist/tools/get-project.d.ts.map +1 -0
  60. package/dist/tools/get-project.js +340 -0
  61. package/dist/tools/get-project.js.map +1 -0
  62. package/dist/tools/get-risk.d.ts +65 -0
  63. package/dist/tools/get-risk.d.ts.map +1 -0
  64. package/dist/tools/get-risk.js +173 -0
  65. package/dist/tools/get-risk.js.map +1 -0
  66. package/dist/tools/get-status-reports.d.ts +46 -0
  67. package/dist/tools/get-status-reports.d.ts.map +1 -0
  68. package/dist/tools/get-status-reports.js +151 -0
  69. package/dist/tools/get-status-reports.js.map +1 -0
  70. package/dist/tools/init-auth.d.ts +47 -0
  71. package/dist/tools/init-auth.d.ts.map +1 -0
  72. package/dist/tools/init-auth.js +213 -0
  73. package/dist/tools/init-auth.js.map +1 -0
  74. package/dist/tools/list-issues.d.ts +134 -0
  75. package/dist/tools/list-issues.d.ts.map +1 -0
  76. package/dist/tools/list-issues.js +285 -0
  77. package/dist/tools/list-issues.js.map +1 -0
  78. package/dist/tools/list-lessons-learned.d.ts +79 -0
  79. package/dist/tools/list-lessons-learned.d.ts.map +1 -0
  80. package/dist/tools/list-lessons-learned.js +155 -0
  81. package/dist/tools/list-lessons-learned.js.map +1 -0
  82. package/dist/tools/list-projects.d.ts +200 -0
  83. package/dist/tools/list-projects.d.ts.map +1 -0
  84. package/dist/tools/list-projects.js +396 -0
  85. package/dist/tools/list-projects.js.map +1 -0
  86. package/dist/tools/list-risks.d.ts +166 -0
  87. package/dist/tools/list-risks.d.ts.map +1 -0
  88. package/dist/tools/list-risks.js +356 -0
  89. package/dist/tools/list-risks.js.map +1 -0
  90. package/dist/tools/search-projects.d.ts +90 -0
  91. package/dist/tools/search-projects.d.ts.map +1 -0
  92. package/dist/tools/search-projects.js +191 -0
  93. package/dist/tools/search-projects.js.map +1 -0
  94. package/dist/utils/formatters.d.ts +12 -0
  95. package/dist/utils/formatters.d.ts.map +1 -0
  96. package/dist/utils/formatters.js +28 -0
  97. package/dist/utils/formatters.js.map +1 -0
  98. package/openapi.yaml +194 -0
  99. package/package.json +68 -0
@@ -0,0 +1,191 @@
1
+ /**
2
+ * MCP Tool: search_projects
3
+ * Search projects by name or description using text matching
4
+ *
5
+ * Uses PostgreSQL ILIKE for case-insensitive partial matching
6
+ */
7
+ // ============================================================================
8
+ // Enum Mappings
9
+ // ============================================================================
10
+ const STATE_TO_DB = {
11
+ active: 0,
12
+ hold: 1,
13
+ completed: 2,
14
+ cancelled: 3,
15
+ pending: 4
16
+ };
17
+ const DB_TO_STATE = {
18
+ 0: 'active',
19
+ 1: 'hold',
20
+ 2: 'completed',
21
+ 3: 'cancelled',
22
+ 4: 'pending'
23
+ };
24
+ const DB_TO_STOPLIGHT = {
25
+ 0: 'green',
26
+ 1: 'yellow',
27
+ 2: 'red',
28
+ 3: 'gray'
29
+ };
30
+ // ============================================================================
31
+ // Helper Functions
32
+ // ============================================================================
33
+ function fromDbValue(value, mapping) {
34
+ if (value === null || value === undefined)
35
+ return null;
36
+ return mapping[value] ?? null;
37
+ }
38
+ function transformProject(raw) {
39
+ return {
40
+ id: raw.id,
41
+ project_id_key: raw.project_id_key,
42
+ name: raw.name,
43
+ description: raw.description,
44
+ project_type: raw.project_type,
45
+ state: fromDbValue(raw.state, DB_TO_STATE) ?? 'active',
46
+ health_status: fromDbValue(raw.health_status, DB_TO_STOPLIGHT),
47
+ percent_complete: raw.percent_complete ?? 0,
48
+ portfolio: raw.portfolio,
49
+ department: raw.department
50
+ };
51
+ }
52
+ // ============================================================================
53
+ // Main Handler
54
+ // ============================================================================
55
+ export async function searchProjects(input, hasuraClient) {
56
+ const { query: searchQuery, search_in = ['name', 'description', 'project_id_key'], project_type = 'project', state, limit = 20 } = input;
57
+ // Build search conditions using _ilike (case-insensitive)
58
+ const searchPattern = `%${searchQuery}%`;
59
+ const searchConditions = [];
60
+ if (search_in.includes('name')) {
61
+ searchConditions.push({ name: { _ilike: searchPattern } });
62
+ }
63
+ if (search_in.includes('description')) {
64
+ searchConditions.push({ description: { _ilike: searchPattern } });
65
+ }
66
+ if (search_in.includes('project_id_key')) {
67
+ searchConditions.push({ project_id_key: { _ilike: searchPattern } });
68
+ }
69
+ // Build where clause
70
+ const whereConditions = {
71
+ _or: searchConditions
72
+ };
73
+ // Filter by project_type (default: 'project', use 'all' to search both)
74
+ if (project_type !== 'all') {
75
+ whereConditions.project_type = { _eq: project_type };
76
+ }
77
+ // Add state filter if provided
78
+ if (state !== undefined) {
79
+ const stateArr = Array.isArray(state) ? state : [state];
80
+ const stateValues = stateArr.map(s => STATE_TO_DB[s]).filter(v => v !== undefined);
81
+ if (stateValues.length > 0) {
82
+ whereConditions.state = stateValues.length === 1
83
+ ? { _eq: stateValues[0] }
84
+ : { _in: stateValues };
85
+ }
86
+ }
87
+ // Build GraphQL query
88
+ const whereClause = JSON.stringify(whereConditions).replace(/"([^"]+)":/g, '$1:');
89
+ const query = `
90
+ query SearchProjects($limit: Int!) {
91
+ projects(
92
+ where: ${whereClause},
93
+ order_by: { updated_at: desc },
94
+ limit: $limit
95
+ ) {
96
+ id
97
+ project_id_key
98
+ name
99
+ description
100
+ project_type
101
+ state
102
+ health_status
103
+ percent_complete
104
+ portfolio { id name }
105
+ department { id name }
106
+ }
107
+
108
+ projects_aggregate(where: ${whereClause}) {
109
+ aggregate {
110
+ count
111
+ }
112
+ }
113
+ }
114
+ `;
115
+ const result = await hasuraClient.query(query, { limit });
116
+ return {
117
+ projects: result.projects.map(transformProject),
118
+ total_count: result.projects_aggregate.aggregate.count,
119
+ query: searchQuery
120
+ };
121
+ }
122
+ // ============================================================================
123
+ // Tool Definition
124
+ // ============================================================================
125
+ export const searchProjectsTool = {
126
+ name: 'search_projects',
127
+ description: `
128
+ Search for projects OR proposals by name, description, or project ID key.
129
+
130
+ Uses case-insensitive partial matching (e.g., "infra" matches "Infrastructure Upgrade").
131
+
132
+ PARAMETERS:
133
+ - query (required): Search text to find in project/proposal fields
134
+ - search_in (optional): Which fields to search in. Default: ["name", "description", "project_id_key"]
135
+ - "name" - Project/proposal name
136
+ - "description" - Project/proposal description
137
+ - "project_id_key" - Human-readable ID (e.g., "PRJ-001")
138
+ - project_type (optional): "project" (default), "proposal", or "all"
139
+ - state (optional): Filter by state
140
+ - limit (optional): Max results (default: 20)
141
+
142
+ RETURNS (for each match):
143
+ - id, project_id_key, name, description, project_type
144
+ - state, health_status, percent_complete
145
+ - portfolio, department (with names)
146
+
147
+ EXAMPLES:
148
+ - "Find projects about infrastructure" → query: "infrastructure"
149
+ - "Search proposals for 'mobile'" → query: "mobile", project_type: "proposal"
150
+ - "Search for PRJ-001" → query: "PRJ-001"
151
+ - "Find active projects with 'mobile' in the name" → query: "mobile", search_in: ["name"], state: "active"
152
+ - "Search everything for 'upgrade'" → query: "upgrade", project_type: "all"
153
+ `.trim(),
154
+ inputSchema: {
155
+ type: 'object',
156
+ properties: {
157
+ query: {
158
+ type: 'string',
159
+ description: 'Search text (case-insensitive, partial match)'
160
+ },
161
+ search_in: {
162
+ type: 'array',
163
+ items: {
164
+ type: 'string',
165
+ enum: ['name', 'description', 'project_id_key']
166
+ },
167
+ description: 'Fields to search in. Default: all three fields.'
168
+ },
169
+ project_type: {
170
+ type: 'string',
171
+ enum: ['project', 'proposal', 'all'],
172
+ description: 'Search in projects (default), proposals, or all',
173
+ default: 'project'
174
+ },
175
+ state: {
176
+ oneOf: [
177
+ { type: 'string', enum: ['active', 'hold', 'completed', 'cancelled', 'pending'] },
178
+ { type: 'array', items: { type: 'string', enum: ['active', 'hold', 'completed', 'cancelled', 'pending'] } }
179
+ ],
180
+ description: 'Optional: filter results by state'
181
+ },
182
+ limit: {
183
+ type: 'number',
184
+ description: 'Maximum results to return (default: 20)',
185
+ default: 20
186
+ }
187
+ },
188
+ required: ['query']
189
+ }
190
+ };
191
+ //# sourceMappingURL=search-projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-projects.js","sourceRoot":"","sources":["../../src/tools/search-projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Formatting utilities for LLM-friendly responses
3
+ */
4
+ /**
5
+ * Format date string to readable format
6
+ */
7
+ export declare function formatDate(dateString: string | null | undefined): string;
8
+ /**
9
+ * Create a divider line
10
+ */
11
+ export declare function divider(length?: number): string;
12
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/utils/formatters.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAcxE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Formatting utilities for LLM-friendly responses
3
+ */
4
+ /**
5
+ * Format date string to readable format
6
+ */
7
+ export function formatDate(dateString) {
8
+ if (!dateString) {
9
+ return 'N/A';
10
+ }
11
+ try {
12
+ return new Date(dateString).toLocaleDateString('en-US', {
13
+ year: 'numeric',
14
+ month: 'long',
15
+ day: 'numeric'
16
+ });
17
+ }
18
+ catch {
19
+ return dateString;
20
+ }
21
+ }
22
+ /**
23
+ * Create a divider line
24
+ */
25
+ export function divider(length = 60) {
26
+ return '='.repeat(length);
27
+ }
28
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/utils/formatters.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,UAAqC;IAC9D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;YACtD,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE;IACzC,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC"}
package/openapi.yaml ADDED
@@ -0,0 +1,194 @@
1
+ swagger: '2.0'
2
+ info:
3
+ title: Acuity MCP Server
4
+ description: |
5
+ AI-powered access to Acuity Project Management data via Model Context Protocol.
6
+
7
+ This MCP server provides tools for:
8
+ - Listing and searching projects
9
+ - Viewing project details, risks, issues, and lessons learned
10
+ - Generating status reports and dashboard summaries
11
+ - Accessing lookup values for departments, categories, etc.
12
+
13
+ ## Authentication
14
+ All requests require OAuth 2.0 Bearer token authentication.
15
+ Obtain tokens from Auth0 (acuityppm.auth0.com).
16
+ version: 1.0.0
17
+ contact:
18
+ name: Acuity PPM
19
+ url: https://acuityppm.com
20
+ host: YOUR_AZURE_APP_URL.azurecontainerapps.io
21
+ basePath: /
22
+ schemes:
23
+ - https
24
+ securityDefinitions:
25
+ oauth2:
26
+ type: oauth2
27
+ flow: implicit
28
+ authorizationUrl: https://acuityppm.auth0.com/authorize
29
+ scopes:
30
+ openid: OpenID Connect
31
+ profile: User profile
32
+ email: User email
33
+ apiKey:
34
+ type: apiKey
35
+ name: x-api-key
36
+ in: header
37
+ description: API key for service-to-service authentication
38
+ paths:
39
+ /mcp:
40
+ post:
41
+ summary: Acuity Project Management MCP Server
42
+ description: |
43
+ Model Context Protocol endpoint for AI-powered project management access.
44
+
45
+ Provides tools for:
46
+ - acuity_init: Initialize connection and get company context
47
+ - list_projects: List projects with filtering
48
+ - get_project: Get detailed project information
49
+ - search_projects: Search projects by keyword
50
+ - get_status_reports: Get project status reports
51
+ - list_risks / get_risk: Access project risks
52
+ - list_issues / get_issue: Access project issues
53
+ - list_lessons_learned / get_lesson_learned: Access lessons learned
54
+ - get_lookup_values: Get department, category, lifecycle values
55
+ - get_dashboard_summary: Get portfolio dashboard data
56
+ operationId: InvokeMCP
57
+ x-ms-agentic-protocol: mcp-streamable-1.0
58
+ consumes:
59
+ - application/json
60
+ produces:
61
+ - application/json
62
+ - text/event-stream
63
+ security:
64
+ - oauth2:
65
+ - openid
66
+ - profile
67
+ - email
68
+ - apiKey: []
69
+ parameters:
70
+ - name: mcp-session-id
71
+ in: header
72
+ type: string
73
+ required: false
74
+ description: MCP session identifier (returned after initialization)
75
+ - name: body
76
+ in: body
77
+ required: true
78
+ schema:
79
+ type: object
80
+ description: JSON-RPC 2.0 request
81
+ responses:
82
+ '200':
83
+ description: Successful MCP response
84
+ schema:
85
+ type: object
86
+ '202':
87
+ description: Accepted (for notifications/responses without reply)
88
+ '400':
89
+ description: Bad request (invalid session or request format)
90
+ schema:
91
+ $ref: '#/definitions/JsonRpcError'
92
+ '401':
93
+ description: Authentication required or token invalid
94
+ schema:
95
+ $ref: '#/definitions/JsonRpcError'
96
+ '500':
97
+ description: Internal server error
98
+ schema:
99
+ $ref: '#/definitions/JsonRpcError'
100
+ get:
101
+ summary: MCP Server-Sent Events stream
102
+ description: |
103
+ Opens an SSE stream for receiving server-initiated messages.
104
+ Requires an active session (mcp-session-id header).
105
+ operationId: GetMCPStream
106
+ x-ms-agentic-protocol: mcp-streamable-1.0
107
+ produces:
108
+ - text/event-stream
109
+ security:
110
+ - oauth2:
111
+ - openid
112
+ - profile
113
+ - email
114
+ - apiKey: []
115
+ parameters:
116
+ - name: mcp-session-id
117
+ in: header
118
+ type: string
119
+ required: true
120
+ description: MCP session identifier
121
+ responses:
122
+ '200':
123
+ description: SSE stream opened
124
+ '400':
125
+ description: Invalid or missing session
126
+ schema:
127
+ $ref: '#/definitions/JsonRpcError'
128
+ '405':
129
+ description: SSE streams not supported
130
+ delete:
131
+ summary: Close MCP session
132
+ description: Terminates an active MCP session and releases resources.
133
+ operationId: CloseMCPSession
134
+ x-ms-agentic-protocol: mcp-streamable-1.0
135
+ security:
136
+ - oauth2:
137
+ - openid
138
+ - profile
139
+ - email
140
+ - apiKey: []
141
+ parameters:
142
+ - name: mcp-session-id
143
+ in: header
144
+ type: string
145
+ required: true
146
+ description: MCP session identifier to close
147
+ responses:
148
+ '200':
149
+ description: Session closed successfully
150
+ '400':
151
+ description: Invalid or missing session
152
+ schema:
153
+ $ref: '#/definitions/JsonRpcError'
154
+ /health:
155
+ get:
156
+ summary: Health check
157
+ description: Returns server health status
158
+ operationId: HealthCheck
159
+ produces:
160
+ - application/json
161
+ responses:
162
+ '200':
163
+ description: Server is healthy
164
+ schema:
165
+ type: object
166
+ properties:
167
+ status:
168
+ type: string
169
+ example: ok
170
+ service:
171
+ type: string
172
+ example: acuity-mcp-server
173
+ activeSessions:
174
+ type: integer
175
+ example: 5
176
+ definitions:
177
+ JsonRpcError:
178
+ type: object
179
+ properties:
180
+ jsonrpc:
181
+ type: string
182
+ example: '2.0'
183
+ error:
184
+ type: object
185
+ properties:
186
+ code:
187
+ type: integer
188
+ example: -32000
189
+ message:
190
+ type: string
191
+ example: Invalid session
192
+ id:
193
+ type: string
194
+ nullable: true
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "acuity-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for Acuity Project Management - enables LLM access to project data",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "acuity-mcp-server": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "!dist/**/__tests__",
13
+ "openapi.yaml",
14
+ "README.md"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/AcuityPPM/acuity-mcp-server"
19
+ },
20
+ "homepage": "https://acuityppm.com",
21
+ "scripts": {
22
+ "dev": "tsx watch src/index.ts",
23
+ "build": "tsc",
24
+ "start": "node dist/index.js",
25
+ "typecheck": "tsc --noEmit",
26
+ "test": "NODE_OPTIONS='--experimental-vm-modules' jest",
27
+ "test:watch": "NODE_OPTIONS='--experimental-vm-modules' jest --watch",
28
+ "test:coverage": "NODE_OPTIONS='--experimental-vm-modules' jest --coverage"
29
+ },
30
+ "keywords": [
31
+ "mcp",
32
+ "model-context-protocol",
33
+ "acuity",
34
+ "project-management",
35
+ "claude",
36
+ "copilot",
37
+ "ai",
38
+ "llm"
39
+ ],
40
+ "author": "Acuity PPM",
41
+ "license": "ISC",
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.21.1",
44
+ "dotenv": "^17.0.0",
45
+ "express": "^5.2.1",
46
+ "graphql": "^16.12.0",
47
+ "graphql-request": "^7.3.3",
48
+ "jsonwebtoken": "^9.0.2",
49
+ "jwks-rsa": "^3.2.0",
50
+ "open": "^11.0.0"
51
+ },
52
+ "optionalDependencies": {
53
+ "keytar": "^7.9.0"
54
+ },
55
+ "devDependencies": {
56
+ "@types/express": "^5.0.6",
57
+ "@types/jest": "^30.0.0",
58
+ "@types/jsonwebtoken": "^9.0.10",
59
+ "@types/keytar": "^4.4.0",
60
+ "@types/nock": "^10.0.3",
61
+ "@types/node": "^24.10.0",
62
+ "jest": "^30.2.0",
63
+ "nock": "^14.0.10",
64
+ "ts-jest": "^29.4.6",
65
+ "tsx": "^4.20.6",
66
+ "typescript": "^5.9.3"
67
+ }
68
+ }