newStreamableHTTPServerProxy creates an MCP server capable of proxying requests using the Streamable HTTP transport. TODO: support SSE transport.
(cfg *proto.MCPServerConfig, accessToken string)
| 155 | // |
| 156 | // TODO: support SSE transport. |
| 157 | func (m *MCPProxyFactory) newStreamableHTTPServerProxy(cfg *proto.MCPServerConfig, accessToken string) (mcp.ServerProxier, error) { |
| 158 | if cfg == nil { |
| 159 | return nil, ErrEmptyConfig |
| 160 | } |
| 161 | |
| 162 | var ( |
| 163 | allowlist, denylist *regexp.Regexp |
| 164 | err error |
| 165 | ) |
| 166 | if cfg.GetToolAllowRegex() != "" { |
| 167 | allowlist, err = regexp.Compile(cfg.GetToolAllowRegex()) |
| 168 | if err != nil { |
| 169 | return nil, ErrCompileRegex |
| 170 | } |
| 171 | } |
| 172 | if cfg.GetToolDenyRegex() != "" { |
| 173 | denylist, err = regexp.Compile(cfg.GetToolDenyRegex()) |
| 174 | if err != nil { |
| 175 | return nil, ErrCompileRegex |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | // TODO: future improvement: |
| 180 | // |
| 181 | // The access token provided here may expire at any time, or the connection to the MCP server could be severed. |
| 182 | // Instead of passing through an access token directly, rather provide an interface through which to retrieve |
| 183 | // an access token imperatively. In the event of a tool call failing, we could Ping() the MCP server to establish |
| 184 | // whether the connection is still active. If not, this indicates that the access token is probably expired/revoked. |
| 185 | // (It could also mean the server has a problem, which we should account for.) |
| 186 | // The proxy could then use its interface to retrieve a new access token and re-establish a connection. |
| 187 | // For now though, the short TTL of this cache should mostly mask this problem. |
| 188 | srv, err := mcp.NewStreamableHTTPServerProxy( |
| 189 | cfg.GetId(), |
| 190 | cfg.GetUrl(), |
| 191 | // See https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization#token-requirements. |
| 192 | map[string]string{ |
| 193 | "Authorization": fmt.Sprintf("Bearer %s", accessToken), |
| 194 | }, |
| 195 | allowlist, |
| 196 | denylist, |
| 197 | m.logger.Named(fmt.Sprintf("mcp-server-proxy-%s", cfg.GetId())), |
| 198 | m.tracer, |
| 199 | ) |
| 200 | if err != nil { |
| 201 | return nil, xerrors.Errorf("create streamable HTTP MCP server proxy: %w", err) |
| 202 | } |
| 203 | |
| 204 | return srv, nil |
| 205 | } |