Skip to content

Integrations ​

Palena WebSearch MCP is an MCP server and works with any MCP-compatible client. This page shows the wiring for the clients teams most often use, plus a minimal example for a custom agent.

For a server that is not running yet, start with Getting Started. For the tool itself, see Tool Reference.


Transport cheat sheet ​

Palena exposes two MCP transports on the same port:

TransportEndpointPreferred client
Streamable HTTPPOST http://<host>:8080/mcpModern MCP clients, custom agents, server-to-server.
SSEGET http://<host>:8080/sse + POST http://<host>:8080/messagesClaude Desktop, older LibreChat builds.

If a client supports both, prefer Streamable HTTP — it is simpler to proxy and easier to debug.


LibreChat ​

Add Palena to the mcpServers block in librechat.yaml:

yaml
mcpServers:
  palena:
    type: streamableHttp
    url: http://palena:8080/mcp

Or, using SSE for older builds:

yaml
mcpServers:
  palena:
    type: sse
    url: http://palena:8080/sse

If LibreChat and Palena are on the same Docker network or the same Kubernetes namespace, use the service name (palena). Restart LibreChat; web_search appears in the tools list automatically for any agent or model that supports tool calling.

Full-stack deployment ​

Running both in Kubernetes? Point LibreChat's mcpServers.palena.url at the ClusterIP service the Helm chart creates:

yaml
mcpServers:
  palena:
    type: streamableHttp
    url: http://palena.palena.svc.cluster.local:8080/mcp

See Deployment for the Helm chart.


Claude Desktop ​

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):

json
{
  "mcpServers": {
    "palena": {
      "url": "http://localhost:8080/sse"
    }
  }
}

Claude Desktop currently uses the SSE transport. Restart the app; web_search appears in the tools tray.

If Palena is on a remote machine, put a TLS-terminating reverse proxy in front of it and point url at the HTTPS address. Palena itself does not terminate TLS — see Deployment.


Cursor / Windsurf ​

Both IDEs support MCP servers via a local configuration file. The exact path differs but the shape is the same.

Cursor — ~/.cursor/mcp.json:

json
{
  "mcpServers": {
    "palena": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Windsurf — ~/.codeium/windsurf/mcp_config.json:

json
{
  "mcpServers": {
    "palena": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Once configured, the web_search tool appears alongside the built-in tools. Cursor shows the pipeline metadata (PII mode, reranker, engines) in its tool-use panel — useful for spot-checking compliance behavior while developing.


Custom agents ​

Palena is MCP-compliant, so any MCP SDK works. The examples below use the official MCP SDKs from modelcontextprotocol.io.

Python ​

python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client("http://localhost:8080/mcp") as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            tools = await session.list_tools()
            print("available:", [t.name for t in tools.tools])

            result = await session.call_tool(
                "web_search",
                arguments={
                    "query": "langchain vs llamaindex 2026",
                    "category": "general",
                    "maxResults": 3,
                },
            )
            for block in result.content:
                print(block.text)

asyncio.run(main())

TypeScript ​

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

const transport = new StreamableHTTPClientTransport(
  new URL("http://localhost:8080/mcp"),
);

const client = new Client({ name: "my-agent", version: "0.1.0" }, { capabilities: {} });
await client.connect(transport);

const tools = await client.listTools();
console.log("available:", tools.tools.map((t) => t.name));

const result = await client.callTool({
  name: "web_search",
  arguments: {
    query: "regulatory changes EU AI Act 2026",
    category: "news",
    timeRange: "month",
    maxResults: 5,
  },
});

for (const block of result.content) {
  if (block.type === "text") console.log(block.text);
}

Bare HTTP (no SDK) ​

MCP is JSON-RPC 2.0 over HTTP — if you cannot use an SDK, call it directly. See the three-step example in Getting Started.


Authentication ​

Palena does not ship authentication. It assumes it sits behind a network boundary:

  • In a Compose stack, Palena is on a private Docker network with the other sidecars. Only the MCP client can reach it.
  • In Kubernetes, the Helm chart creates a ClusterIP service (no Ingress by default).
  • For public exposure, run Palena behind a reverse proxy that handles TLS, mutual TLS, OAuth, or IP allowlisting.

See Deployment — TLS and Ingress for example NGINX and Istio configs.


Troubleshooting the connection ​

SymptomLikely cause
Client reports "no tools"Client connected but skipped the notifications/initialized step. Most SDKs handle this automatically; custom code may need to send it explicitly.
401 Mcp-Session-Id requiredStreamable HTTP session expired or never opened. Re-run initialize.
EHOSTUNREACH in DockerClient container not on the same network as Palena. Add it to the palena_default network or use the host IP.
SSE connection drops every 30 sReverse proxy is buffering or timing out. Disable response buffering and set a long read timeout (NGINX: proxy_buffering off; proxy_read_timeout 1h;).
tool execution failed with no detailsCheck the Palena container logs — the root-cause error is logged at WARN / ERROR level with the OTel trace ID.

What's next ​

Released under the Apache License, Version 2.0.