pulsemcp-cms-admin-mcp-server 0.9.2 → 0.9.5

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.
@@ -56,6 +56,8 @@ export async function getProctorRuns(apiKey, baseUrl, params) {
56
56
  num_tools: run.num_tools,
57
57
  packages: run.packages,
58
58
  remotes: run.remotes,
59
+ known_missing_init_tools_list: run.known_missing_init_tools_list || false,
60
+ known_missing_auth_check: run.known_missing_auth_check || false,
59
61
  })),
60
62
  pagination: {
61
63
  current_page: data.meta.current_page,
@@ -151,6 +151,12 @@ Use cases:
151
151
  if (run.remotes.length > 0) {
152
152
  content += ` Remotes: ${run.remotes.join(', ')}\n`;
153
153
  }
154
+ if (run.known_missing_init_tools_list) {
155
+ content += ` Known Missing Init Tools List: yes\n`;
156
+ }
157
+ if (run.known_missing_auth_check) {
158
+ content += ` Known Missing Auth Check: yes\n`;
159
+ }
154
160
  content += '\n';
155
161
  }
156
162
  return { content: [{ type: 'text', text: content.trim() }] };
@@ -24,9 +24,9 @@ const PARAM_DESCRIPTIONS = {
24
24
  github_repo: 'GitHub repository name (without owner prefix).',
25
25
  github_subfolder: 'Subfolder path within the repository, for monorepos. Omit for root-level projects.',
26
26
  // Remote endpoints
27
- remote: 'Array of remote endpoint configurations for MCP servers. Each remote can have: id (existing remote ID or blank for new), url_direct, url_setup, transport (e.g., "sse"), host_platform (e.g., "smithery"), host_infrastructure (e.g., "cloudflare"), authentication_method (e.g., "open"), cost (e.g., "free"), status (defaults to "live"), display_name, and internal_notes.',
27
+ remote: 'Array of remote endpoint configurations for MCP servers. Providing this replaces ALL existing remotes. Omitting leaves them unchanged. Pass an empty array to delete all. Each remote can have: id (existing remote ID or blank for new), url_direct, url_setup, transport (e.g., "sse"), host_platform (e.g., "smithery"), host_infrastructure (e.g., "cloudflare"), authentication_method (e.g., "open"), cost (e.g., "free"), status (defaults to "live"), display_name, and internal_notes.',
28
28
  // Canonical URLs
29
- canonical: 'Array of canonical URL configurations. Each entry must have: url (the canonical URL), scope (one of "domain", "subdomain", or "url"), and optional note for additional context.',
29
+ canonical: 'Array of canonical URL configurations. Providing this replaces ALL existing canonical URLs. Omitting leaves them unchanged. Pass an empty array to delete all. Each entry must have: url (the canonical URL), scope (one of "domain", "subdomain", or "url"), and optional note for additional context.',
30
30
  // Flags
31
31
  verified_no_remote_canonicals: 'Mark that this server has been verified to have no remote canonical URLs (true = verified no remote canonicals exist, false = reset/canonicals found)',
32
32
  // Other fields
@@ -106,14 +106,17 @@ export function saveMCPImplementation(_server, clientFactory) {
106
106
  **Creating a new implementation:**
107
107
  - Omit the \`id\` field to create a new implementation
108
108
  - Required fields for creation: \`name\`, \`type\` (either "server" or "client")
109
+ - Remote endpoints and canonical URLs CAN be included on creation
109
110
 
110
111
  **Updating an existing implementation:**
111
112
  - Provide the \`id\` field to update an existing implementation
112
- - Only provided fields will be updated; omitted fields remain unchanged
113
+ - Only provided fields will be updated; **omitted fields remain unchanged**
114
+ - Omitting \`remote\` or \`canonical\` leaves existing values unchanged (does NOT clear them)
115
+ - Providing \`remote: []\` or \`canonical: []\` (empty array) will DELETE all existing entries
113
116
 
114
117
  All business logic from the Rails controller is applied (validation, associations, callbacks).
115
118
 
116
- Example request (CREATE new implementation):
119
+ Example request (CREATE with remote endpoints and canonical URLs):
117
120
  {
118
121
  "name": "My New MCP Server",
119
122
  "type": "server",
@@ -121,7 +124,19 @@ Example request (CREATE new implementation):
121
124
  "classification": "community",
122
125
  "implementation_language": "typescript",
123
126
  "github_owner": "myorg",
124
- "github_repo": "my-mcp-server"
127
+ "github_repo": "my-mcp-server",
128
+ "remote": [
129
+ {
130
+ "url_direct": "https://api.example.com/mcp",
131
+ "transport": "sse",
132
+ "host_platform": "smithery",
133
+ "authentication_method": "open",
134
+ "cost": "free"
135
+ }
136
+ ],
137
+ "canonical": [
138
+ { "url": "https://github.com/myorg/my-mcp-server", "scope": "url" }
139
+ ]
125
140
  }
126
141
 
127
142
  Example request (UPDATE existing implementation):
@@ -134,7 +149,7 @@ Example request (UPDATE existing implementation):
134
149
  "implementation_language": "typescript"
135
150
  }
136
151
 
137
- Example request (with remote endpoints - new remote):
152
+ Example request (UPDATE with remote endpoints - replaces ALL existing remotes):
138
153
  {
139
154
  "id": 11371,
140
155
  "remote": [
@@ -151,21 +166,12 @@ Example request (with remote endpoints - new remote):
151
166
  ]
152
167
  }
153
168
 
154
- Example response:
155
- {
156
- "id": 11371,
157
- "name": "GitHub MCP Server",
158
- "slug": "github-mcp-server",
159
- "type": "server",
160
- "status": "live",
161
- "classification": "official",
162
- "updated_at": "2024-01-20T16:30:00Z"
163
- }
164
-
165
169
  Important notes:
166
170
  - Omit \`id\` to CREATE, provide \`id\` to UPDATE
167
171
  - When creating: \`name\` and \`type\` are required
168
172
  - When updating: only provided fields will be changed
173
+ - **Omission semantics:** omitting \`remote\` or \`canonical\` leaves them unchanged. To clear them, pass an empty array.
174
+ - Providing \`remote\` or \`canonical\` replaces ALL existing entries (not a merge)
169
175
  - CREATE-ONLY restrictions:
170
176
  - \`github_stars\` is read-only (derived from GitHub repository)
171
177
  - \`mcp_server_id\`/\`mcp_client_id\` are created automatically based on \`type\`
@@ -174,17 +180,7 @@ Important notes:
174
180
  - Setting mcp_server_id or mcp_client_id to null will unlink the association (UPDATE only)
175
181
  - Remote endpoints are for MCP servers only and configure how they can be accessed
176
182
  - Canonical URLs help identify the authoritative source for the implementation
177
-
178
- Use cases:
179
- - Create new MCP implementation entries
180
- - Update draft implementations before publishing
181
- - Change implementation status (draft → live, live → archived)
182
- - Update metadata (stars, language, classification)
183
- - Link or unlink MCP server/client associations
184
- - Update descriptions and documentation
185
- - Modify URLs and provider information
186
- - Add or update remote endpoint configurations for servers
187
- - Set canonical URLs for implementations`,
183
+ - After creating/updating, use \`get_mcp_server\` to verify the full state including remotes and canonical URLs`,
188
184
  inputSchema: {
189
185
  type: 'object',
190
186
  properties: {
@@ -377,9 +373,25 @@ Use cases:
377
373
  if (implementation.url) {
378
374
  content += `**URL:** ${implementation.url}\n`;
379
375
  }
376
+ if (implementation.canonical && implementation.canonical.length > 0) {
377
+ content += `**Canonical URLs:** ${implementation.canonical.length}\n`;
378
+ implementation.canonical.forEach((c) => {
379
+ content += ` - ${c.url} (${c.scope})\n`;
380
+ });
381
+ }
382
+ const remotes = implementation.mcp_server?.remotes;
383
+ if (remotes && remotes.length > 0) {
384
+ content += `**Remote Endpoints:** ${remotes.length}\n`;
385
+ remotes.forEach((r) => {
386
+ content += ` - ${r.display_name || r.url_direct || `ID ${r.id}`}\n`;
387
+ });
388
+ }
380
389
  if (implementation.created_at) {
381
390
  content += `**Created:** ${new Date(implementation.created_at).toLocaleDateString()}\n`;
382
391
  }
392
+ if (implementation.type === 'server') {
393
+ content += `\n**Tip:** Use \`get_mcp_server\` with slug \`${implementation.slug}\` to verify the full state including remotes and canonical URLs.\n`;
394
+ }
383
395
  return {
384
396
  content: [
385
397
  {
@@ -434,6 +446,19 @@ Use cases:
434
446
  if (implementation.mcp_client_id) {
435
447
  content += `**Linked MCP Client ID:** ${implementation.mcp_client_id}\n`;
436
448
  }
449
+ if (implementation.canonical && implementation.canonical.length > 0) {
450
+ content += `**Canonical URLs:** ${implementation.canonical.length}\n`;
451
+ implementation.canonical.forEach((c) => {
452
+ content += ` - ${c.url} (${c.scope})\n`;
453
+ });
454
+ }
455
+ const updateRemotes = implementation.mcp_server?.remotes;
456
+ if (updateRemotes && updateRemotes.length > 0) {
457
+ content += `**Remote Endpoints:** ${updateRemotes.length}\n`;
458
+ updateRemotes.forEach((r) => {
459
+ content += ` - ${r.display_name || r.url_direct || `ID ${r.id}`}\n`;
460
+ });
461
+ }
437
462
  if (implementation.updated_at) {
438
463
  content += `**Updated:** ${new Date(implementation.updated_at).toLocaleDateString()}\n`;
439
464
  }
@@ -18,9 +18,9 @@ const PARAM_DESCRIPTIONS = {
18
18
  recommended: 'Mark this server as recommended by PulseMCP',
19
19
  verified_no_remote_canonicals: 'Mark that this server has been verified to have no remote canonical URLs (true = verified no remote canonicals exist, false = reset/canonicals found)',
20
20
  created_on_override: 'Override the automatically derived created date (ISO date string, e.g., "2025-01-15")',
21
- tags: 'Tags for the server. Replaces all existing tags when provided. Use tag slugs.',
22
- canonical_urls: 'Authoritative URLs for the server. Replaces all existing canonical URLs when provided.',
23
- remotes: 'Remote endpoints for the server. Replaces all existing remotes when provided.',
21
+ tags: 'Tags for the server. Providing this replaces ALL existing tags. Omitting leaves them unchanged. Pass an empty array to delete all. Use tag slugs.',
22
+ canonical_urls: 'Authoritative URLs for the server. Providing this replaces ALL existing canonical URLs. Omitting leaves them unchanged. Pass an empty array to delete all.',
23
+ remotes: 'Remote endpoints for the server. Providing this replaces ALL existing remotes. Omitting leaves them unchanged. Pass an empty array to delete all.',
24
24
  internal_notes: 'Admin-only internal notes',
25
25
  };
26
26
  const CanonicalUrlSchema = z.object({
@@ -99,10 +99,15 @@ const UpdateMCPServerSchema = z.object({
99
99
  export function updateMCPServer(_server, clientFactory) {
100
100
  return {
101
101
  name: 'update_mcp_server',
102
- description: `Update an MCP server's information. Only provided fields will be updated.
102
+ description: `Update an MCP server's information. Only provided fields will be updated; **omitted fields remain unchanged**.
103
103
 
104
104
  **Important:** Use the \`implementation_id\` from \`get_mcp_server\` or \`list_mcp_servers\`, NOT the server ID or slug.
105
105
 
106
+ ## Omission semantics
107
+ - **Omitting** \`remotes\`, \`canonical_urls\`, or \`tags\` leaves existing values **unchanged** (does NOT clear them)
108
+ - **Providing** \`remotes\`, \`canonical_urls\`, or \`tags\` **replaces ALL** existing entries (not a merge)
109
+ - To **delete all** entries, pass an empty array (e.g., \`"remotes": []\`)
110
+
106
111
  ## Updating Basic Info
107
112
  \`\`\`json
108
113
  {
@@ -126,7 +131,7 @@ export function updateMCPServer(_server, clientFactory) {
126
131
  \`\`\`
127
132
 
128
133
  ## Adding/Updating Canonical URLs
129
- Providing canonical_urls replaces ALL existing canonical URLs:
134
+ Providing canonical_urls replaces ALL existing canonical URLs (omitting leaves them unchanged):
130
135
  \`\`\`json
131
136
  {
132
137
  "implementation_id": 456,
@@ -138,7 +143,7 @@ Providing canonical_urls replaces ALL existing canonical URLs:
138
143
  \`\`\`
139
144
 
140
145
  ## Adding/Updating Remote Endpoints
141
- Providing remotes replaces ALL existing remote endpoints:
146
+ Providing remotes replaces ALL existing remote endpoints (omitting leaves them unchanged):
142
147
  \`\`\`json
143
148
  {
144
149
  "implementation_id": 456,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pulsemcp-cms-admin-mcp-server",
3
- "version": "0.9.2",
3
+ "version": "0.9.5",
4
4
  "description": "Local implementation of PulseMCP CMS Admin MCP server",
5
5
  "mcpName": "com.pulsemcp.servers/pulsemcp-cms-admin",
6
6
  "main": "build/index.js",
@@ -56,6 +56,8 @@ export async function getProctorRuns(apiKey, baseUrl, params) {
56
56
  num_tools: run.num_tools,
57
57
  packages: run.packages,
58
58
  remotes: run.remotes,
59
+ known_missing_init_tools_list: run.known_missing_init_tools_list || false,
60
+ known_missing_auth_check: run.known_missing_auth_check || false,
59
61
  })),
60
62
  pagination: {
61
63
  current_page: data.meta.current_page,
@@ -151,6 +151,12 @@ Use cases:
151
151
  if (run.remotes.length > 0) {
152
152
  content += ` Remotes: ${run.remotes.join(', ')}\n`;
153
153
  }
154
+ if (run.known_missing_init_tools_list) {
155
+ content += ` Known Missing Init Tools List: yes\n`;
156
+ }
157
+ if (run.known_missing_auth_check) {
158
+ content += ` Known Missing Auth Check: yes\n`;
159
+ }
154
160
  content += '\n';
155
161
  }
156
162
  return { content: [{ type: 'text', text: content.trim() }] };
@@ -129,7 +129,7 @@ export declare function saveMCPImplementation(_server: Server, clientFactory: Cl
129
129
  };
130
130
  };
131
131
  };
132
- description: "Array of remote endpoint configurations for MCP servers. Each remote can have: id (existing remote ID or blank for new), url_direct, url_setup, transport (e.g., \"sse\"), host_platform (e.g., \"smithery\"), host_infrastructure (e.g., \"cloudflare\"), authentication_method (e.g., \"open\"), cost (e.g., \"free\"), status (defaults to \"live\"), display_name, and internal_notes.";
132
+ description: "Array of remote endpoint configurations for MCP servers. Providing this replaces ALL existing remotes. Omitting leaves them unchanged. Pass an empty array to delete all. Each remote can have: id (existing remote ID or blank for new), url_direct, url_setup, transport (e.g., \"sse\"), host_platform (e.g., \"smithery\"), host_infrastructure (e.g., \"cloudflare\"), authentication_method (e.g., \"open\"), cost (e.g., \"free\"), status (defaults to \"live\"), display_name, and internal_notes.";
133
133
  };
134
134
  canonical: {
135
135
  type: string;
@@ -149,7 +149,7 @@ export declare function saveMCPImplementation(_server: Server, clientFactory: Cl
149
149
  };
150
150
  required: string[];
151
151
  };
152
- description: "Array of canonical URL configurations. Each entry must have: url (the canonical URL), scope (one of \"domain\", \"subdomain\", or \"url\"), and optional note for additional context.";
152
+ description: "Array of canonical URL configurations. Providing this replaces ALL existing canonical URLs. Omitting leaves them unchanged. Pass an empty array to delete all. Each entry must have: url (the canonical URL), scope (one of \"domain\", \"subdomain\", or \"url\"), and optional note for additional context.";
153
153
  };
154
154
  verified_no_remote_canonicals: {
155
155
  type: string;
@@ -24,9 +24,9 @@ const PARAM_DESCRIPTIONS = {
24
24
  github_repo: 'GitHub repository name (without owner prefix).',
25
25
  github_subfolder: 'Subfolder path within the repository, for monorepos. Omit for root-level projects.',
26
26
  // Remote endpoints
27
- remote: 'Array of remote endpoint configurations for MCP servers. Each remote can have: id (existing remote ID or blank for new), url_direct, url_setup, transport (e.g., "sse"), host_platform (e.g., "smithery"), host_infrastructure (e.g., "cloudflare"), authentication_method (e.g., "open"), cost (e.g., "free"), status (defaults to "live"), display_name, and internal_notes.',
27
+ remote: 'Array of remote endpoint configurations for MCP servers. Providing this replaces ALL existing remotes. Omitting leaves them unchanged. Pass an empty array to delete all. Each remote can have: id (existing remote ID or blank for new), url_direct, url_setup, transport (e.g., "sse"), host_platform (e.g., "smithery"), host_infrastructure (e.g., "cloudflare"), authentication_method (e.g., "open"), cost (e.g., "free"), status (defaults to "live"), display_name, and internal_notes.',
28
28
  // Canonical URLs
29
- canonical: 'Array of canonical URL configurations. Each entry must have: url (the canonical URL), scope (one of "domain", "subdomain", or "url"), and optional note for additional context.',
29
+ canonical: 'Array of canonical URL configurations. Providing this replaces ALL existing canonical URLs. Omitting leaves them unchanged. Pass an empty array to delete all. Each entry must have: url (the canonical URL), scope (one of "domain", "subdomain", or "url"), and optional note for additional context.',
30
30
  // Flags
31
31
  verified_no_remote_canonicals: 'Mark that this server has been verified to have no remote canonical URLs (true = verified no remote canonicals exist, false = reset/canonicals found)',
32
32
  // Other fields
@@ -106,14 +106,17 @@ export function saveMCPImplementation(_server, clientFactory) {
106
106
  **Creating a new implementation:**
107
107
  - Omit the \`id\` field to create a new implementation
108
108
  - Required fields for creation: \`name\`, \`type\` (either "server" or "client")
109
+ - Remote endpoints and canonical URLs CAN be included on creation
109
110
 
110
111
  **Updating an existing implementation:**
111
112
  - Provide the \`id\` field to update an existing implementation
112
- - Only provided fields will be updated; omitted fields remain unchanged
113
+ - Only provided fields will be updated; **omitted fields remain unchanged**
114
+ - Omitting \`remote\` or \`canonical\` leaves existing values unchanged (does NOT clear them)
115
+ - Providing \`remote: []\` or \`canonical: []\` (empty array) will DELETE all existing entries
113
116
 
114
117
  All business logic from the Rails controller is applied (validation, associations, callbacks).
115
118
 
116
- Example request (CREATE new implementation):
119
+ Example request (CREATE with remote endpoints and canonical URLs):
117
120
  {
118
121
  "name": "My New MCP Server",
119
122
  "type": "server",
@@ -121,7 +124,19 @@ Example request (CREATE new implementation):
121
124
  "classification": "community",
122
125
  "implementation_language": "typescript",
123
126
  "github_owner": "myorg",
124
- "github_repo": "my-mcp-server"
127
+ "github_repo": "my-mcp-server",
128
+ "remote": [
129
+ {
130
+ "url_direct": "https://api.example.com/mcp",
131
+ "transport": "sse",
132
+ "host_platform": "smithery",
133
+ "authentication_method": "open",
134
+ "cost": "free"
135
+ }
136
+ ],
137
+ "canonical": [
138
+ { "url": "https://github.com/myorg/my-mcp-server", "scope": "url" }
139
+ ]
125
140
  }
126
141
 
127
142
  Example request (UPDATE existing implementation):
@@ -134,7 +149,7 @@ Example request (UPDATE existing implementation):
134
149
  "implementation_language": "typescript"
135
150
  }
136
151
 
137
- Example request (with remote endpoints - new remote):
152
+ Example request (UPDATE with remote endpoints - replaces ALL existing remotes):
138
153
  {
139
154
  "id": 11371,
140
155
  "remote": [
@@ -151,21 +166,12 @@ Example request (with remote endpoints - new remote):
151
166
  ]
152
167
  }
153
168
 
154
- Example response:
155
- {
156
- "id": 11371,
157
- "name": "GitHub MCP Server",
158
- "slug": "github-mcp-server",
159
- "type": "server",
160
- "status": "live",
161
- "classification": "official",
162
- "updated_at": "2024-01-20T16:30:00Z"
163
- }
164
-
165
169
  Important notes:
166
170
  - Omit \`id\` to CREATE, provide \`id\` to UPDATE
167
171
  - When creating: \`name\` and \`type\` are required
168
172
  - When updating: only provided fields will be changed
173
+ - **Omission semantics:** omitting \`remote\` or \`canonical\` leaves them unchanged. To clear them, pass an empty array.
174
+ - Providing \`remote\` or \`canonical\` replaces ALL existing entries (not a merge)
169
175
  - CREATE-ONLY restrictions:
170
176
  - \`github_stars\` is read-only (derived from GitHub repository)
171
177
  - \`mcp_server_id\`/\`mcp_client_id\` are created automatically based on \`type\`
@@ -174,17 +180,7 @@ Important notes:
174
180
  - Setting mcp_server_id or mcp_client_id to null will unlink the association (UPDATE only)
175
181
  - Remote endpoints are for MCP servers only and configure how they can be accessed
176
182
  - Canonical URLs help identify the authoritative source for the implementation
177
-
178
- Use cases:
179
- - Create new MCP implementation entries
180
- - Update draft implementations before publishing
181
- - Change implementation status (draft → live, live → archived)
182
- - Update metadata (stars, language, classification)
183
- - Link or unlink MCP server/client associations
184
- - Update descriptions and documentation
185
- - Modify URLs and provider information
186
- - Add or update remote endpoint configurations for servers
187
- - Set canonical URLs for implementations`,
183
+ - After creating/updating, use \`get_mcp_server\` to verify the full state including remotes and canonical URLs`,
188
184
  inputSchema: {
189
185
  type: 'object',
190
186
  properties: {
@@ -377,9 +373,25 @@ Use cases:
377
373
  if (implementation.url) {
378
374
  content += `**URL:** ${implementation.url}\n`;
379
375
  }
376
+ if (implementation.canonical && implementation.canonical.length > 0) {
377
+ content += `**Canonical URLs:** ${implementation.canonical.length}\n`;
378
+ implementation.canonical.forEach((c) => {
379
+ content += ` - ${c.url} (${c.scope})\n`;
380
+ });
381
+ }
382
+ const remotes = implementation.mcp_server?.remotes;
383
+ if (remotes && remotes.length > 0) {
384
+ content += `**Remote Endpoints:** ${remotes.length}\n`;
385
+ remotes.forEach((r) => {
386
+ content += ` - ${r.display_name || r.url_direct || `ID ${r.id}`}\n`;
387
+ });
388
+ }
380
389
  if (implementation.created_at) {
381
390
  content += `**Created:** ${new Date(implementation.created_at).toLocaleDateString()}\n`;
382
391
  }
392
+ if (implementation.type === 'server') {
393
+ content += `\n**Tip:** Use \`get_mcp_server\` with slug \`${implementation.slug}\` to verify the full state including remotes and canonical URLs.\n`;
394
+ }
383
395
  return {
384
396
  content: [
385
397
  {
@@ -434,6 +446,19 @@ Use cases:
434
446
  if (implementation.mcp_client_id) {
435
447
  content += `**Linked MCP Client ID:** ${implementation.mcp_client_id}\n`;
436
448
  }
449
+ if (implementation.canonical && implementation.canonical.length > 0) {
450
+ content += `**Canonical URLs:** ${implementation.canonical.length}\n`;
451
+ implementation.canonical.forEach((c) => {
452
+ content += ` - ${c.url} (${c.scope})\n`;
453
+ });
454
+ }
455
+ const updateRemotes = implementation.mcp_server?.remotes;
456
+ if (updateRemotes && updateRemotes.length > 0) {
457
+ content += `**Remote Endpoints:** ${updateRemotes.length}\n`;
458
+ updateRemotes.forEach((r) => {
459
+ content += ` - ${r.display_name || r.url_direct || `ID ${r.id}`}\n`;
460
+ });
461
+ }
437
462
  if (implementation.updated_at) {
438
463
  content += `**Updated:** ${new Date(implementation.updated_at).toLocaleDateString()}\n`;
439
464
  }
@@ -101,7 +101,7 @@ export declare function updateMCPServer(_server: Server, clientFactory: ClientFa
101
101
  items: {
102
102
  type: string;
103
103
  };
104
- description: "Tags for the server. Replaces all existing tags when provided. Use tag slugs.";
104
+ description: "Tags for the server. Providing this replaces ALL existing tags. Omitting leaves them unchanged. Pass an empty array to delete all. Use tag slugs.";
105
105
  };
106
106
  canonical_urls: {
107
107
  type: string;
@@ -124,7 +124,7 @@ export declare function updateMCPServer(_server: Server, clientFactory: ClientFa
124
124
  };
125
125
  required: string[];
126
126
  };
127
- description: "Authoritative URLs for the server. Replaces all existing canonical URLs when provided.";
127
+ description: "Authoritative URLs for the server. Providing this replaces ALL existing canonical URLs. Omitting leaves them unchanged. Pass an empty array to delete all.";
128
128
  };
129
129
  remotes: {
130
130
  type: string;
@@ -177,7 +177,7 @@ export declare function updateMCPServer(_server: Server, clientFactory: ClientFa
177
177
  };
178
178
  };
179
179
  };
180
- description: "Remote endpoints for the server. Replaces all existing remotes when provided.";
180
+ description: "Remote endpoints for the server. Providing this replaces ALL existing remotes. Omitting leaves them unchanged. Pass an empty array to delete all.";
181
181
  };
182
182
  internal_notes: {
183
183
  type: string;
@@ -18,9 +18,9 @@ const PARAM_DESCRIPTIONS = {
18
18
  recommended: 'Mark this server as recommended by PulseMCP',
19
19
  verified_no_remote_canonicals: 'Mark that this server has been verified to have no remote canonical URLs (true = verified no remote canonicals exist, false = reset/canonicals found)',
20
20
  created_on_override: 'Override the automatically derived created date (ISO date string, e.g., "2025-01-15")',
21
- tags: 'Tags for the server. Replaces all existing tags when provided. Use tag slugs.',
22
- canonical_urls: 'Authoritative URLs for the server. Replaces all existing canonical URLs when provided.',
23
- remotes: 'Remote endpoints for the server. Replaces all existing remotes when provided.',
21
+ tags: 'Tags for the server. Providing this replaces ALL existing tags. Omitting leaves them unchanged. Pass an empty array to delete all. Use tag slugs.',
22
+ canonical_urls: 'Authoritative URLs for the server. Providing this replaces ALL existing canonical URLs. Omitting leaves them unchanged. Pass an empty array to delete all.',
23
+ remotes: 'Remote endpoints for the server. Providing this replaces ALL existing remotes. Omitting leaves them unchanged. Pass an empty array to delete all.',
24
24
  internal_notes: 'Admin-only internal notes',
25
25
  };
26
26
  const CanonicalUrlSchema = z.object({
@@ -99,10 +99,15 @@ const UpdateMCPServerSchema = z.object({
99
99
  export function updateMCPServer(_server, clientFactory) {
100
100
  return {
101
101
  name: 'update_mcp_server',
102
- description: `Update an MCP server's information. Only provided fields will be updated.
102
+ description: `Update an MCP server's information. Only provided fields will be updated; **omitted fields remain unchanged**.
103
103
 
104
104
  **Important:** Use the \`implementation_id\` from \`get_mcp_server\` or \`list_mcp_servers\`, NOT the server ID or slug.
105
105
 
106
+ ## Omission semantics
107
+ - **Omitting** \`remotes\`, \`canonical_urls\`, or \`tags\` leaves existing values **unchanged** (does NOT clear them)
108
+ - **Providing** \`remotes\`, \`canonical_urls\`, or \`tags\` **replaces ALL** existing entries (not a merge)
109
+ - To **delete all** entries, pass an empty array (e.g., \`"remotes": []\`)
110
+
106
111
  ## Updating Basic Info
107
112
  \`\`\`json
108
113
  {
@@ -126,7 +131,7 @@ export function updateMCPServer(_server, clientFactory) {
126
131
  \`\`\`
127
132
 
128
133
  ## Adding/Updating Canonical URLs
129
- Providing canonical_urls replaces ALL existing canonical URLs:
134
+ Providing canonical_urls replaces ALL existing canonical URLs (omitting leaves them unchanged):
130
135
  \`\`\`json
131
136
  {
132
137
  "implementation_id": 456,
@@ -138,7 +143,7 @@ Providing canonical_urls replaces ALL existing canonical URLs:
138
143
  \`\`\`
139
144
 
140
145
  ## Adding/Updating Remote Endpoints
141
- Providing remotes replaces ALL existing remote endpoints:
146
+ Providing remotes replaces ALL existing remote endpoints (omitting leaves them unchanged):
142
147
  \`\`\`json
143
148
  {
144
149
  "implementation_id": 456,
package/shared/types.d.ts CHANGED
@@ -714,6 +714,8 @@ export interface ProctorRun {
714
714
  num_tools: number | null;
715
715
  packages: string[];
716
716
  remotes: string[];
717
+ known_missing_init_tools_list: boolean;
718
+ known_missing_auth_check: boolean;
717
719
  }
718
720
  export interface ProctorRunsResponse {
719
721
  runs: ProctorRun[];