Connecting Remote MCP Servers to Flue Agents with Authentication
Use the connectMcpServer helper from @flue/sdk/client to establish authenticated connections to remote Model Context Protocol (MCP) servers, passing bearer tokens via the headers option and injecting discovered tools into your agent harness through init({ tools }).
Flue agents extend their capabilities by consuming tools hosted on remote MCP servers. According to the withastro/flue source code, the SDK provides a dedicated connection helper that handles transport negotiation, header injection, and tool discovery, enabling secure authenticated integrations with external tool providers.
How the Flue SDK Handles MCP Authentication
The authentication flow centers on the McpServerOptions interface defined in packages/sdk/src/mcp.ts (lines 8‑14). This configuration object accepts a headers field that allows you to inject any HTTP headers—including Authorization bearer tokens—into every request sent to the remote MCP server.
Header Injection and Merging
When you provide custom headers, the SDK merges them with any existing requestInit configuration using the internal mergeRequestInit utility (lines 13‑22 in packages/sdk/src/mcp.ts). This ensures your authentication tokens take precedence while preserving additional fetch options you might specify.
// From mcp.ts - merges headers ensuring auth tokens are preserved
const mergedInit = mergeRequestInit(
{ headers: { Authorization: `Bearer ${env.TOKEN}` } },
userProvidedInit
);
The connectMcpServer function (lines 25‑55) then uses these merged options to build the transport layer, negotiate the connection, and return a McpServerConnection object containing the discovered tools.
Step-by-Step Implementation
1. Configure the Connection with Environment Variables
Never hardcode secrets. Instead, access tokens through the env object available in your Flue agent function. Call connectMcpServer with a descriptive name and the remote URL:
// .flue/agents/github-assist.ts
import { connectMcpServer } from '@flue/sdk/client';
const github = await connectMcpServer('github', {
url: 'https://mcp.github.com/mcp',
headers: {
Authorization: `Bearer ${env.GITHUB_TOKEN}`, // Securely injected
},
});
2. Initialize the Harness with Remote Tools
The connection object exposes a tools array containing the remote MCP tools formatted for Flue's harness system. Pass these to the init function alongside your model configuration:
const harness = await init({
model: 'anthropic/claude-sonnet-4-6',
tools: github.tools, // Remote tools become available to the LLM
});
3. Cleanup Resources After Execution
Remote connections hold active HTTP sessions and SSE streams. Always close the connection in a finally block to prevent resource leaks:
try {
const session = await harness.session();
return await session.prompt(payload.prompt);
} finally {
await github.close(); // Releases underlying client resources
}
Transport Protocol Options
Streamable HTTP (Default)
The modern streamable‑http transport is the default in Flue. It uses standard HTTP requests with streaming response bodies for efficient bidirectional communication. This mode works automatically when you omit the transport option or set it explicitly to 'streamable-http'.
Legacy SSE Mode
For older MCP servers that require Server-Sent Events, force the transport by setting transport: 'sse' in your options:
const legacy = await connectMcpServer('legacy-server', {
url: 'https://old-mcp.example.com/sse',
transport: 'sse',
headers: { Authorization: `Bearer ${env.TOKEN}` },
});
Advanced Configuration
Pass additional fetch parameters through the requestInit option. These are merged with your authentication headers via the internal mergeRequestInit logic:
const github = await connectMcpServer('github', {
url: 'https://mcp.github.com/mcp',
headers: { Authorization: `Bearer ${env.GITHUB_TOKEN}` },
requestInit: {
mode: 'cors',
cache: 'no-store'
},
});
Complete Working Example
Here is the canonical implementation from the withastro/flue repository demonstrating secure authentication and proper resource management:
// .flue/agents/github-assist.ts
import { connectMcpServer, type FlueContext } from '@flue/sdk/client';
export const triggers = { webhook: true };
export default async function ({ init, payload, env }: FlueContext) {
// Establish authenticated connection
const github = await connectMcpServer('github', {
url: 'https://mcp.github.com/mcp',
headers: {
Authorization: `Bearer ${env.GITHUB_TOKEN}`,
},
});
try {
// Initialize harness with remote tools
const harness = await init({
model: 'anthropic/claude-sonnet-4-6',
tools: github.tools,
});
// Execute agent logic
const session = await harness.session();
return await session.prompt(payload.prompt);
} finally {
// Critical: Release connection resources
await github.close();
}
}
Key Source Files
packages/sdk/src/mcp.ts– Core implementation ofconnectMcpServer, transport selection, and themergeRequestInitutility (lines 8‑55).packages/sdk/src/client.ts– Public API surface that re‑exportsconnectMcpServerfor convenient importing (lines 59‑62).README.md– Canonical usage examples in the "Remote MCP Tools" section (lines 93‑124).
Summary
connectMcpServerhandles transport negotiation, authentication header injection, and tool discovery in a single async call.- Authentication tokens pass securely through the
headersfield ofMcpServerOptions, merged viamergeRequestInitto preserve precedence. - Remote tools integrate seamlessly into the Flue harness by passing the
toolsarray from the connection toinit({ tools }). - Resource management requires explicit
close()calls to terminate underlying HTTP clients and SSE connections. - Environment variables (
env) provide the secure mechanism for accessing secrets without exposing them in code.
Frequently Asked Questions
How do I securely store authentication tokens for MCP servers?
Store sensitive tokens as environment variables in your Flue project configuration. The env object injected into every agent function provides secure runtime access to these values. Never commit credentials to your repository or hardcode them in agent files.
What transport protocols does Flue support for MCP connections?
Flue supports streamable-http (modern default) and sse (legacy Server-Sent Events). The SDK automatically negotiates the appropriate transport unless you explicitly override it via the transport option in McpServerOptions.
Can I combine remote MCP tools with local custom tools?
Yes. The tools array accepted by init() accepts any combination of remote tools (from connectMcpServer) and local tool definitions. You can merge multiple remote connections and local implementations into a single tools array passed to the harness.
How do I handle connection errors and retries?
Wrap connectMcpServer calls in try-catch blocks to handle network failures. The underlying MCP client throws descriptive errors for connection timeouts, authentication failures (401/403), and transport negotiation issues. Implement retry logic around the initial connection call if your use case requires high availability.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →