Skip to content

Add MCP_INSTRUCTIONS support to fast-time-server - #58

Merged
jonpspri merged 1 commit into
mainfrom
issue-57
Oct 15, 2026
Merged

jonpspri merged 1 commit into
mainfrom
issue-57

Conversation

@jonpspri

Copy link
Copy Markdown
Collaborator

Closes #57

Summary

Returns a configurable instructions string in both the legacy initialize result (2025-11-25) and the modern server/discover result (2026-07-28).

Behaviour

MCP_INSTRUCTIONS instructions field
Unset (default) "Fast Time Server. Use get_system_time for the current time. Use convert_time to convert a time between timezones."
Non-empty value That value
Empty string "" Field omitted from both responses

Implementation notes

  • The default text is stored in a DEFAULT_INSTRUCTIONS constant.
  • instructions_from_env() reads MCP_INSTRUCTIONS at startup and returns Option<String>.
  • The value is stored on FastTimeServer and used in get_info() via with_instructions().
  • The rmcp SDK already propagates instructions from ServerConfig (alias for InitializeResult) into DiscoverResult::from_server_info(), so both eras are covered by a single field with no extra code.

Tests added (6 new)

  • Default text present in initialize
  • Default text present in server/discover
  • Empty env var omits field in initialize
  • Empty env var omits field in server/discover
  • Custom value returned in initialize
  • Custom value returned in server/discover

All 51 tests pass. cargo clippy --all-targets and cargo fmt are clean.

Return a configurable instructions string in both the legacy
initialize result (2025-11-25) and the modern server/discover
result (2026-07-28).

Behaviour:
- MCP_INSTRUCTIONS unset or absent → default text:
  "Fast Time Server. Use get_system_time for the current time.
  Use convert_time to convert a time between timezones."
- MCP_INSTRUCTIONS set to a non-empty value → that value
- MCP_INSTRUCTIONS set to empty string → field omitted from both

The default text was wired directly into get_info() via
with_instructions(); the rmcp SDK already propagates instructions
from ServerConfig (InitializeResult) into DiscoverResult through
DiscoverResult::from_server_info(), so both eras are covered by
the single field.

Six acceptance-criteria tests added:
- default text present in initialize
- default text present in server/discover
- empty env var omits field in initialize
- empty env var omits field in server/discover
- custom value returned in initialize
- custom value returned in server/discover

README updated with MCP_INSTRUCTIONS variable documentation.

Closes #57

Signed-off-by: Jonathan Springer <jps@s390x.com>

@lucarlig lucarlig left a comment

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.

Reviewed commit 457061e. No blocking issues found.

Verified top-level instructions in both initialize and server/discover: exact required default, custom value, and complete field omission for empty MCP_INSTRUCTIONS. Confirmed configuration and discovery propagation against the locked rmcp 3.5.0 source.

Validation: cargo test --locked (51 passed), cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, and cargo build --locked. Ran the built server with MCP_INSTRUCTIONS unset, empty, and custom and checked both endpoints over HTTP (6 passed). All 7 GitHub checks passed.

@Lang-Akshay Lang-Akshay left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

@jonpspri
jonpspri merged commit f508f79 into main Oct 15, 2026
7 checks passed
jonpspri added a commit to IBM/mcp-context-forge that referenced this pull request Oct 16, 2026
Add black-box tests for the `instructions` text of a virtual server. Each
scenario runs in the legacy era (`initialize`) and the modern era
(`server/discover`). The scenarios cover a single upstream server, a subset
of its tools, a mix of upstream and local tools, an override, an empty
override, an update through PUT, and the global endpoint.

Pin the fast-time-server image in `docker-compose.yml` to the build that
sends `instructions` (IBM/contextforge-examples#58, closes #57). The image
exposes one more tool, `whoami`, which needs no change to the benchmark
denylist. The tests expect the fast-time-server text from a single-upstream
virtual server. `FAST_TIME_INSTRUCTIONS` selects another expected text.

Document the resolution order, the single-upstream rule, and the meaning of
`null` and an empty string in the REST API guide. State that upstream text
changes at the next refresh and that a client can put it in a model prompt.
Add a CHANGELOG entry.

Part of #4693

Signed-off-by: Jonathan Springer <jps@s390x.com>
jonpspri added a commit to IBM/mcp-context-forge that referenced this pull request Oct 16, 2026
Add black-box tests for the `instructions` text of a virtual server. Each
scenario runs in the legacy era (`initialize`) and the modern era
(`server/discover`). The scenarios cover a single upstream server, a subset
of its tools, a mix of upstream and local tools, an override, an empty
override, an update through PUT, and the global endpoint.

Pin the fast-time-server image in `docker-compose.yml` to the build that
sends `instructions` (IBM/contextforge-examples#58, closes #57). The image
exposes one more tool, `whoami`, which needs no change to the benchmark
denylist. The tests expect the fast-time-server text from a single-upstream
virtual server. `FAST_TIME_INSTRUCTIONS` selects another expected text.

Document the resolution order, the single-upstream rule, and the meaning of
`null` and an empty string in the REST API guide. State that upstream text
changes at the next refresh and that a client can put it in a model prompt.
Add a CHANGELOG entry.

Part of #4693

Signed-off-by: Jonathan Springer <jps@s390x.com>
jonpspri added a commit to IBM/mcp-context-forge that referenced this pull request Oct 16, 2026
Add black-box tests for the `instructions` text of a virtual server. Each
scenario runs in the legacy era (`initialize`) and the modern era
(`server/discover`). The scenarios cover a single upstream server, a subset
of its tools, a mix of upstream and local tools, an override, an empty
override, an update through PUT, and the global endpoint.

Pin the fast-time-server image in `docker-compose.yml` to the build that
sends `instructions` (IBM/contextforge-examples#58, closes #57). The image
exposes one more tool, `whoami`, which needs no change to the benchmark
denylist. The tests expect the fast-time-server text from a single-upstream
virtual server. `FAST_TIME_INSTRUCTIONS` selects another expected text.

Document the resolution order, the single-upstream rule, and the meaning of
`null` and an empty string in the REST API guide. State that upstream text
changes at the next refresh and that a client can put it in a model prompt.
Add a CHANGELOG entry.

Part of #4693

Signed-off-by: Jonathan Springer <jps@s390x.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Return instructions from fast-time-server (initialize and server/discover)

3 participants