Bring your own MCP server

Your data stays in your own systems. Expose it through an MCP server you run, connect the server in Tools, and its read-only tools join the Hedge Layer catalog. Hedge Layer Agent, scheduled runs, and any client using your Hedge Layer token can then combine your data with Polymarket, Hyperliquid, SEC, macro, and FX data in one conversation.

How it works

  1. Connect. Enter a short name (for example warehouse), the server URL, and an optional bearer token. Hedge Layer lists the server's tools and checks them against the profile below.
  2. Approve. The tools that meet the profile are saved as an approved snapshot; the others are listed with the reason they were skipped. Hedge Layer only exposes and calls the snapshot, so later changes on your server take effect only after you choose Refresh tools.
  3. Use. Each tool appears as u_<name>__<tool> in MCP tools/list and GET /api/v1/tools for your account only. Results are wrapped as { source: { server, tool, trust: "user_supplied", retrieved_at }, result }, so agents never present your data as Hedge Layer-verified.

Hedge Layer MCP profile

The profile is standard MCP with a few conventions, so one server works with Hedge Layer and any other MCP client.

AreaRequirement
TransportStreamable HTTP at a public https:// URL on the default port. Stateless servers work best: Hedge Layer opens a short session per call.
AuthenticationNone, or a static bearer token sent as Authorization: Bearer <token>. Use a token that can only read the data you want to share. OAuth is not supported yet.
CapabilitiesTools only. Resources and prompts are ignored.
SafetyEvery tool must be annotated readOnlyHint: true and not destructiveHint: true. Other tools are skipped.
ContractsEach tool declares an object inputSchema and outputSchema (at most 16 KiB each) and returns matching structuredContent. Results that do not match are rejected.
NamesTool names use 1-44 letters, digits, _ or -. Descriptions over 1,000 characters are truncated. At most 25 tools per server and 5 servers per account.
Size and timeResponses up to 1 MiB within 15 seconds. Agents read results of about 100 KB or less, so page large results.

Recommended financial conventions

  • Return numbers as decimal strings with an explicit unit, as Hedge Layer's own tools do.
  • Use ISO-8601 dates and UTC timestamps. Keep the observation date separate from retrieval time.
  • Include a provenance object, for example { source, as_of }.
  • Identify what each row is about in an entity object with keys agents can join on: ticker, cik, polymarket_slug, hyperliquid_coin, or date.
  • Page large results with a limit input and a next_cursor output.

Example servers

TypeScript, with the official MCP SDK:

import { McpServer, createMcpHandler } from "@modelcontextprotocol/server";
import { z } from "zod";

const handler = createMcpHandler(() => {
  const server = new McpServer({ name: "my-signals", version: "1.0.0" });
  server.registerTool("get_signal", {
    description: "Latest in-house signal for a ticker, from our warehouse.",
    inputSchema: z.object({ ticker: z.string().max(10) }),
    outputSchema: z.object({
      entity: z.object({ ticker: z.string() }),
      value: z.string(), unit: z.string(),
      provenance: z.object({ source: z.string(), as_of: z.string() }),
    }),
    annotations: { readOnlyHint: true, destructiveHint: false },
  }, async ({ ticker }) => {
    const row = await queryWarehouse(ticker); // Databricks SQL, Snowflake, ...
    const result = { entity: { ticker }, value: String(row.score), unit: "z_score",
      provenance: { source: "warehouse.signals.daily", as_of: row.as_of } };
    return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
  });
  return server;
}, { legacy: "stateless", responseMode: "json" });

Python, with the official MCP SDK:

from mcp.server.fastmcp import FastMCP
from mcp.types import ToolAnnotations
from pydantic import BaseModel

mcp = FastMCP("my-signals", stateless_http=True, json_response=True)

class Signal(BaseModel):
    ticker: str
    value: str  # decimal string
    unit: str
    as_of: str  # ISO-8601 date

@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False))
def get_signal(ticker: str) -> Signal:
    """Latest in-house signal for a ticker, from our warehouse."""
    row = query_warehouse(ticker)  # Databricks SQL, Snowflake, ...
    return Signal(ticker=ticker, value=str(row.score), unit="z_score", as_of=row.as_of)

mcp.run(transport="streamable-http")

Security and privacy

  • Hedge Layer calls your server from its own infrastructure. It never forwards your Hedge Layer token, follows no redirects, and only connects to public addresses.
  • Your server token is encrypted at rest, never shown again after you save it, and deleted when you remove the server or your account.
  • Tool arguments chosen by the agent and the results your server returns pass through Hedge Layer and the agent's model provider. Only expose data you are permitted to share with them. See the privacy policy.
  • Treat your server as public-facing: validate inputs and bound queries. Hedge Layer limits calls to about 60 per minute per account.