Where does validation of a peer's declarations belong? Four things the client accepts today
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 30/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Necesita aclaración
- Estado de actividad
- Activo
- Stack tecnológico
- node.js, typescript
Línea de trabajo
No se nombra ningún archivo ni prueba. Empieza por la ruta de respuesta de client.listTools() y su validación con Zod; después revisa cómo se emparejan los IDs de las solicitudes; se considera terminado cuando un mantenedor haya decidido qué comprobaciones de declaraciones pertenecen al SDK y si esa política debería documentarse.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
This is a scope question rather than four bug reports, and I would rather ask it than assume the answer.
Probing the stdio client against deliberately malformed servers, I found four things it accepts without comment. Some of them the spec says something about; for others it is silent. In every case the SDK is the one place that sees the data before any application does, which is why it seems worth asking where the line is — not because accepting them is obviously wrong.
All on @modelcontextprotocol/[email protected], Node 22.22.1, via client.listTools().
| # | Server returns | Client result | What the spec says |
|---|---|---|---|
| 1 | two tools both named same |
tools.length === 2, both kept |
"name: Unique identifier for the tool" |
| 2 | a tool named safetool |
accepted verbatim | name is "used as a display name ... fallback (if title isn't present)" |
| 3 | numeric request id 0, response id "0" |
matched, resolves normally | RequestId = string | number; JSON-RPC 2.0 requires the response id to equal the request's |
| 4 | 100,000 tools in one response | all 100,000 returned, 406ms | nothing |
Reproduction for any row — server answers initialize normally, then returns the listed payload for tools/list:
// #1
{ tools: [
{ name: 'same', description: 'First.', inputSchema: { type: 'object' } },
{ name: 'same', description: 'Second.', inputSchema: { type: 'object' } },
]}
// #2 — U+200B zero width space, U+202E right-to-left override
{ tools: [{ name: 'safetool', description: 'd', inputSchema: { type: 'object' } }] }
// #3 — request went out with id 0
{ jsonrpc: '2.0', id: '0', result: { tools: [] } }
Why #2 is the one I would actually argue about
The other three are conformance questions. This one interacts with a control the spec asks clients to provide:
For trust & safety and security, there SHOULD always be a human in the loop with the ability to deny tool invocations.
U+202E reverses the display order of everything after it. Combined with name being the display fallback when title is absent, a server can choose a name that renders in an approval dialog as something other than the name the model will call. The human in the loop is then approving a string that does not exist.
That is not a transport bug — the bytes are delivered faithfully, which is the transport's job. But the SDK is the last place that sees the name as bytes before an application renders it as text, and an application author has no particular reason to expect a tool name to contain a bidi override.
The actual question
Is any of this the SDK's business, or is it all the application's?
A defensible answer is "all of it" — the SDK transports and parses, and what a client does with a hostile server's declarations is a policy decision above it. If that is the position, then it is worth saying so somewhere, because the current behaviour reads as "validated" rather than "passed through": responses go through a Zod schema, so an application author could reasonably conclude that anything reaching them has been checked.
If some of it is in scope, #1 and #3 are the cheap ones — a duplicate-name check and an id type comparison, both a few lines and neither a breaking change for a conforming server.
I am not proposing a PR yet because the answer determines whether there is anything to write. Happy to do so once the direction is clear.
Context on where this came from, since it explains the odd angle: I maintain a scanner that connects to MCP servers before anyone has established they are trustworthy, so it treats hostile declarations as the normal case. #2775 and #2776 came out of the same probing.
- Lenguaje dominante
- TypeScript
- Estrellas
- 13.6k
- Forks
- 2.3k
- Merge medio
- 1 d 14 h
- PR fusionados (30 d)
- 53
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de modelcontextprotocol/typescript-sdk
-
Stateless 405 response omits the Allow headerPosiblemente ocupada @Hugo-DDT la tomó hace 3 días. Abiertov2
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
modelcontextprotocol/typescript-sdk#2970 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
[v2] @modelcontextprotocol/server inlines fast-uri 3.1.0, which has 9 published advisoriesPosiblemente ocupada @Andiii208 la tomó hace 5 días. Abiertov2
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
modelcontextprotocol/typescript-sdk#2966 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
v1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
modelcontextprotocol/typescript-sdk#2946 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
[v2] URI template reserved expansions encode existing %HH sequences againPosiblemente ocupada @takagibit18 la tomó hace 12 días. Abiertov1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
modelcontextprotocol/typescript-sdk#2920 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[v2] URI template strict expansions leave !'()* unencodedPosiblemente ocupada @takagibit18 la tomó hace 12 días. Abiertov1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
modelcontextprotocol/typescript-sdk#2919 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de modelcontextprotocol/typescript-sdk
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
status:approved type:bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 70/100
egdev6/quorb#109 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
stage:4
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
ilan-pinto/roaring-lions#598 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Frontmatter next to `src:` is applied to every imported slide, not only the first (undocumented)Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día