Skip to content

feat: add optional lastModified timestamp to Annotated #140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 10, 2025

Conversation

salman1993
Copy link
Contributor

@salman1993 salman1993 commented Jan 13, 2025

Adds an optional timestamp field to Annotated interface.

Motivation and Context

It's useful to know when a Resource is created or updated for context truncation.

How Has This Been Tested?

Breaking Changes

None

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

Copy link
Member

@jspahrsummers jspahrsummers left a comment

Choose a reason for hiding this comment

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

Thanks for the suggestion!

Can you share a bit more about how you might use this to truncate context, just so I have a greater understanding of the use case? I think it probably makes sense, but would love more detail.

Also left a couple of minor comments for discussion. 🙏

schema/schema.ts Outdated
@@ -832,6 +832,13 @@ export interface Annotated {
* @maximum 1
*/
priority?: number;

/**
* The timestamp indicating when this annotation was created or last updated.
Copy link
Member

Choose a reason for hiding this comment

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

Should this be about the annotation (only) or about the thing that the annotation is attached to? I lean toward the latter—maybe we could update the phrasing to reflect this?

schema/schema.ts Outdated
*
* Should be an ISO 8601 formatted string (e.g., "2025-01-12T15:00:58Z").
*/
timestamp?: string;
Copy link
Member

Choose a reason for hiding this comment

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

We may want to have other timestamps in future, so perhaps a more specific name like:

Suggested change
timestamp?: string;
lastModified?: string;

* upstream/main:
  docs: update README links
  chore: add markdown format check workflow and format all docs
  chore: add prettier and format command for markdown files
  Move schema files to versioned directory
  Fix broken links. 2024-11-05 schema.ts/schema.json points to main/schema/2024-11-05/schema.ts in anticipation of PR modelcontextprotocol#145 being merged.
  update generate json after merge
  update protocol revision to draft on sampling page
  updated schema protocol version to reflect draft.
  change to relative link in spec
  point documentation changes to "draft"
  Revert schema/schema.ts to upstream/main, add drafts folder. Update validate and build scripts to build drafts too.
  fix: update draft page reference and add alias for better navigation
  fix: incorrect link for "Specification (Draft)" on nav bar
  Update schema/schema.ts
  remove spurious semicolon
  validation, simplify wording.
  Add optional "size" attribute to Resource, include in Documentation
  Update docs/specification/client/sampling.md
  Updated Specification and Docs to support Audio Modality.
@salman1993 salman1993 changed the title feat: add optional timestamp to Annotated feat: add optional lastModified timestamp to Annotated Jan 28, 2025
@salman1993
Copy link
Contributor Author

@jspahrsummers sorry for the delay on this one. I updated the name and added some examples to the docstring.

Generally, the idea here is that since resources are application controlled, it's useful to pass in the lastModified timestamp of the attached data especially for truncation when we exceed context limits (eg. evict files that have no recent activity)

Copy link
Member

@jerome3o-anthropic jerome3o-anthropic left a comment

Choose a reason for hiding this comment

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

This seems reasonable to me, thanks for adding this

dsp-ant
dsp-ant previously approved these changes Feb 13, 2025
Comment on lines 835 to 842

/**
* The timestamp when the resource was last modified.
* Examples: last activity timestamp in an open file, timestamp when resource is attached, etc.
*
* Should be an ISO 8601 formatted string (e.g., "2025-01-12T15:00:58Z").
*/
lastModified?: string;
Copy link
Member

Choose a reason for hiding this comment

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

jspahrsummers pushed a commit that referenced this pull request Mar 12, 2025
@jspahrsummers jspahrsummers moved this to In Review in Standards Track Mar 14, 2025
*
* Should be an ISO 8601 formatted string (e.g., "2025-01-12T15:00:58Z").
*/
lastModified?: Date;
Copy link
Member

Choose a reason for hiding this comment

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

I like the idea. While this is usually the most intuitive way to express a point in time. However, I assume a client application will want to use this for comparison of the resource has changed. Notable ISO 8601 are not guarantee to be monotonically increasing. The following issues can appear:

  • Leap Seconds
  • Clock Adjustment
  • Daylight Savings
  • Clock Drift or Time Sync issues between client and server (particularly in a remote scenario)

There are a few ways to go about this:

  • We can include more metadata (e,g, rsync uses size + mtime, git uses mtime + hashes) and use unix timestamps, to make educated guesses.
  • We can enforce a monotonically increasing time, e.g. the watchman uses a random "point in time" stamp, that will always increase. It doesn't have to represent time, but for example things like "since the system started'.
  • We can define lastModified to be purely informational and must not be used for comparision

Open to any suggestions. THrowing it back to you. If it's intended to be purely informational, I am happy to accept as is.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW, unix timestamps + some additional information might be proibably the easiest.

Copy link
Contributor

Choose a reason for hiding this comment

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

However, I assume a client application will want to use this for comparison of the resource has changed.

Strictly speaking, we could add language cautioning about the nonmonotonic risk and leave it up to the client how they want to use it, rather than insisting that they not use it for comparison. (I think most rsync/watchman-like things actually let you decide what to do if you get a backwards-moving timestamp?)

Thinking about it for the first time, but: I think I'd opt for ^ plus more (optional) metadata: hash and size both seem useful in different situations. I don't know how much value we'd add by being opinionated here.

Copy link
Contributor

Choose a reason for hiding this comment

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

HTTP MCP servers will also have a Date header in their responses which clients could use to detect if their clock is ergegiously out of sync. Imo that's probably good enough for most use cases.

Copy link
Member

Choose a reason for hiding this comment

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

@connor4312 That's a transport layer information leaking into the data layer.

Copy link
Contributor

Choose a reason for hiding this comment

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

@connor4312 true, although in this case the client's clock shouldn't enter into the comparison I don't think

Copy link
Member

Choose a reason for hiding this comment

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

I assume that for now we can probably get away with lastModified and add documentation about dealing with non monotone behaviour on the client side if they choose to care.

@dsp-ant dsp-ant added this to the DRAFT 2025-06-XX milestone Jun 5, 2025
dsp-ant
dsp-ant previously approved these changes Jun 10, 2025
Copy link
Member

@dsp-ant dsp-ant left a comment

Choose a reason for hiding this comment

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

@salman1993 mind rebasing this

@dsp-ant dsp-ant merged commit 0c7ad86 into modelcontextprotocol:main Jun 10, 2025
1 check passed
@github-project-automation github-project-automation bot moved this from In Review to Approved in Standards Track Jun 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Approved
Development

Successfully merging this pull request may close these issues.

6 participants