OmniForge

Product guides · Trusted local networks only

Connecting MCP clients

OmniForge publishes your enabled tools, plus two built-in helpers, at one endpoint:

http://your-host:8000/mcp

The Connect screen in the dashboard shows the exact URL, based on the address you opened it from, and whether a key is required.

Local/trusted clients only. The quickstart binds to 127.0.0.1; another host or container cannot use that host-local address. Cloud connectors need authentication and isolation work beyond this guide. Never make the open dashboard public just to satisfy a remote connector. There are no human logins, per-user accounts or tenant boundaries.

What the endpoint actually speaks

Read this before choosing a client. OmniForge's MCP transport is handwritten and partial.

Supported Not supported
POST /mcp with one JSON-RPC 2.0 request object and Content-Type: application/json Full MCP Streamable HTTP: no SSE responses, no Mcp-Session-Id, no resumable streams
Methods initialize, tools/list, tools/call, ping The legacy HTTP+SSE transport. GET /mcp is a stub that sends one event and closes
Plain application/json responses OAuth, or any discovery under /.well-known/…
Optional Authorization: Bearer <key> header Notifications, including notifications/tools/list_changed, and JSON-RPC batches

Full details are in MCP protocol support.

[!IMPORTANT] Client compatibility is not verified. The project's tests exercise the JSON-RPC handler directly; they don't run any third-party client. The configurations below match what the server accepts, but whether a given client version tolerates the gaps above is for you to check. A quick tools/list from the client is the test.

Before you connect

Claude Code

Unverified configuration: test your exact client version.

Add the server with the CLI:

claude mcp add --transport http omniforge http://your-host:8000/mcp \
  --header "Authorization: Bearer <YOUR_API_KEY>"

Leave out --header if you didn't set a key. Add --scope project to write it to the project's .mcp.json, or --scope user for every project.

Or put it in .mcp.json yourself, referencing an environment variable so the key stays out of the file:

{
  "mcpServers": {
    "omniforge": {
      "type": "http",
      "url": "http://your-host:8000/mcp",
      "headers": {
        "Authorization": "Bearer ${OMNIFORGE_API_KEY}"
      }
    }
  }
}

Check it with claude mcp list, or with /mcp inside a session. If first calls to tools with packages time out, raise Claude Code's tool timeout (the MCP_TOOL_TIMEOUT environment variable, in milliseconds), or warm the cache from the dashboard first.

Claude Desktop

Unverified bridge configuration: test your exact client and bridge versions.

The configuration below starts a local (stdio) bridge through claude_desktop_config.json. To reach an HTTP server on your LAN, run a stdio-to-HTTP bridge. The community package mcp-remote is the usual choice, and needs Node.js on the desktop machine.

Config file locations:

{
  "mcpServers": {
    "omniforge": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://your-host:8000/mcp",
        "--allow-http",
        "--transport",
        "http-only",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer <YOUR_API_KEY>"
      }
    }
  }
}

Do not expose OmniForge publicly for a cloud connector. A local bridge does not add server authentication or guarantee transport compatibility.

LibreChat

Unverified configuration: test your exact client version.

In librechat.yaml:

mcpServers:
  omniforge:
    type: streamable-http
    url: http://your-host:8000/mcp
    headers:
      Authorization: "Bearer ${OMNIFORGE_API_KEY}"
    timeout: 120000

Generic HTTP

Any HTTP client can talk to OmniForge. No session handshake is needed: each POST stands alone.

1. Initialise (optional, but polite):

curl -s http://your-host:8000/mcp \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"omniforge-mcp","version":"0.1.0"}}}

OmniForge echoes back whatever protocolVersion you send.

2. List tools:

curl -s http://your-host:8000/mcp \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {"name": "omniforge_instructions", "description": "Read how to author and register trusted Python/Node scripts…", "inputSchema": {"type": "object", "properties": {}, "additionalProperties": false}},
      {"name": "omniforge_create_tool", "description": "Save a new trusted script as a tool without executing it…", "inputSchema": {"…": "…"}},
      {"name": "add_vat", "description": "Add UK VAT to a net amount…", "inputSchema": {"type": "object", "properties": {"net": {"type": "number", "minimum": 0}}, "required": ["net"], "additionalProperties": false}}
    ]
  }
}

3. Call a tool:

curl -s http://your-host:8000/mcp \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"add_vat","arguments":{"net":10}}}'

Python (standard library only):

import json
import os
import urllib.request

def mcp(method, params=None, *, url="http://your-host:8000/mcp", request_id=1):
    body = json.dumps({"jsonrpc": "2.0", "id": request_id, "method": method, "params": params or {}}).encode()
    headers = {"Content-Type": "application/json"}
    if key := os.environ.get("OMNIFORGE_API_KEY"):
        headers["Authorization"] = f"Bearer {key}"
    with urllib.request.urlopen(urllib.request.Request(url, body, headers), timeout=300) as response:
        return json.load(response)

print(mcp("tools/call", {"name": "add_vat", "arguments": {"net": 10}})["result"]["content"][0]["text"])

When it doesn't connect

Symptom Likely cause
HTTP 401, {"error":{"code":-32000,"message":"Unauthorized"}} Missing or wrong key. The header must be Authorization: Bearer <key>.
HTTP 422 with a FastAPI detail body The body isn't a single JSON object: an empty body, a batch array, or the wrong Content-Type.
Method not found: notifications/initialized in a log Harmless. OmniForge answers notifications with an error instead of HTTP 202. A strict client may complain.
Client hangs or loops on SSE It expects the legacy HTTP+SSE transport or a server-sent event stream. OmniForge doesn't provide either.
A tool is missing from the list It's disabled, or the client hasn't refreshed. Tools aren't announced.
Unknown or inactive tool The name is wrong, or the tool is disabled.
First call times out, the second works The first call installed packages. Warm the cache from the dashboard.
Whole server unresponsive for a while Another tool call is still running. See Security and limitations.

More in Troubleshooting and FAQ (repository access required).


← Home · Next: Built-in authoring tools → (repository access required)