# Custom agents & MCP clients

> Connect any MCP client or your own agent to f1ow over Streamable HTTP, by OAuth, API key, key-in-path or x402 pay-per-call.

Source: https://www.f1ow.com/docs/connect/custom-agent

f1ow is a remote MCP server over **Streamable HTTP**. Any client that speaks MCP can connect. Pick the endpoint for your authentication method:

| Endpoint | URL |
| --- | --- |
| MCP · OAuth | `https://mcp.f1ow.com/mcp` |
| MCP · Bearer | `https://mcp.f1ow.com` |
| MCP · x402 | `https://mcp.f1ow.com/x402` |
| MCP · Key in path | `https://mcp.f1ow.com/key/<your-key>` |

- **OAuth**: for clients that run the MCP authorization flow (discovery, dynamic client registration, PKCE). See [authentication](https://www.f1ow.com/docs/auth#oauth).
- **Bearer**: send `Authorization: Bearer <your-key>`.
- **Key in path**: for clients that cannot set headers. Treat the URL as a secret.
- **x402**: no account. The agent pays per call in USDC on Base. See [x402](https://www.f1ow.com/docs/auth#x402).

## The protocol in three requests

```bash
# 1. initialize
curl -s https://mcp.f1ow.com/ \
  -H "Authorization: Bearer $F1OW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'

# 2. list the tools (names, descriptions, JSON input schemas)
#    -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

# 3. call one
#    -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"funding_current","arguments":{"symbol":"BTC"}}}'
```

Send `notifications/initialized` after `initialize`, and echo the `Mcp-Session-Id` response header on later requests if the server sends one. The server may answer with JSON or a short `text/event-stream`, so accept both. MCP SDKs handle all of this for you.

## With an SDK

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(
  new StreamableHTTPClientTransport(new URL("https://mcp.f1ow.com/"), {
    requestInit: { headers: { Authorization: `Bearer ${process.env.F1OW_API_KEY}` } },
  }),
);

const { tools } = await client.listTools();
const result = await client.callTool({ name: "research_regime", arguments: {} });
console.log(result.structuredContent ?? result.content);
```

## Reading results

A `tools/call` result has:

- `content`: a text report written for a model to read. Pass it to your LLM as is.
- `structuredContent`: the same result as JSON, typed by the tool's output schema. REST and WebSocket return just this object.
- `_meta`: for example, the view an MCP Apps host can render.

Results are snapshots. Check `generatedAt` and the coverage notes before acting on them, and call again, or [subscribe over WebSocket](https://www.f1ow.com/docs/api/websocket), for fresh data.

## Discovery

Agents can find everything without reading this page:

- MCP discovery card: [`/.well-known/mcp.json`](https://mcp.f1ow.com/.well-known/mcp.json)
- API catalog (RFC 9727): [`/.well-known/api-catalog`](https://mcp.f1ow.com/.well-known/api-catalog)
- OAuth protected-resource metadata (RFC 9728): [`/.well-known/oauth-protected-resource`](https://mcp.f1ow.com/.well-known/oauth-protected-resource)
- Official MCP Registry entry: `com.f1ow/f1ow`

> Get an API key for your agent: https://www.f1ow.com/dashboard
