Support Runtime Variables in MCP Server Headers
- Dominant language
- TypeScript
- Stars
- 156k
- Forks
- 24.6k
- Avg merge
- 22h 9m
- Merged PRs (30d)
- 610
Description
### Self Checks
- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] Please do not modify this template :) and fill in all the required fields.
### 1. Is this request related to a challenge you're experiencing? Tell me about your story.
Feature Request
Title
Support Runtime Variables in MCP Server Headers
Summary
Currently, Dify supports configuring static headers for MCP Servers.
Example:
{
"transport": "streamable_http",
"url": "http://mcp-host:3010/mcp",
"headers": {
"Authorization": "Bearer ${MCP_SERVICE_TOKEN}"
}
}
However, headers only support environment variables and cannot access runtime context.
This makes it difficult to implement enterprise scenarios where MCP Servers require per-user identity or credentials.
Problem Statement
Many enterprise MCP Servers need user-specific authentication.
Examples:
ERP
CRM
Jira
GitHub Enterprise
Microsoft Graph
Feishu
DingTalk
Typically every user has:
ERP Token
OAuth Access Token
SSO Session
Tenant ID
User ID
These values are only available at runtime.
Currently there is no way to inject them into MCP HTTP headers.
Developers must:
modify Dify source code
build a Gateway
or expose security tokens as Tool parameters
The last option is not recommended because credentials become part of the LLM prompt.
Proposal
Support runtime template variables inside MCP headers.
Example:
{
"transport": "streamable_http",
"url": "http://mcp-host:3010/mcp",
"headers": {
"Authorization": "Bearer ${MCP_SERVICE_TOKEN}",
"X-Dify-User": "{{user}}",
"X-Dify-Conversation": "{{conversation_id}}",
"X-Erp-Token": "{{inputs.erp_user_token}}",
"X-Tenant": "{{inputs.tenant_id}}"
}
}
Before sending the MCP request, Dify resolves runtime variables.
Example:
{{user}}
→ zhangsan
{{conversation_id}}
→ conv_123456
{{inputs.erp_user_token}}
→ eyJhbGc...
{{inputs.tenant_id}}
→ trade-app
Suggested Runtime Variables
User
{{user}}
API Request
"user":"zhangsan"
Conversation
{{conversation_id}}
App
{{app_id}}
Query
{{query}}
Workflow Inputs
{{inputs.xxx}}
Examples:
{{inputs.erp_user_token}}
{{inputs.company_id}}
{{inputs.department_id}}
Optional
Environment variables remain unchanged.
${ENV_NAME}
For example
${MCP_SERVICE_TOKEN}
Benefits
Enterprise Authentication
Per-user ERP authentication
Per-user OAuth token
Per-user SSO
Security
Credentials stay inside HTTP headers.
LLM never sees them.
No prompt injection risk.
Cleaner MCP Tool Schema
Current
query_salary(
token,
year
)
Expected
query_salary(
year
)
Authentication is handled by HTTP headers.
Backward Compatibility
Existing MCP configurations continue to work.
Only template resolution is added.
Example
Chat API
{
"user":"zhangsan",
"inputs":{
"erp_user_token":"abc123",
"tenant":"trade-app"
},
"query":"查询我的工资"
}
Configured MCP headers
{
"Authorization":"Bearer ${MCP_SERVICE_TOKEN}",
"X-Dify-User":"{{user}}",
"X-Erp-Token":"{{inputs.erp_user_token}}",
"X-Tenant":"{{inputs.tenant}}"
}
Actual HTTP Request
Authorization: Bearer xxxxxx
X-Dify-User: zhangsan
X-Erp-Token: abc123
X-Tenant: trade-app
MCP Server can authenticate users without exposing credentials to the LLM.
### 2. Additional context or comments
1 、Query Parameter Support runtime variables
http://mcp-server/mcp?tenant={{inputs.tenant}}
2、Dynamic Credential Provider
Allow MCP Server configuration:
Credential Source
○ Static ENV
● Runtime Input
○ Dify User Credential
○ Plugin Credential
### 3. Can you help us with this feature?
- [x] I am interested in contributing to this feature.
Contributor guide
Research direction
The issue identifies MCP server header configuration, Chat API inputs, and outbound HTTP requests as the relevant entry points, but names no files or tests. First trace how MCP headers are configured and sent, then define runtime resolution for user, conversation, app, query, and workflow-input values while preserving environment-variable behavior and backward compatibility.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100