#MCP not injecting tools?

1 messages · Page 1 of 1 (latest)

cinder timber
#

The mcp.servers Section in the config as I understand it should be injecting the third-party MCP tools as first-class tools within the session. Is that not accurate? If it is, for some reason it is not injecting them in my sessions. If that is not accurate, how do agents access those MCP servers?

To be clear i am not talking about serving as an MCP server. I am talking about agent accessing remote MCP servers in sessions.

languid pantherBOT
hot coralBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

raven slateBOT
#

Short version: partly yes.

mcp.servers is an OpenClaw-managed registry of MCP server definitions. In native embedded Pi sessions, those servers can become usable tools in the session. But a few gotchas:

  • they are exposed with prefixed safe names, like my-server__tool_name, not the raw MCP tool name
  • they only show when the session tool policy allows bundle-mcp
    • coding and messaging profiles include it
    • minimal does not
    • tools.deny: ["bundle-mcp"] disables them
  • changes are picked up on a new session (/new or /reset)

Also, it is not universal across every runtime:

  • embedded/default OpenClaw session: uses mcp.servers
  • ACP harness sessions (Codex/Claude/Gemini via acpx): use plugins.entries.acpx.config.mcpServers
  • openclaw acp bridge: per-session mcpServers are unsupported
#

For remote MCP servers, OpenClaw expects url over HTTP(S), with sse as default transport, or transport: "streamable-http".

If they are not appearing, I would check these first:

  1. pnpm openclaw --version
  2. pnpm openclaw mcp list
  3. pnpm openclaw mcp show <name>
  4. start a new session
  5. make sure you are not on tools.profile: "minimal" and not denying bundle-mcp
  6. look for names like serverName__toolName
  7. pnpm openclaw status --all and pnpm openclaw logs --follow for MCP connect/start errors

Docs:

#

If you paste:

  • pnpm openclaw --version
  • whether this is a normal OpenClaw session or an ACP/Codex/Claude session
  • your MCP config block (with secrets redacted)

…I can tell you exactly which path applies.

cinder timber
#

The tools are definitely not getting injected. It says it's looking for them an running /tools doesn't show them

raven slateBOT
#

Yep, for a normal OpenClaw session, mcp.servers is the right mechanism.

Your config snippet shows the likely problem though:

"mymcp": {
  "headers": {
    "Authorization": "Bearer blahblah"
  },
  "baseUrl": "https://mcp.mysite.com/api/mcp"
}

Two things jump out:

  1. baseUrl is wrong
    OpenClaw expects url, not baseUrl.
#
  1. transport may be wrong
    For remote MCP servers, OpenClaw defaults to SSE if you omit transport.
    A lot of /api/mcp endpoints are actually streamable HTTP, so you may need:
mcp: {
  servers: {
    mymcp: {
      url: "https://mcp.mysite.com/api/mcp",
      transport: "streamable-http",
      headers: {
        Authorization: "Bearer blahblah",
      },
    },
  },
}
#

Then:

  • start a new session (/new or /reset)
  • look for tools named like mymcp__some_tool
  • make sure you are not using tools.profile: "minimal" or tools.deny: ["bundle-mcp"]

So the short answer is:

  • Yes, mcp.servers should make remote MCP tools available in normal sessions
  • No, they are not injected from that exact snippet because baseUrl is not a supported field, and transport may need to be explicit

Docs:

If you want, paste the full mcp.servers block and I’ll sanity-check it.

cinder timber
#

This agent has the profile full and we're not denying bundle-mcp anywhere. What command do I run to see what tools are in there?

raven slateBOT
#

/tools verbose is the right in-session command.

If the MCP server is loaded, it should show up there under Connected tools with names like:

mymcp__some_tool

If it does not show up in /tools, then it is not in the runtime tool inventory for that session.

In your case, I think the config is still the blocker. This shape will not load:

"mymcp": {
  "headers": {
    "Authorization": "Bearer blahblah"
#
  },
  "baseUrl": "https://mcp.mysite.com/api/mcp"
}

