Docs
Connect a client, make a call, read the bill.
Omnial MCP is one HTTP MCP endpoint with a bearer token. No SDK to install, no OAuth flow to complete. If your client speaks MCP over HTTP, it is a config file away.
Get started
Four steps, about five minutes.
Create an account
Sign up with an email address. There is no password: creating the account and signing in both work by a link emailed to you, valid for 15 minutes and usable once. Nothing is created until you open that link.
Mint an API key
In the dashboard, create a key. It is shown once, at creation, and only its prefix is stored in readable form afterwards. There is no way to retrieve it later, so save it then.
Give it the scopes it needs and no more. A key without
runs:executecan search, inspect and read usage docs, and will be refused byomnial_execute. A per-key spend cap bounds what that key can spend in aggregate.Point your MCP client at the endpoint
The endpoint is below, the credential is an
Authorization: Bearerheader, and the config block for your client is in the next section.Ask your agent to find a tool
If the connection is healthy, eight tools appear in your client. Ask it to search the catalog for a capability and it will use them.
Setting this up with an agent instead of doing it by hand? Send it /SKILL.md, a plain-text document written for an agent to read and act on directly, with no JavaScript and no sign-in required to fetch it. The same document, with the config for your specific client and a copy button, is on the install page. (The older /install.md URL serves the identical body and is not going away.)
Endpoint
https://mcp.eden-engine.com/mcpAuthentication
Authorization: Bearer omn_live_REPLACE_WITH_YOUR_KEYA static header, on every request. The MCP specification makes authorization optional and every developer-facing client supports a static header natively, so there is no OAuth flow in this version.
Client configs
The exact file your client expects.
The shapes genuinely differ: one client roots its config at servers rather than mcpServers, another names the endpoint serverUrl rather than url, and getting one key name wrong costs your first ten minutes. Each tab is the whole file, not a fragment.
Paste a key to have it written straight into the snippet below. It stays in this browser tab — it is not sent to us, not stored, and not part of the page's HTML. Leave it blank and the snippet uses a placeholder you can fill in later.
Project-scoped .mcp.json is checked in and shared with the repo; the CLI form below writes it for you.
Goes in .mcp.json (project) or ~/.claude.json (user)
{
"mcpServers": {
"omnial": {
"type": "http",
"url": "https://mcp.eden-engine.com/mcp",
"headers": {
"Authorization": "Bearer omn_live_REPLACE_WITH_YOUR_KEY"
}
}
}
}
claude mcp add --transport http omnial https://mcp.eden-engine.com/mcp --header "Authorization: Bearer omn_live_REPLACE_WITH_YOUR_KEY"- Claude Code needs the explicit "type": "http". Without it the entry is read as a stdio server and the url is ignored.
- Run `claude mcp list` afterwards; a healthy entry reports connected.
Cursor reads a project file first, then the global one; both use the same shape.
Goes in .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)
{
"mcpServers": {
"omnial": {
"url": "https://mcp.eden-engine.com/mcp",
"headers": {
"Authorization": "Bearer omn_live_REPLACE_WITH_YOUR_KEY"
}
}
}
}
- Cursor infers the transport from the presence of url; there is no type field to set.
- After saving, open Settings -> MCP and confirm the server shows a green dot before using it.
Windsurf's Cascade agent. Note the endpoint key name.
Goes in ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"omnial": {
"serverUrl": "https://mcp.eden-engine.com/mcp",
"headers": {
"Authorization": "Bearer omn_live_REPLACE_WITH_YOUR_KEY"
}
}
}
}
- Windsurf names the endpoint "serverUrl", not "url": a "url" key is silently ignored and the server never connects.
- Press the refresh icon in Cascade's MCP panel after editing; Windsurf does not hot-reload this file.
OpenCode nests servers under mcp and distinguishes remote from local explicitly.
Goes in opencode.json (project) or ~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"omnial": {
"type": "remote",
"url": "https://mcp.eden-engine.com/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer omn_live_REPLACE_WITH_YOUR_KEY"
}
}
}
}
- The block is "mcp", not "mcpServers", and every entry needs "type": "remote" plus "enabled": true.
- Keeping the $schema line gives you completion and validation in the editor.
Not a config file: the Agents SDK takes MCP servers as objects you construct and hand to the Agent. Building your own agent in Python, not using Codex or ChatGPT? This is that.
Goes in in your agent code
import asyncio
import os
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
# export OMNIAL_API_KEY=omn_live_REPLACE_WITH_YOUR_KEY
OMNIAL_API_KEY = os.environ["OMNIAL_API_KEY"]
async def main() -> None:
async with MCPServerStreamableHttp(
name="omnial",
params={
"url": "https://mcp.eden-engine.com/mcp",
"headers": {"Authorization": f"Bearer {OMNIAL_API_KEY}"},
},
cache_tools_list=True,
) as omnial:
agent = Agent(
name="Assistant",
instructions=(
"Use omnial_search to find a tool, omnial_learn to read its usage "
"instructions before calling it, and omnial_execute with dry_run=True "
"to check cost before spending."
),
mcp_servers=[omnial],
)
result = await Runner.run(agent, "Find a tool that can search the web and tell me what it costs.")
print(result.final_output)
asyncio.run(main())
- Use the Streamable HTTP server class; the SSE class is for the older transport and will not negotiate correctly here.
- Read the key from the environment rather than pasting it into source; the snippet below does.
- cache_tools_list avoids re-listing the meta-tools on every turn.
- This is a different product from OpenAI Codex (the CLI/IDE coding agent). Codex has its own entry above/below with its own TOML config, no code required.
OpenAI Codex: the CLI, the ChatGPT desktop app and the IDE extension all share this one TOML file.
Goes in ~/.codex/config.toml (or a project's own .codex/config.toml, trusted projects only)
# export OMNIAL_API_KEY=omn_live_REPLACE_WITH_YOUR_KEY
[mcp_servers.omnial]
url = "https://mcp.eden-engine.com/mcp"
bearer_token_env_var = "OMNIAL_API_KEY"
- Verified 2026-08-24 against developers.openai.com/codex/mcp/ (live redirects to learn.chatgpt.com/docs/extend/mcp): Codex is a different product from the OpenAI Agents SDK above; a real client with its own config format, not a rename of it.
- bearer_token_env_var names an environment variable holding the token; Codex reads the variable at startup rather than storing the key in the file itself.
- The docs only show codex mcp add for stdio servers; for a remote HTTP server like this one, add the [mcp_servers.*] table below by hand.
Claude Desktop's native remote-server path (Settings -> Connectors -> Add custom connector) has no usable static-key option today (its one static-bearer field is beta and gated), and Omnial issues a static API key instead, so this runs the mcp-remote stdio bridge through npx rather than a direct url entry.
Goes in macOS: ~/Library/Application Support/Claude/claude_desktop_config.json; Windows: %APPDATA%\Claude\claude_desktop_config.json; Linux (unconfirmed, see note below): ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"omnial": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.eden-engine.com/mcp",
"--header",
"Authorization:${OMNIAL_API_KEY}"
],
"env": {
"OMNIAL_API_KEY": "Bearer omn_live_REPLACE_WITH_YOUR_KEY"
}
}
}
}
- Verified 2026-08-21 against modelcontextprotocol.io's official docs ("Connect to local MCP servers" and "Connect to remote MCP Servers", spec version 2026-07-28), Anthropic's help center article on custom connectors, and claude.com/docs/connectors/custom/remote-mcp: claude_desktop_config.json only documents stdio servers ("command"/"args"), and the in-app "Add custom connector" flow authenticates over OAuth (with an optional OAuth Client ID/Secret field). Claude's own docs do describe a "Request headers" option there that takes a static "Authorization: Bearer <token>", but it is marked beta and gated ("contact Anthropic for early access"), so it is not something a normal user can turn on today; for everyone without that access, neither in-app path takes a plain API key directly.
- mcp-remote (github.com/geelen/mcp-remote) is the widely-used community bridge for exactly this gap, not an Anthropic-endorsed one. No official Anthropic doc names it; it just happens to be what filled the space Claude Desktop's missing native remote-HTTP entry left open. Its own README describes it as "a working proof-of-concept" that "should be considered experimental," a stop-gap until clients support remote authorized servers natively; that caveat is the tool's own, not ours, and it still applies. It needs Node.js installed, same as any other npx-based server.
- Claude Desktop on Windows (and Cursor) mangle spaces inside "args" when they invoke npx, so the header is passed as "Authorization:${OMNIAL_API_KEY}" (no space after the colon) with the actual "Bearer <key>" value moved into the env block instead of inlined in args: mcp-remote's own documented workaround for the bug.
- Restart Claude Desktop completely after editing this file; it does not hot-reload. A hammer/tools icon appears near the message box once mcp-remote connects; check ~/Library/Logs/Claude/mcp*.log (macOS) or %APPDATA%\Claude\logs\mcp*.log (Windows) if it does not.
- Claude Desktop also ships an official Linux beta now (Ubuntu 22.04+ / Debian 12+, x86_64 and arm64, installed from Anthropic's own apt repo, code.claude.com/docs/en/desktop-linux, checked 2026-08-21). That page documents install, update and uninstall only; it never states a config-file path. ~/.config/Claude/claude_desktop_config.json above is the strong convention (it is where Electron apps put per-user config on Linux and where community write-ups of this app put it), but it is NOT confirmed against an official Anthropic source, unlike the macOS and Windows paths above; treat it as the best current guess, not a certainty.
The MCP tools are named omnial_* because this product is Omnial MCP (in full, Eden Omnial MCP), one product under the Eden Engine umbrella. The names are part of the wire protocol your client speaks, so they are shown here exactly as your agent will call them.
The tool surface
Eight tools, and what each one promises.
The catalog is not exposed as one MCP tool per entry: listing it would spend tens of thousands of tokens of your agent's context before it did any work.
| Tool | Purpose |
|---|---|
| omnial_search | Keyword query to ranked tools, each carrying the reason it matched. It always answers with what it found. An empty list means the catalog genuinely carries none of those terms, not that the engine declined to rank.Tuned to answer rather than refuse: returning a tool you can decline beats returning nothing, so search always ranks what it found. Against its 44-query set the right tool is first 43 times. Relevance is shown relative to the best match in that answer, not as a probability, and every hit says which keyword or field it matched on, so a weak match is visible as a weak match rather than dressed up as a confident one. |
| omnial_inspect | The full contract: input schema, output schema, pricing, a cost estimate for your actual input, latency and success rate.Latency and success rate are measured from this deployment's own runs, so they read as unknown until it has made some. |
| omnial_learn | Hand-authored instructions for a tool you have already chosen: what its parameters actually do, worked examples, failure modes, cost shape. |
| omnial_execute | Runs the tool. Supports dry_run to price a call without spending anything. The quote is held while the call runs and the charge follows what the call actually cost.A quote is not a cap: the quote is held while the call runs, you are charged what the call actually cost, and a call that costs more than its quote is charged up to 2x the quote. Above that, Omnial MCP absorbs the difference. |
| omnial_run_status | Polls a run handle for anything that could not return inline. |
| omnial_balance | Available and held balance, so an agent can reason about its own budget. |
| omnial_cancel | Stops a run you no longer want: the provider is asked to stop the job, then the run settles cancelled and whatever is left of the hold is released. An agent that passed the wrong input to a long job can stop paying for it instead of waiting for the provider to finish. Stopping a job that is already running can still cost you what the provider had incurred by then, where it reports one.It refuses rather than pretends. Stopping a job is a capability a provider has to declare, and no tool in this catalog declares one today, so cancel answers with a refusal naming the tool. Releasing your hold while the provider keeps working and keeps billing would be a loss with nobody to attribute it to. A synchronous run is refused too, with the same honesty: abort your own request instead, which aborts the provider call with it. |
| omnial_runs | Lists this workspace's runs, newest first; by default only the ones still in flight, which are the ones still holding money. Run handles are opaque and stateless, so an agent whose process restarted has no other way to find the runs it left behind. Returns handles omnial_run_status and omnial_cancel accept. |
No SDK to install, no OAuth flow to complete.
Your first call
Search, inspect, learn, price, run.
Written as your agent will call them. Every tool page in the catalog carries the same block with that tool's slug filled in.
// 1. find something that can do the job
omnial_search({ query: "scrape a product page" })
// 2. what does it take, what does it return, what will it cost
omnial_inspect({
tool: "crawlco/scrape",
input: { url: "https://example.com/product/1" }
})
// 3. how to use it well, from its author
omnial_learn({ tool: "crawlco/scrape" })
// 4. price this exact call. spends nothing, calls nobody
omnial_execute({
tool: "crawlco/scrape",
input: { url: "https://example.com/product/1" },
dry_run: true
})
// 5. run it
omnial_execute({
tool: "crawlco/scrape",
input: { url: "https://example.com/product/1" }
})
// and, at any time
omnial_balance({})Worth knowing
- Slugs
- Always
provider/tool.omnial_searchreturns them; a slug that does not exist is refused with a pointer back to search rather than guessed at. - Categories
- Data, not schema. Every search response carries the valid list, and an unknown value is refused with that list attached.
- Estimates
omnial_inspectanddry_runboth validate your input against the tool's own schema before pricing it.
Long-running runs
Anything slow returns a handle.
A video render does not finish inside a request. Fast tools answer inline; everything else hands back an opaque run handle.
omnial_execute({ tool: "genco/videogen-1-pro-t2v", input: { /* ... */ } })
// -> { run: "<opaque handle>", status: "RUNNING" }
omnial_run_status({ run }) // poll it
omnial_runs({}) // list this workspace's in-flight runs
omnial_cancel({ run }) // ask the provider to stop itWhy omnial_runs exists
Handles are opaque and stateless: nothing on the server maps your agent to its runs between calls. If your process restarts, this is the only way to find the runs it left behind, which are also the runs still holding your money.
Errors and refusals
A failure is a result your agent can read, not an exception.
- A run that failed
- Comes back as an error result, from
omnial_executeand fromomnial_run_statusalike: a failed paid call is never indistinguishable from a successful one.QUEUEDandRUNNINGare not errors: the hold is taken and the job is live. - Not enough balance
- A
dry_runanswers withsufficient_balance: falseand the shortfall rather than failing opaquely. A real call in the same state is refused before any provider is contacted, and nothing is charged. - An unknown category or slug
- Refused, naming what is valid. Silently matching zero rows would read as “this catalog cannot do that”.
- Cancel on a tool that cannot be stopped
- Refused, naming the tool. Stopping a job is a capability a provider has to declare; no tool in this catalog declares one today, and releasing your hold while the provider keeps working would be worse than saying no.
- A tool this deployment cannot execute
- Withheld from search results and counted separately, with the cause named. A missing provider credential is a fact about the deployment, not about the catalog.
Limits
The numbers worth knowing before you hit them.
- Inline output: 32 KiB
- Larger provider output is replaced by an envelope saying it is not the result, how large the real one is, and where to fetch the whole thing with the same API key. Nothing is discarded. Truncation is a delivery decision, never a storage one.
- Provider response: 16 MiB
- A response larger than this is refused loudly as a typed failure naming the limit and the bytes read, and the connection is cut rather than drained.
- Rate limits
omnial_inspectreturns the per-key and per-workspace request rates your calls are held to. The public catalog and its search are rate-limited per address.- Spend
- Bounded by your balance, by any per-key spend cap, and, on any single run, by the enforced ceiling of 2x its quote. The quote itself is what gets held while the call runs; it is not a cap on the charge.
Both limits are enforced, not just documented: an inline result over 32 KiB is replaced with a fetch link rather than silently cut, and a provider response over 16 MiB is refused outright and the connection closed rather than drained to fit.
One more thing worth knowing before you wire this in: calling these tools to power your own product, under your own brand, is permitted; making our catalog itself — the listings, the hand-authored usage docs your agent reads through omnial_learn, or this directory's agent-tool surface — what you offer your users, in whole or in substantial part, whether copied or proxied live, is not. See /legal/terms#acceptable-use for the policy, and /why#whitelabel for worked examples of it. Integration permission is separate from data-use restrictions: a provider's data still carries its own, listed in the same /legal/terms#acceptable-use section.
Status
What is real today.
Early access: what is real and what is not
Omnial MCP's catalog is no longer empty: our first provider integration, a genuine vendor account, has been promoted all the way to live — it is browsable at /tools and callable today, the first real, working integration on this platform. Every other provider defined so far remains below live. Most are synthetic: an invented vendor with a full input and output contract, a modelled pricing structure and a hand-authored usage doc, reachable only at a reserved .example host that resolves to nothing. One entry, echoco, is not synthetic and is not a vendor either: it is an internal fixture that calls a real, free public test endpoint solely to prove the pipeline end to end, and nothing about it is for sale. Nothing about those remaining entries is a working paid integration, and no figure on this site attached to them is revenue. What that live integration proves, and what the platform around it was already built and tested for, is real: the append-only ledger, hold-before-the-call and settle-after, the pricing engine, the eight MCP tools, and now real, callable tools behind them.
A synthetic provider is a complete catalog entry (input and output schemas, a modelled pricing structure, rate and usage limits, a hand-authored usage doc, worked examples validated against its own schema) pointed at a reserved .example host. The catalog linter requires that disclosure and refuses a fabricated provider whose egress hosts are not reserved, so nothing in this catalog can quietly reach a real vendor.
What that means for you right now
Everything on this page works: connect a client, then have your agent search, inspect, read a usage doc, and price a call. Real, callable tools are live in the catalog today; most of it is not stocked yet. If you want to be told as more of it fills in, an account is the way to be reachable.
