Skip to content

Commit c47091a

Browse files
author
Lasim
committed
feat(frontend): add MCP server limit to team management forms
1 parent a9dff02 commit c47091a

File tree

5 files changed

+51
-3
lines changed

5 files changed

+51
-3
lines changed

services/frontend/src/components/admin/teams/TeamEditForm.vue

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ const emit = defineEmits<{
2424
const formData = ref<UpdateTeamAdminRequest>({
2525
name: '',
2626
description: '',
27-
non_http_mcp_limit: 0
27+
non_http_mcp_limit: 0,
28+
mcp_server_limit: 0
2829
})
2930
3031
const errors = ref<Record<string, string>>({})
@@ -34,7 +35,8 @@ onMounted(() => {
3435
formData.value = {
3536
name: props.team.name,
3637
description: props.team.description,
37-
non_http_mcp_limit: props.team.non_http_mcp_limit
38+
non_http_mcp_limit: props.team.non_http_mcp_limit,
39+
mcp_server_limit: props.team.mcp_server_limit
3840
}
3941
})
4042
@@ -63,6 +65,12 @@ const validateForm = (): boolean => {
6365
return false
6466
}
6567
68+
// Validate mcp_server_limit
69+
if (formData.value.mcp_server_limit !== undefined && formData.value.mcp_server_limit < 0) {
70+
errors.value.mcp_server_limit = t('adminTeams.teamEdit.form.mcpLimitMin')
71+
return false
72+
}
73+
6674
return true
6775
}
6876
@@ -86,6 +94,10 @@ const handleSubmit = () => {
8694
updates.non_http_mcp_limit = formData.value.non_http_mcp_limit
8795
}
8896
97+
if (formData.value.mcp_server_limit !== props.team.mcp_server_limit) {
98+
updates.mcp_server_limit = formData.value.mcp_server_limit
99+
}
100+
89101
emit('submit', updates)
90102
}
91103
@@ -133,6 +145,28 @@ const handleCancel = () => {
133145
</p>
134146
</div>
135147

148+
<!-- Total MCP Server Limit -->
149+
<div class="space-y-2">
150+
<Label for="mcp_server_limit" class="required">
151+
{{ t('adminTeams.teamEdit.form.totalMcpLimit') }}
152+
</Label>
153+
<Input
154+
id="mcp_server_limit"
155+
v-model.number="formData.mcp_server_limit"
156+
type="number"
157+
min="0"
158+
:disabled="isSubmitting"
159+
:class="{ 'border-red-500': errors.mcp_server_limit }"
160+
required
161+
/>
162+
<p class="text-sm text-muted-foreground">
163+
{{ t('adminTeams.teamEdit.form.totalMcpLimitHelp') }}
164+
</p>
165+
<p v-if="errors.mcp_server_limit" class="text-sm text-red-500">
166+
{{ errors.mcp_server_limit }}
167+
</p>
168+
</div>
169+
136170
<!-- Non-HTTP MCP Limit -->
137171
<div class="space-y-2">
138172
<Label for="non_http_mcp_limit" class="required">

services/frontend/src/i18n/locales/en/adminTeams.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default {
4141
slug: 'Slug',
4242
description: 'Description',
4343
type: 'Type',
44+
totalMcpLimit: 'Total MCP Server Limit',
4445
mcpLimit: 'Non-HTTP MCP Limit',
4546
teamDetails: 'Team Details',
4647
members: 'Members',
@@ -75,6 +76,8 @@ export default {
7576
description: 'Description',
7677
descriptionPlaceholder: 'Enter team description (optional)',
7778
descriptionMaxLength: 'Description must be 500 characters or less',
79+
totalMcpLimit: 'Total MCP Server Limit',
80+
totalMcpLimitHelp: 'Maximum total number of MCP servers this team can install (all transport types)',
7881
mcpLimit: 'Non-HTTP MCP Server Limit',
7982
mcpLimitHelp: 'Maximum number of stdio MCP servers this team can install',
8083
mcpLimitMin: 'Must be 0 or greater',

services/frontend/src/services/teamService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const TeamSchema = z.object({
1010
owner_id: z.string(),
1111
is_default: z.boolean(),
1212
non_http_mcp_limit: z.number(),
13+
mcp_server_limit: z.number(),
1314
created_at: z.string(),
1415
updated_at: z.string(),
1516
role: z.enum(['team_admin', 'team_user']).optional(),
@@ -413,7 +414,7 @@ export class TeamService {
413414
/**
414415
* Update team as global admin
415416
*/
416-
static async updateTeamAsAdmin(teamId: string, teamData: { name?: string; description?: string | null; non_http_mcp_limit?: number }): Promise<Team> {
417+
static async updateTeamAsAdmin(teamId: string, teamData: { name?: string; description?: string | null; non_http_mcp_limit?: number; mcp_server_limit?: number }): Promise<Team> {
417418
try {
418419
const apiUrl = this.getApiUrl()
419420

services/frontend/src/views/admin/teams/[id].vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ const goToEdit = () => {
192192
</dd>
193193
</div>
194194

195+
<!-- Total MCP Server Limit -->
196+
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
197+
<dt class="text-sm/6 font-medium text-gray-900">{{ t('adminTeams.teamDetail.fields.totalMcpLimit') }}</dt>
198+
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">
199+
{{ team.mcp_server_limit }}
200+
</dd>
201+
</div>
202+
195203
<!-- Non-HTTP MCP Limit -->
196204
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
197205
<dt class="text-sm/6 font-medium text-gray-900">{{ t('adminTeams.teamDetail.fields.mcpLimit') }}</dt>

services/frontend/src/views/admin/teams/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface Team {
66
owner_id: string
77
is_default: boolean
88
non_http_mcp_limit: number
9+
mcp_server_limit: number
910
created_at: string
1011
updated_at: string
1112
}
@@ -19,6 +20,7 @@ export interface UpdateTeamAdminRequest {
1920
name?: string
2021
description?: string | null
2122
non_http_mcp_limit?: number
23+
mcp_server_limit?: number
2224
}
2325

2426
export interface UpdateTeamResponse {

0 commit comments

Comments
 (0)