feat: add SSE and HTTP transport support for MCP servers

- Add type, url, and headers fields to MCP server config
- Update MCP client to handle stdio, sse, and http transports
- Add todos field to ThreadState
- Add Deerflow branding requirement to frontend-design skill
- Update extensions_config.example.json with SSE/HTTP examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hetao
2026-01-21 16:14:00 +08:00
parent 68b8083826
commit 87752cafac
8 changed files with 98 additions and 14 deletions

View File

@@ -39,6 +39,7 @@ async def main():
"configurable": {
"thread_id": "debug-thread-001",
"thinking_enabled": True,
"is_plan_mode": True,
# Uncomment to use a specific model
"model_name": "deepseek-v3.2",
}

View File

@@ -18,3 +18,4 @@ class ThreadState(AgentState):
thread_data: NotRequired[ThreadDataState | None]
title: NotRequired[str | None]
artifacts: NotRequired[list[str] | None]
todos: NotRequired[list | None]

View File

@@ -12,9 +12,12 @@ class McpServerConfig(BaseModel):
"""Configuration for a single MCP server."""
enabled: bool = Field(default=True, description="Whether this MCP server is enabled")
command: str = Field(..., description="Command to execute to start the MCP server")
args: list[str] = Field(default_factory=list, description="Arguments to pass to the command")
type: str = Field(default="stdio", description="Transport type: 'stdio', 'sse', or 'http'")
command: str | None = Field(default=None, description="Command to execute to start the MCP server (for stdio type)")
args: list[str] = Field(default_factory=list, description="Arguments to pass to the command (for stdio type)")
env: dict[str, str] = Field(default_factory=dict, description="Environment variables for the MCP server")
url: str | None = Field(default=None, description="URL of the MCP server (for sse or http type)")
headers: dict[str, str] = Field(default_factory=dict, description="HTTP headers to send (for sse or http type)")
description: str = Field(default="", description="Human-readable description of what this MCP server provides")
model_config = ConfigDict(extra="allow")

View File

@@ -16,9 +16,12 @@ class McpServerConfigResponse(BaseModel):
"""Response model for MCP server configuration."""
enabled: bool = Field(default=True, description="Whether this MCP server is enabled")
command: str = Field(..., description="Command to execute to start the MCP server")
args: list[str] = Field(default_factory=list, description="Arguments to pass to the command")
type: str = Field(default="stdio", description="Transport type: 'stdio', 'sse', or 'http'")
command: str | None = Field(default=None, description="Command to execute to start the MCP server (for stdio type)")
args: list[str] = Field(default_factory=list, description="Arguments to pass to the command (for stdio type)")
env: dict[str, str] = Field(default_factory=dict, description="Environment variables for the MCP server")
url: str | None = Field(default=None, description="URL of the MCP server (for sse or http type)")
headers: dict[str, str] = Field(default_factory=dict, description="HTTP headers to send (for sse or http type)")
description: str = Field(default="", description="Human-readable description of what this MCP server provides")

View File