OpenClaw expects url, not baseUrl.

Try:

mcp: {
  servers: {
    mymcp: {
      url: "https://mcp.mysite.com/api/mcp",
      transport: "streamable-http", // if your server is not SSE
#
      headers: {
        Authorization: "Bearer blahblah",
      },
    },
  },
}

Then:

  1. openclaw mcp show mymcp
  2. start a new session with /new
  3. run /tools verbose

For gateway-side debugging, this is the best check:

#
openclaw logs --follow

With the bad config, I’d expect a warning very close to:

bundle-mcp: skipped server "mymcp" because its command is missing and its url is missing.

So short answer:

  • use /tools verbose to see the session’s actual tools
  • use openclaw logs --follow to see why MCP loading was skipped
  • fix baseUrlurl

Docs:

cinder timber
#

AHA! It's: 01:02:26+00:00 warn bundle-mcp {"subsystem":"bundle-mcp"} skipped server "mymcp" because its command is missing and its url is missing.

I changed it to be url and streamable http transport though but still getting that? it's mcp.servers.mymcp

raven slateBOT
#

Nice, that log line is the smoking gun.

If it still says its url is missing, then the running gateway is not seeing the updated shape. Usually that means one of these:

  1. you edited the wrong config file
  2. the gateway is still running old config
  3. the saved mymcp entry still isn’t actually url

Run these:

pnpm openclaw mcp show mymcp --json
pnpm openclaw gateway status

mcp show should look like this:

#
{
  "url": "https://mcp.mysite.com/api/mcp",
  "transport": "streamable-http",
  "headers": {
    "Authorization": "Bearer blahblah"
  }
}

If mcp show still shows baseUrl, then the config wasn’t updated where OpenClaw is reading it.

If mcp show looks correct but logs still say url is missing, restart the gateway, then start a fresh session:

pnpm openclaw gateway restart
#

Then in chat:

/new
/tools verbose

If it still fails after that, paste the output of:

pnpm openclaw mcp show mymcp --json
pnpm openclaw gateway status

That should tell us pretty quickly whether this is a stale gateway vs wrong config path issue.

Docs:

cinder timber
#

mcp show shows the url key.

~ git:(main) ✗ openclaw mcp show --profile personal-agents --json
{
"mymcp": {
"headers": {
"Authorization": "Bearer dsfasf"
},
"transport": "streamable-http",
"url": "https://mcp.mymcp.com/api/mcp"
}
}

raven slateBOT
#

That strongly smells like a profile/service mismatch.

You showed:

openclaw mcp show --profile personal-agents --json

So the CLI is reading the personal-agents profile, but the running gateway may still be using default or another profile. That would explain why logs still say url is missing.

Run these with the same profile:

openclaw --profile personal-agents gateway status
openclaw --profile personal-agents gateway restart
#

In gateway status, look at:

  • Config (cli)
  • Config (service)

If those differ, that’s the problem. The FAQ calls this out directly.

Fix:

openclaw --profile personal-agents gateway install --force
openclaw --profile personal-agents gateway restart

Then start a fresh chat session and run:

cinder timber
#

Nope they match Config (cli): ~/.openclaw-personal-agents/openclaw.json
Config (service): ~/.openclaw-personal-agents/openclaw.json

raven slateBOT
#

Got it, that rules out the easy profile mismatch.

At this point I’d treat that url is missing warning as either:

  1. a stale pre-fix log line, or
  2. a 2026.4.22 bug in how the runtime is reloading/reading mcp.servers

Important nuance: openclaw mcp show only shows the saved config. It does not connect to the server. The actual proof is the fresh bundle-mcp log line when the session/tool catalog is built.

I’d do this exact sequence:

openclaw --profile personal-agents gateway restart
openclaw --profile personal-agents logs --follow

Then in chat:

#
/new
/tools verbose

What I’d expect next:

  • if the config is now being read correctly, the log should change from
    • skipped server "mymcp" because ... url is missing
      to either
    • a successful load and tools appear, or
    • failed to start server "mymcp" (...) ...
      which means config is fine and the remaining problem is transport/auth/reachability/server behavior

