Skip to content

SEP-2293 Add Support for Completions Metadata#2293

Open
evalstate wants to merge 8 commits intomodelcontextprotocol:mainfrom
evalstate:main
Open

SEP-2293 Add Support for Completions Metadata#2293
evalstate wants to merge 8 commits intomodelcontextprotocol:mainfrom
evalstate:main

Conversation

@evalstate
Copy link
Copy Markdown
Member

This supercedes #589 authored by @kentcdodds to bring it to the new SEP format. The text below is broadly the same.

This adds (non-breaking) support for title and description in the completions server response which clients can use to display something different for a value than the value itself.

: #1440

Motivation and Context

@connor4312 demonstrates the need for this in a real world setting today:

Screenshot of a tweet by @connor4312 stating, “I would use this in VS Code 👍 Our current UI for prompt completions:” followed by an image of a dark-themed UI dropdown titled “temperature (1/2)” with a text input labeled “Temperature setting” and options including “Insert as text”, “Run as Command”, and temperature values: 0, 0.5, 0.7, and 1.0. The option “0” is highlighted.

The user experience could be much better if they could provide display values.

Here's another example from a Journaling server I run (screenshot from MCP Inspector):

Dropdown UI from the MCP Inspector Resource Templates tool. The section is labeled “entry” with a subheading “A single entry.” The user is selecting an id from a searchable dropdown input. The list includes values in descending order: 71, 61, 51, 41, 31, 21, 19, down to 1, which is currently selected and indicated with a checkmark.

This is the best they can do. Users have to just know what ID they want. Would be better if I could display the journal entry title and the date in parentheses.

With this setup, the user would naturally type the title rather than the ID and the server could filter based on the title (or any other field) instead of just the ID.

How Has This Been Tested?

No, but it's a common pattern in many libraries with UX experiences like this.

Breaking Changes

I'm not a huge fan of having two ways to do this, but for simple use cases, it's much better to just use an array of strings so there's a good argument to support both an array of value/displayValue objects as well as an array of strings. If we do go this direction, then there is no breaking change here.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Closes #585

Co-authored-by: Kent C. Dodds <me@kentcdodds.com>
@evalstate evalstate requested a review from a team as a code owner February 22, 2026 19:37
@evalstate evalstate changed the title SEP-0000 Add Support for Completions Metadata SEP-2293 Add Support for Completions Metadata Feb 22, 2026
@evalstate evalstate added the draft SEP proposal with a sponsor. label Feb 22, 2026
@evalstate evalstate self-assigned this Feb 22, 2026
@evalstate evalstate added the SEP label Feb 22, 2026
@SamMorrowDrums
Copy link
Copy Markdown
Contributor

Nice @evalstate, GitHub really wants this for issue, PR and commit completions for example, where the title or commit message could be displayed to provide helpful context, where it's basically useless without additional text.

@evalstate evalstate added in-review SEP proposal ready for review. and removed draft SEP proposal with a sponsor. labels Feb 25, 2026
- Regenerate index.mdx and docs.json with SEP-2293 Draft
- Remove orphaned 2148/2149 .mdx files (upstream removed these SEPs)
@sep-automation-bot
Copy link
Copy Markdown

Maintainer Activity Check

Hi @evalstate!

You're assigned to this SEP but there hasn't been any activity from you in 18 days.

Please provide an update on:

  • Current status of your review/work
  • Any blockers or concerns
  • Expected timeline for next steps

If you're no longer able to sponsor this SEP, please let us know so we can find another maintainer.


This is an automated message from the SEP lifecycle bot.

@dend
Copy link
Copy Markdown
Contributor

dend commented Mar 17, 2026

@evalstate can you please resolve the conflicts and re-run the SEP generator?

@evalstate evalstate requested a review from a team as a code owner March 17, 2026 18:35
This change is fully backward compatible:

- **Existing servers** returning `string[]` require zero changes.
- **Existing clients** that expect `string[]` will encounter object items only if a new-style server is deployed. Such clients SHOULD handle unknown item shapes gracefully (e.g., by extracting a `value` property if present or skipping unrecognised items).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can an existing client extract the value property? It doesn't know about the value property.

I think to be backwards compatible, new servers need to return string if the client is not on the new version of the spec.

Comment on lines +284 to +287
Recommended migration path:

1. Clients update to handle `string | CompletionValue` (additive, no breaking change).
2. Servers optionally migrate completions to rich objects where they add value.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot reasonably expect all clients to update before servers start rolling this out. I think the migration path should be that SDKs automatically extract the value and return that instead when talking to old clients.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and we'd need version bump

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting from the Go SDK side: I agree this is not an "additive, optional enrichment" as we're replacing a string in the schema with a union type. Go doesn't have union types, so this essentially means we need to replace string with a struct, which is a backwards incompatible SDK API change.

We would likely need to follow a similar path as we did with adding tools to sampling:

  1. create a new variant of CompleteResult that has the changes applied,
  2. add additional method for calling completion API on the client side that would use the new result type as a return type (e.g. CompleteWithMetadata in addition to existing Complete),
  3. modify the existing Complete to strip the additional metadata if CompletionValues were returned from the server,
  4. add additional handler type for completions on the server side (e.g. CompletionWithMetadataHandler in addition to existing CompletionHandler) that would use the new result type,
  5. use the new handler for completion requests if provided and the most recent spec version was negotiated with the client, otherwise use the old handler.

Hope this helps!


Clients that receive `CompletionValue` objects:

1. **MUST** use the `value` field (not `title`) when constructing subsequent `completion/complete` requests (i.e., in `context.arguments` or as the argument value).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. I don't use completions much, so apologies if I'm missing something, but Isn't the idea of completions that the user types things and it shows a list of options prefixed by what you type? If the value is an ID (e.g. 1234) but the title is a user-readable string (e.g. Python), I assume the user is typing Pyt... not 123..., so the partial completion is the title, not the value? What value do you send if the user has typed Pyt...?

Copy link
Copy Markdown
Contributor

@SamMorrowDrums SamMorrowDrums Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a real challenge, given the completion not search, it is meant to be the value, I think @evalstate is spiritually correct and the title would show to ensure the user is getting the expected completion result, but they'd have to type the actual value.

Places GitHub might use this:

  • pull request number show titles
  • commit sha show commit title
  • issue number show title
  • project ID show title

But you complete the value, the server gets the partial value to be completed and returns new completions as you type more chars, if you allow for typing the title it would mean:

  • you'd have to rely on an initial completion request from blank string definitely returning results
  • the client/user having to find the full value in the potentially partial initial completion result.

So yeah, I think this wording is correct as is.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the motivation and context section it says:

With this setup, the user would naturally type the title rather than the ID and the server could filter based on the title (or any other field) instead of just the ID.

This seems to contradict what is being proposed?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or is the idea that the server will filter on both and return the union? So I can type either 12 or Py to get Python?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blog in-review SEP proposal ready for review. SEP

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

5 participants