Skip to content

Commit 1b9998f

Browse files
author
Lasim
committed
feat(gateway): add client configuration endpoints and modal
1 parent 6739b9f commit 1b9998f

File tree

14 files changed

+529
-50
lines changed

14 files changed

+529
-50
lines changed

services/backend/api-spec.json

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19536,7 +19536,7 @@
1953619536
}
1953719537
}
1953819538
},
19539-
"/api/config/{client}": {
19539+
"/api/gateway/config/{client}": {
1954019540
"get": {
1954119541
"summary": "Get client-specific gateway configuration",
1954219542
"tags": [
@@ -19657,6 +19657,104 @@
1965719657
}
1965819658
}
1965919659
},
19660+
"/api/gateway/config/clients": {
19661+
"get": {
19662+
"summary": "List supported MCP client types",
19663+
"tags": [
19664+
"Gateway Configuration"
19665+
],
19666+
"description": "Returns a list of all supported MCP client types that can be configured with the DeployStack Gateway.",
19667+
"security": [
19668+
{
19669+
"cookieAuth": []
19670+
},
19671+
{
19672+
"bearerAuth": []
19673+
}
19674+
],
19675+
"responses": {
19676+
"200": {
19677+
"description": "List of supported MCP client types",
19678+
"content": {
19679+
"application/json": {
19680+
"schema": {
19681+
"type": "object",
19682+
"properties": {
19683+
"clients": {
19684+
"type": "array",
19685+
"items": {
19686+
"type": "string",
19687+
"enum": [
19688+
"claude-desktop",
19689+
"cline",
19690+
"vscode",
19691+
"cursor",
19692+
"windsurf"
19693+
]
19694+
},
19695+
"description": "List of supported MCP client types"
19696+
}
19697+
},
19698+
"required": [
19699+
"clients"
19700+
],
19701+
"additionalProperties": false,
19702+
"description": "List of supported MCP client types"
19703+
}
19704+
}
19705+
}
19706+
},
19707+
"401": {
19708+
"description": "Unauthorized - Authentication required",
19709+
"content": {
19710+
"application/json": {
19711+
"schema": {
19712+
"type": "object",
19713+
"properties": {
19714+
"success": {
19715+
"type": "boolean",
19716+
"default": false
19717+
},
19718+
"error": {
19719+
"type": "string"
19720+
}
19721+
},
19722+
"required": [
19723+
"success",
19724+
"error"
19725+
],
19726+
"description": "Unauthorized - Authentication required"
19727+
}
19728+
}
19729+
}
19730+
},
19731+
"403": {
19732+
"description": "Forbidden - Insufficient permissions",
19733+
"content": {
19734+
"application/json": {
19735+
"schema": {
19736+
"type": "object",
19737+
"properties": {
19738+
"success": {
19739+
"type": "boolean",
19740+
"default": false
19741+
},
19742+
"error": {
19743+
"type": "string"
19744+
}
19745+
},
19746+
"required": [
19747+
"success",
19748+
"error"
19749+
],
19750+
"description": "Forbidden - Insufficient permissions"
19751+
}
19752+
}
19753+
}
19754+
}
19755+
}
19756+
}
19757+
},
1966019758
"/api/auth/email/register": {
1966119759
"post": {
1966219760
"summary": "User registration via email",

services/backend/api-spec.yaml

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13433,7 +13433,7 @@ paths:
1343313433
- success
1343413434
- error
1343513435
description: Internal Server Error - SMTP configuration or email sending failed
13436-
/api/config/{client}:
13436+
/api/gateway/config/{client}:
1343713437
get:
1343813438
summary: Get client-specific gateway configuration
1343913439
tags:
@@ -13513,6 +13513,71 @@ paths:
1351313513
- success
1351413514
- error
1351513515
description: Forbidden - Insufficient permissions
13516+
/api/gateway/config/clients:
13517+
get:
13518+
summary: List supported MCP client types
13519+
tags:
13520+
- Gateway Configuration
13521+
description: Returns a list of all supported MCP client types that can be
13522+
configured with the DeployStack Gateway.
13523+
security:
13524+
- cookieAuth: []
13525+
- bearerAuth: []
13526+
responses:
13527+
"200":
13528+
description: List of supported MCP client types
13529+
content:
13530+
application/json:
13531+
schema:
13532+
type: object
13533+
properties:
13534+
clients:
13535+
type: array
13536+
items:
13537+
type: string
13538+
enum:
13539+
- claude-desktop
13540+
- cline
13541+
- vscode
13542+
- cursor
13543+
- windsurf
13544+
description: List of supported MCP client types
13545+
required:
13546+
- clients
13547+
additionalProperties: false
13548+
description: List of supported MCP client types
13549+
"401":
13550+
description: Unauthorized - Authentication required
13551+
content:
13552+
application/json:
13553+
schema:
13554+
type: object
13555+
properties:
13556+
success:
13557+
type: boolean
13558+
default: false
13559+
error:
13560+
type: string
13561+
required:
13562+
- success
13563+
- error
13564+
description: Unauthorized - Authentication required
13565+
"403":
13566+
description: Forbidden - Insufficient permissions
13567+
content:
13568+
application/json:
13569+
schema:
13570+
type: object
13571+
properties:
13572+
success:
13573+
type: boolean
13574+
default: false
13575+
error:
13576+
type: string
13577+
required:
13578+
- success
13579+
- error
13580+
description: Forbidden - Insufficient permissions
1351613581
/api/auth/email/register:
1351713582
post:
1351813583
summary: User registration via email

services/backend/src/routes/gateway/config/get-client-config.ts

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,12 @@
11
import { type FastifyInstance } from 'fastify';
22
import { requireAuthenticationAny, requireOAuthScope } from '../../../middleware/oauthMiddleware';
3-
4-
// Reusable Schema Constants
5-
const CLIENT_PARAM_SCHEMA = {
6-
type: 'object',
7-
properties: {
8-
client: {
9-
type: 'string',
10-
enum: ['claude-desktop', 'cline', 'vscode', 'cursor', 'windsurf'],
11-
description: 'The MCP client type'
12-
}
13-
},
14-
required: ['client'],
15-
additionalProperties: false
16-
} as const;
17-
18-
const SUCCESS_RESPONSE_SCHEMA = {
19-
type: 'object',
20-
description: 'Client-specific gateway configuration (format varies by client type)',
21-
additionalProperties: true
22-
} as const;
23-
24-
const ERROR_RESPONSE_SCHEMA = {
25-
type: 'object',
26-
properties: {
27-
success: { type: 'boolean', default: false },
28-
error: { type: 'string' }
29-
},
30-
required: ['success', 'error']
31-
} as const;
32-
33-
// TypeScript interfaces
34-
interface ClientParams {
35-
client: 'claude-desktop' | 'cline' | 'vscode' | 'cursor' | 'windsurf';
36-
}
37-
38-
interface ErrorResponse {
39-
success: boolean;
40-
error: string;
41-
}
3+
import {
4+
CLIENT_PARAM_SCHEMA,
5+
SUCCESS_RESPONSE_SCHEMA,
6+
ERROR_RESPONSE_SCHEMA,
7+
type ClientParams,
8+
type ErrorResponse
9+
} from './schemas';
4210

4311
// Client configuration generator
4412
function generateClientConfig(clientType: string): object {
@@ -92,7 +60,7 @@ function generateClientConfig(clientType: string): object {
9260
}
9361

9462
export default async function getClientConfig(server: FastifyInstance) {
95-
server.get('/config/:client', {
63+
server.get('/gateway/config/:client', {
9664
preValidation: [
9765
requireAuthenticationAny(),
9866
requireOAuthScope('gateway:config:read')
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { type FastifyInstance } from 'fastify';
2+
import { requireAuthenticationAny, requireOAuthScope } from '../../../middleware/oauthMiddleware';
3+
import {
4+
CLIENT_TYPES,
5+
CLIENTS_LIST_RESPONSE_SCHEMA,
6+
ERROR_RESPONSE_SCHEMA,
7+
type ClientsListResponse,
8+
type ErrorResponse
9+
} from './schemas';
10+
11+
export default async function listClients(server: FastifyInstance) {
12+
server.get('/gateway/config/clients', {
13+
preValidation: [
14+
requireAuthenticationAny(),
15+
requireOAuthScope('gateway:config:read')
16+
],
17+
schema: {
18+
tags: ['Gateway Configuration'],
19+
summary: 'List supported MCP client types',
20+
description: 'Returns a list of all supported MCP client types that can be configured with the DeployStack Gateway.',
21+
security: [
22+
{ cookieAuth: [] },
23+
{ bearerAuth: [] }
24+
],
25+
response: {
26+
200: {
27+
...CLIENTS_LIST_RESPONSE_SCHEMA,
28+
description: 'List of supported MCP client types'
29+
},
30+
401: {
31+
...ERROR_RESPONSE_SCHEMA,
32+
description: 'Unauthorized - Authentication required'
33+
},
34+
403: {
35+
...ERROR_RESPONSE_SCHEMA,
36+
description: 'Forbidden - Insufficient permissions'
37+
}
38+
}
39+
}
40+
}, async (request, reply) => {
41+
try {
42+
const response: ClientsListResponse = {
43+
clients: CLIENT_TYPES
44+
};
45+
46+
const jsonString = JSON.stringify(response);
47+
return reply.status(200).type('application/json').send(jsonString);
48+
} catch (error) {
49+
const errorResponse: ErrorResponse = {
50+
success: false,
51+
error: error instanceof Error ? error.message : 'Internal server error'
52+
};
53+
const jsonString = JSON.stringify(errorResponse);
54+
return reply.status(500).type('application/json').send(jsonString);
55+
}
56+
});
57+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Shared schemas for gateway configuration endpoints
2+
3+
// Supported MCP client types
4+
export const CLIENT_TYPES = ['claude-desktop', 'cline', 'vscode', 'cursor', 'windsurf'] as const;
5+
6+
export type ClientType = typeof CLIENT_TYPES[number];
7+
8+
// Reusable Schema Constants
9+
export const CLIENT_PARAM_SCHEMA = {
10+
type: 'object',
11+
properties: {
12+
client: {
13+
type: 'string',
14+
enum: CLIENT_TYPES,
15+
description: 'The MCP client type'
16+
}
17+
},
18+
required: ['client'],
19+
additionalProperties: false
20+
} as const;
21+
22+
export const SUCCESS_RESPONSE_SCHEMA = {
23+
type: 'object',
24+
description: 'Client-specific gateway configuration (format varies by client type)',
25+
additionalProperties: true
26+
} as const;
27+
28+
export const CLIENTS_LIST_RESPONSE_SCHEMA = {
29+
type: 'object',
30+
properties: {
31+
clients: {
32+
type: 'array',
33+
items: {
34+
type: 'string',
35+
enum: CLIENT_TYPES
36+
},
37+
description: 'List of supported MCP client types'
38+
}
39+
},
40+
required: ['clients'],
41+
additionalProperties: false
42+
} as const;
43+
44+
export const ERROR_RESPONSE_SCHEMA = {
45+
type: 'object',
46+
properties: {
47+
success: { type: 'boolean', default: false },
48+
error: { type: 'string' }
49+
},
50+
required: ['success', 'error']
51+
} as const;
52+
53+
// TypeScript interfaces
54+
export interface ClientParams {
55+
client: ClientType;
56+
}
57+
58+
export interface ClientsListResponse {
59+
clients: readonly string[];
60+
}
61+
62+
export interface ErrorResponse {
63+
success: boolean;
64+
error: string;
65+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { type FastifyInstance } from 'fastify';
22
import getClientConfig from './config/get-client-config';
3+
import listClients from './config/list-clients';
34

45
export default async function gatewayRoutes(server: FastifyInstance) {
56
// Register gateway configuration routes
67
await server.register(getClientConfig);
8+
await server.register(listClients);
79
}

services/backend/src/routes/users/preferences/schemas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { DEFAULT_USER_PREFERENCES, type PreferenceValue } from '../../../config/
55

66
// Helper function to generate schema properties from config
77
function generateSchemaProperties() {
8+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
89
const properties: Record<string, any> = {};
910

1011
for (const [key, defaultValue] of Object.entries(DEFAULT_USER_PREFERENCES)) {

0 commit comments

Comments
 (0)