Also, use the named form once just to remove ambiguity:

#
openclaw --profile personal-agents mcp show mymcp --json

If after a gateway restart you still get a fresh url is missing line, with:

  • matching Config (cli) / Config (service)
  • mcp show mymcp --json showing url

then honestly that smells like a real bug on 2026.4.22, and I’d file it here:
https://github.com/openclaw/openclaw/issues

If you paste the fresh post-restart bundle-mcp line, I can tell you which branch you’re in right away.

cinder timber
#

Okay, now I'm quite confused because the tools command is not showing it, but if I ask it if it has any MCP tools, it is showing those tools in there and it is able to call them now, but the tools command is not listing them as tools, but it appears to be working fine.

raven slateBOT
#

Ah, okay, that makes sense now.

If the agent can see and call the MCP tools, then the MCP side is working. What’s broken is /tools visibility, not tool injection.

This looks like a current limitation/bug: the actual run path appends bundle MCP tools at runtime, but /tools is using a different inventory path and can miss those connected MCP tools. So:

  • runtime behavior = source of truth
  • /tools output = currently incomplete for these MCP tools

So your original understanding was basically right, and the confusing part is just that /tools is lying a bit here.

I’d treat this as a bug and file it here:
https://github.com/openclaw/openclaw/issues

Useful repro summary:

  • normal OpenClaw session
#
  • mcp.servers.mymcp configured with url + transport: "streamable-http"
  • agent can successfully call the MCP tools
  • /tools does not list them

For now, I’d trust:

  • successful MCP calls
  • bundle-mcp logs
  • the model/tool behavior in-session

…not /tools, for this case.

Glad we found it, this was a sneaky one.

cinder timber
#

Can you please make me an issue please

raven slateBOT
#

I can’t open GitHub issues for you directly, but I can absolutely draft it. Paste this into https://github.com/openclaw/openclaw/issues/new:

Title
/tools does not list mcp.servers tools even though the agent can see and call them

Body

## Summary

In a normal OpenClaw session, tools from `mcp.servers` are usable by the agent, but `/tools` and `/tools verbose` do not list them.

This makes it look like MCP tools are not injected, even though they actually are available at runtime.

## Version

- OpenClaw: `2026.4.22`
#

## Setup

- Normal OpenClaw session
- Profile: `personal-agents`
- `Config (cli)` and `Config (service)` both point to:
  - `~/.openclaw-personal-agents/openclaw.json`

## MCP config

```json5
{
  mcp: {
    servers: {
      mymcp: {
        url: "https://mcp.mymcp.com/api/mcp",
#

transport: "streamable-http",
headers: {
Authorization: "Bearer <redacted>"
}
}
}
}
}


## What I expected

- `/tools` and `/tools verbose` should list the MCP tools exposed by `mcp.servers`

## What actually happens
#
- `/tools` does **not** list the MCP tools
- but if I ask the agent about MCP tools, it can see them
- and the agent is able to successfully call those MCP tools

So runtime tool access works, but the `/tools` inventory appears incomplete/inaccurate.

## Notes

Earlier I had a bad config shape (`baseUrl` instead of `url`), which produced:

```text
bundle-mcp: skipped server "mymcp" because its command is missing and its url is missing

After fixing config to use url and transport: "streamable-http", the agent can call the MCP tools successfully, but /tools still does not show them.

#

## Repro steps

1. Configure `mcp.servers` with a working remote MCP server
2. Restart gateway
3. Start a new session
4. Run `/tools verbose`
5. Observe MCP tools are missing from `/tools`
6. Ask the agent to use/check MCP tools
7. Observe the agent can see and call them successfully

## Possible area

This looks like a mismatch between:
- the actual runtime tool path used by the agent
#
- and the inventory path used by `/tools`

Small side note, rotate that bearer token if the one pasted in thread was real.

cinder timber
#

yea it has been thanks