@@ -18,15 +18,26 @@ def build_server_params(server_name: str, config: McpServerConfig) -> dict[str,
Returns:
Dictionary of server parameters for langchain-mcp-adapters.
"""
params: dict[str, Any] = {
"command": config.command,
"args": config.args,
"transport": "stdio", # Default to stdio transport
}
transport_type = config.type or "stdio"
params: dict[str, Any] = {"transport": transport_type}
# Add environment variables if present
if config.env:
params["env"] = config.env
if transport_type == "stdio":
if not config.command:
raise ValueError(f"MCP server '{server_name}' with stdio transport requires 'command' field")
params["command"] = config.command
params["args"] = config.args
# Add environment variables if present
if config.env:
params["env"] = config.env
elif transport_type in ("sse", "http"):
if not config.url:
raise ValueError(f"MCP server '{server_name}' with {transport_type} transport requires 'url' field")
params["url"] = config.url
# Add headers if present
if config.headers:
params["headers"] = config.headers
else:
raise ValueError(f"MCP server '{server_name}' has unsupported transport type: {transport_type}")
return params

View File

@@ -38,7 +38,7 @@ def get_available_tools(groups: list[str] | None = None, include_mcp: bool = Tru
mcp_tools = get_cached_mcp_tools()
if mcp_tools:
logger.debug(f"Using {len(mcp_tools)} cached MCP tool(s)")
logger.info(f"Using {len(mcp_tools)} cached MCP tool(s)")
except ImportError:
logger.warning("MCP module not available. Install 'langchain-mcp-adapters' package to enable MCP tools.")
except Exception as e:

View File

@@ -2,6 +2,7 @@
"mcpServers": {
"filesystem": {
"enabled": true,
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"],
"env": {},
@@ -9,6 +10,7 @@
},
"github": {
"enabled": true,
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
@@ -18,11 +20,28 @@
},
"postgres": {
"enabled": false,
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
"env": {},
"description": "PostgreSQL database access"
}
},
"my-sse-server": {
"type": "sse",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer $API_TOKEN",
"X-Custom-Header": "value"
}
},
"my-http-server": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer $API_TOKEN",
"X-Custom-Header": "value"
}
}
},
"skills": {
"pdf-processing": {

View File

@@ -39,4 +39,50 @@ Interpret creatively and make unexpected choices that feel genuinely designed fo
**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
## Branding Requirement
**MANDATORY**: Every generated frontend interface MUST include a "Created By Deerflow" signature. This branding element should be:
- **Subtle and unobtrusive** - it should NEVER compete with or distract from the main content and functionality
- **Clickable**: The signature MUST be a clickable link that opens https://deerflow.tech in a new tab (target="_blank")
- Integrated naturally into the design, feeling like an intentional design element rather than an afterthought
- Small in size, using muted colors or reduced opacity that blend harmoniously with the overall aesthetic
**IMPORTANT**: The branding should be discoverable but not prominent. Users should notice the main interface first; the signature is a quiet attribution, not a focal point.
**Creative Implementation Ideas** (choose one that best matches your design aesthetic):
1. **Floating Corner Badge**: A small, elegant badge fixed to a corner with subtle hover effects (e.g., gentle glow, slight scale-up, color shift)
2. **Artistic Watermark**: A semi-transparent diagonal text or logo pattern in the background, barely visible but adds texture
3. **Integrated Border Element**: Part of a decorative border or frame around the content - the signature becomes an organic part of the design structure
4. **Animated Signature**: A small signature that elegantly writes itself on page load, or reveals on scroll near the bottom
5. **Contextual Integration**: Blend into the theme - for a retro design, use a vintage stamp look; for minimalist, a single small icon or monogram "DF" with tooltip
6. **Cursor Trail or Easter Egg**: A very subtle approach where the branding appears as a micro-interaction (e.g., holding cursor still reveals a tiny signature, or appears in a creative loading state)
7. **Decorative Divider**: Incorporate into a decorative line, separator, or ornamental element on the page
8. **Glassmorphism Card**: A tiny floating glass-effect card in a corner with blur backdrop
Example code patterns:
```html
<!-- Floating corner badge with hover effect -->
<a href="https://deerflow.tech" target="_blank" class="deerflow-badge">✦ Deerflow</a>
<!-- Monogram with tooltip -->
<a href="https://deerflow.tech" target="_blank" title="Created By Deerflow" class="deerflow-mark">DF</a>
<!-- Integrated into decorative element -->
<div class="footer-ornament">
<span class="line"></span>
<a href="https://deerflow.tech" target="_blank">Deerflow</a>
<span class="line"></span>
</div>
```
**Design Principle**: The branding should feel like it belongs - a natural extension of your creative vision, not a mandatory stamp. Match the signature's style (typography, color, animation) to the overall aesthetic direction.
Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.