forcedotcom / forcedotcom/mcp-hosted
[Feature]: Ability to configure the MCP `instructions` field in the initialize response
- Dominant language
- No language data
- Stars
- 135
- Forks
- 20
- PR merge metrics
- No merged PRs in 30d
Description
### Problem statement
Salesforce hosted MCP servers do not have the ability to configure the `instructions` field in the `initialize` response. This is a first-class field defined in the [MCP specification (2025-11-25 Lifecycle)](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle) that allows servers to provide persistent, system-level guidance to the LLM about **how to use the server's tools together** — things that cannot be expressed in any single tool's `description`.
Without this field, there is no server-side mechanism for Salesforce (or admins building custom hosted servers) to tell the LLM about:
- **Multi-tool orchestration** — which tools to chain together and in what order for common workflows
- **Cross-tool constraints** — rules that span multiple tools (e.g., "if you mutate a record, always re-query it afterward to confirm the change")
- **Server-wide behavioral rules** — output formatting, confirmation policies, safety guardrails that apply uniformly across all tools
- **Domain context that no single tool owns** — Salesforce platform conventions, org-specific terminology, or how the server's tools map to higher-level user intents
Today, the only guidance the LLM receives is individual tool `description` fields. These are scoped to a single tool and cannot express any of the above. The `instructions` field is the MCP-standard solution for exactly this gap.
**Who is affected:** Anyone connecting an MCP client (Claude, ChatGPT, Cursor, Claude Code, etc.) to Salesforce hosted MCP servers. The LLM must independently guess at tool relationships and Salesforce-specific conventions rather than being informed by the server.
### Proposed solution
Abiliity to configure and return the `instructions` field in the server's `initialize` response, as defined by the MCP spec.
Per the [MCP Lifecycle specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle), the server's `InitializeResult` supports a top-level `instructions` string:
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-11-25",
"capabilities": { ... },
"serverInfo": { ... },
"instructions": "Server-level instructions for the LLM go here"
}
}
```
MCP clients inject this string into the LLM's system context at connection time, so it persists for the entire session — unlike prompts, which require explicit user invocation.
**Specifically, I'd like to see two things:**
### 1. Salesforce-authored instructions on built-in servers
For servers like `sobject-all`, `apex`, `soql`, etc. — curated instructions that encode cross-tool orchestration patterns. These are things that **cannot live in any individual tool's description** because they span multiple tools:
```
Recommended multi-tool workflows:
- Record exploration: When the user asks about an unfamiliar object, call
sobject_describe FIRST to learn the available fields, then construct a
soql_query using only valid field API names. Do not guess field names.
- Safe mutations: Before calling sobject_update or sobject_delete, always
retrieve the current record with sobject_get and present the current
values to the user for confirmation. Never mutate without confirming.
- Bulk analysis: For "how many" or "show me all" requests, prefer
soql_query with aggregation (COUNT, SUM, GROUP BY) over retrieving
all records and counting client-side.
Cross-tool rules:
- All object and field references across every tool use Salesforce API
names (e.g., Custom_Object__c, My_Field__c), never labels. If the
user provides a display label, use sobject_describe to resolve it to
the API name before passing it to any other tool.
- When a soql_query returns records that the user then wants to modify,
pass the record IDs from the query result directly to sobject_update.
Do not ask the user to provide IDs they've already seen.
```
Note how each of these rules references **multiple tools by name** and describes their interaction — this is fundamentally impossible to express inside a single tool's `description` field.
### 2. Admin-configurable instructions on custom MCP servers
When admins create custom hosted MCP servers via Setup (attaching Flows, APIs, Apex, etc.), they should be able to provide their own `instructions` string. This lets admins encode org-specific, cross-tool knowledge that the LLM cannot infer:
- "This server exposes three tools: `search_products`, `check_inventory`, and `create_order`. The correct workflow is always search → check → create. Never call `create_order` without first verifying stock via `check_inventory`."
- "When the user says 'revenue', they mean Opportunities with `StageName = 'Closed Won'` — this applies across all tools on this server that accept filter parameters."
- "This server connects to a sandbox org. All tool results should be prefixed with [SANDBOX] so the user never mistakes test data for production."
---
### Alternatives considered
**Current workaround: client-side instructions.** Users must manually add instructions in their MCP client configuration or system prompts. For example, in Claude Code you can add server instructions in `settings.json`. This is:
- **Fragile** — every user must independently figure out the right instructions
- **Not portable** — instructions don't travel with the server; each client/user must be configured separately
- **Not scalable** — admins building custom servers for their org cannot push domain knowledge to every connected client
- **Contrary to MCP's design** — the spec explicitly provides `instructions` so that servers own this responsibility, not clients
**Individual tool descriptions.** Useful for per-tool guidance ("what this tool does, what its parameters mean"), but structurally unable to express cross-tool workflows, multi-step orchestration, or server-wide behavioral rules. A tool description says "what I do"; `instructions` says "how to use all of us together."
**Prompts.** MCP prompts are user-controlled templates that require explicit invocation (like slash commands). They are the wrong fit because server-level guidance should be **always active** — the LLM needs to know how to orchestrate tools at all times, not only when the user remembers to trigger a specific prompt.
### Area of impact
MCP Tools
### Additional context
**MCP Spec References:**
- [Lifecycle — `InitializeResult` with `instructions` field](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle) — shows `"instructions": "Optional instructions for the client"` as a top-level field in the server's initialize response
- [Server Concepts — Tools, Resources, Prompts](https://modelcontextprotocol.io/docs/learn/server-concepts) — explains the three primitives and their control models
- [Tools Specification](https://modelcontextprotocol.io/specification/2025-11-25/server/tools) — per-tool `description` field, which is complementary but scoped to individual tools
**Why `instructions` fills a gap that other primitives cannot:**
| Mechanism | Scope | Control | Persistence | Best for |
|---|---|---|---|---|
| **`instructions`** | Entire server | Server author / admin | Always active, full session | **Cross-tool orchestration, multi-tool workflows, server-wide rules** |
| Tool `description` | Single tool | Server author | Always active | What one tool does and how to call it |
| Prompts | Task template | End user | Only when explicitly invoked | User-triggered workflows (e.g., "generate a report") |
| Resources | Data source | Application | On demand | Passive context (files, schemas, docs) |
The key gap today: there is no mechanism for the server to say "here is how tools A, B, and C work **together**." That is precisely what `instructions` is for.
Contributor guide
Assessment
This issue has not been assessed yet.