openclaw-mcp-router 0.2.6 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -159
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -2
- package/skills/mcp-router/SKILL.md +84 -0
- package/skills/mcp-router/references/workflows.md +184 -0
- package/src/commands/add-server.ts +90 -0
- package/src/commands/disable-server.ts +33 -0
- package/src/commands/enable-server.ts +37 -0
- package/src/commands/list-servers.ts +106 -0
- package/src/commands/remove-server.ts +33 -0
- package/src/config.ts +52 -13
- package/src/constants.ts +19 -0
- package/src/index.ts +147 -34
- package/src/indexer.ts +22 -9
- package/src/mcp-client.ts +2 -2
- package/src/setup/config-writer.ts +184 -0
- package/src/setup/control-command.ts +467 -0
- package/src/setup/setup-command.ts +199 -0
- package/src/test/config.test.ts +70 -2
- package/src/test/tools/mcp-call-tool.test.ts +3 -2
- package/src/test/tools/mcp-search-tool.test.ts +2 -1
- package/src/tools/mcp-call-tool.ts +7 -7
- package/src/tools/mcp-search-tool.ts +5 -5
- package/src/vector-store.ts +18 -0
- package/.claude/settings.local.json +0 -9
- package/CLAUDE.md +0 -54
package/README.md
CHANGED
|
@@ -1,208 +1,129 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OpenClaw MCP Router 🚀
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**OpenClaw MCP Router** is a dynamic tool discovery layer for [OpenClaw](https://openclaw.ai). It uses semantic vector search to eliminate **Context Bloat** by routing only the necessary Model Context Protocol (MCP) tool schemas to your agent on-demand.
|
|
4
4
|
|
|
5
|
-
## The
|
|
5
|
+
## ⚡ The Problem: Context Window Exhaustion
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Modern MCP catalogs are growing. Loading every tool schema upfront is expensive and inefficient:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
* **Token Waste:** 5 MCP servers with 50+ tools can burn **55k–134k tokens** before your agent even says "Hello."
|
|
10
|
+
* **Performance Hit:** Massive system prompts degrade reasoning accuracy (the "lost in the middle" phenomenon).
|
|
11
|
+
* **Cost:** High token usage leads to higher API costs for every turn of the conversation.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## 🛠️ The Solution: Semantic Tool Routing
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- **`mcp_call(tool_name, params_json)`** — look up the owning MCP server, execute the call, return the result
|
|
15
|
+
Instead of a full schema dump, this plugin registers two lightweight "Meta-Tools":
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
1. **`mcp_search(query)`**: Uses **Ollama** and **LanceDB** to perform a semantic search. It returns only the top-N most relevant tool definitions (reducing overhead by ~95%).
|
|
18
|
+
2. **`mcp_call(tool_name, params)`**: Dynamically resolves the owning MCP server and executes the call.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
> **Result:** Your agent "asks" for the tools it needs, keeping the context window clean and the reasoning sharp.
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
openclaw plugins install openclaw-mcp-router
|
|
22
|
-
```
|
|
22
|
+
---
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
## 🚀 Quick Start
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
git clone https://github.com/lunarmoon26/openclaw-mcp-router.git
|
|
28
|
-
openclaw plugins install ./openclaw-mcp-router
|
|
29
|
-
```
|
|
26
|
+
### 1. Prerequisites
|
|
30
27
|
|
|
31
|
-
|
|
28
|
+
Ensure you have **Ollama** running locally with an embedding model:
|
|
32
29
|
|
|
33
|
-
```
|
|
30
|
+
```bash
|
|
34
31
|
ollama pull embeddinggemma
|
|
35
|
-
ollama serve
|
|
36
|
-
```
|
|
37
32
|
|
|
38
|
-
## Configuration
|
|
39
|
-
|
|
40
|
-
Add to `~/.openclaw/openclaw.yml`:
|
|
41
|
-
|
|
42
|
-
```yaml
|
|
43
|
-
tools:
|
|
44
|
-
alsoAllow:
|
|
45
|
-
- mcp_search
|
|
46
|
-
- mcp_call
|
|
47
|
-
|
|
48
|
-
plugins:
|
|
49
|
-
openclaw-mcp-router:
|
|
50
|
-
enabled: true
|
|
51
|
-
config:
|
|
52
|
-
servers:
|
|
53
|
-
- name: filesystem
|
|
54
|
-
transport: stdio
|
|
55
|
-
command: npx
|
|
56
|
-
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
57
|
-
- name: github
|
|
58
|
-
transport: sse
|
|
59
|
-
url: https://api.githubcopilot.com/mcp/
|
|
60
|
-
embedding:
|
|
61
|
-
provider: ollama
|
|
62
|
-
model: embeddinggemma # or qwen3-embedding:0.6b, all-minilm
|
|
63
|
-
url: http://localhost:11434
|
|
64
|
-
search:
|
|
65
|
-
topK: 5 # tools returned per search (1–20)
|
|
66
|
-
minScore: 0.3 # minimum similarity threshold (0–1)
|
|
67
33
|
```
|
|
68
34
|
|
|
69
|
-
###
|
|
35
|
+
### 2. Installation
|
|
70
36
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
If the plugin is running and `openclaw openclaw-mcp-router stats` shows indexed tools, but your agent can't call `mcp_search` — this is why. Add the allowlist to your config:
|
|
74
|
-
|
|
75
|
-
```yaml
|
|
76
|
-
# Global — all agents get access
|
|
77
|
-
tools:
|
|
78
|
-
alsoAllow:
|
|
79
|
-
- mcp_search
|
|
80
|
-
- mcp_call
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Or scope it to specific agents:
|
|
37
|
+
```bash
|
|
38
|
+
openclaw plugins install openclaw-mcp-router
|
|
84
39
|
|
|
85
|
-
```yaml
|
|
86
|
-
# Per-agent or under agents.defaults
|
|
87
|
-
agents:
|
|
88
|
-
defaults:
|
|
89
|
-
tools:
|
|
90
|
-
alsoAllow:
|
|
91
|
-
- mcp_search
|
|
92
|
-
- mcp_call
|
|
93
40
|
```
|
|
94
41
|
|
|
95
|
-
|
|
42
|
+
### 3. Setup & Indexing
|
|
96
43
|
|
|
97
|
-
|
|
44
|
+
Run the interactive wizard to configure your servers and automatically update your `alsoAllow` permissions:
|
|
98
45
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|-------|----------|-------------|
|
|
103
|
-
| `name` | yes | Unique server identifier |
|
|
104
|
-
| `transport` | yes | `stdio`, `sse`, or `http` |
|
|
105
|
-
| `command` | stdio only | Executable to run |
|
|
106
|
-
| `args` | stdio only | Arguments array |
|
|
107
|
-
| `env` | no | Extra env vars merged over process.env; supports `${VAR}` expansion |
|
|
108
|
-
| `url` | sse/http only | Server endpoint URL |
|
|
109
|
-
| `timeout` | no | Per-server connect timeout in ms; overrides `indexer.connectTimeout` |
|
|
110
|
-
|
|
111
|
-
### `embedding`
|
|
112
|
-
|
|
113
|
-
| Field | Default | Description |
|
|
114
|
-
|-------|---------|-------------|
|
|
115
|
-
| `provider` | `ollama` | Only Ollama is supported |
|
|
116
|
-
| `model` | `embeddinggemma` | Embedding model name |
|
|
117
|
-
| `url` | `http://localhost:11434` | Ollama base URL (must be localhost) |
|
|
118
|
-
|
|
119
|
-
### `vectorDb`
|
|
46
|
+
```bash
|
|
47
|
+
openclaw openclaw-mcp-router setup
|
|
48
|
+
openclaw openclaw-mcp-router reindex
|
|
120
49
|
|
|
121
|
-
|
|
122
|
-
|-------|---------|-------------|
|
|
123
|
-
| `path` | `~/.openclaw/openclaw-mcp-router/lancedb` | LanceDB database directory |
|
|
50
|
+
```
|
|
124
51
|
|
|
125
|
-
|
|
52
|
+
---
|
|
126
53
|
|
|
127
|
-
|
|
54
|
+
## ⚙️ Configuration
|
|
128
55
|
|
|
129
|
-
|
|
130
|
-
|-------|---------|-------------|
|
|
131
|
-
| `connectTimeout` | `60000` | Per-server default connect timeout in ms |
|
|
132
|
-
| `maxRetries` | `3` | Retry attempts per server (0 = no retry) |
|
|
133
|
-
| `initialRetryDelay` | `2000` | Initial backoff delay in ms |
|
|
134
|
-
| `maxRetryDelay` | `30000` | Max backoff cap in ms |
|
|
135
|
-
| `maxChunkChars` | `500` | Max characters per chunk for long tool descriptions. `0` = disable chunking |
|
|
136
|
-
| `overlapChars` | `100` | Overlap characters between adjacent chunks |
|
|
56
|
+
The plugin is highly configurable via `~/.openclaw/openclaw.json`.
|
|
137
57
|
|
|
138
|
-
|
|
58
|
+
### Server Management
|
|
139
59
|
|
|
140
|
-
|
|
60
|
+
You can manage servers via the **Interactive TUI**:
|
|
141
61
|
|
|
142
|
-
|
|
62
|
+
```bash
|
|
63
|
+
openclaw openclaw-mcp-router control
|
|
143
64
|
|
|
144
|
-
```yaml
|
|
145
|
-
plugins:
|
|
146
|
-
openclaw-mcp-router:
|
|
147
|
-
config:
|
|
148
|
-
mcpServers:
|
|
149
|
-
my-python-server:
|
|
150
|
-
command: uvx
|
|
151
|
-
args: ["my-mcp-server"]
|
|
152
|
-
timeout: 120000 # this server needs 2 minutes to start
|
|
153
|
-
indexer:
|
|
154
|
-
maxRetries: 5
|
|
155
|
-
initialRetryDelay: 3000
|
|
156
65
|
```
|
|
157
66
|
|
|
158
|
-
###
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
|
67
|
+
### Manual Schema Example
|
|
68
|
+
|
|
69
|
+
For power users, add servers directly to your `plugins.entries`:
|
|
70
|
+
|
|
71
|
+
| Key | Description | Default |
|
|
72
|
+
| --- | --- | --- |
|
|
73
|
+
| `topK` | Number of tools returned per search | `5` |
|
|
74
|
+
| `minScore` | Similarity threshold (0.0 - 1.0) | `0.3` |
|
|
75
|
+
| `maxRetries` | Connection attempts for slow servers | `3` |
|
|
76
|
+
|
|
77
|
+
```json5
|
|
78
|
+
// ~/.openclaw/openclaw.json
|
|
79
|
+
{
|
|
80
|
+
"plugins": {
|
|
81
|
+
"entries": {
|
|
82
|
+
"openclaw-mcp-router": {
|
|
83
|
+
"enabled": true,
|
|
84
|
+
"config": {
|
|
85
|
+
"servers": [{ "name": "filesystem", "transport": "stdio", "command": "npx", "args": ["..."] }],
|
|
86
|
+
"embedding": { "provider": "ollama", "model": "embeddinggemma" }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
164
92
|
|
|
165
|
-
|
|
93
|
+
```
|
|
166
94
|
|
|
167
|
-
|
|
168
|
-
# Re-index all configured MCP servers
|
|
169
|
-
openclaw openclaw-mcp-router reindex
|
|
95
|
+
---
|
|
170
96
|
|
|
171
|
-
|
|
172
|
-
openclaw openclaw-mcp-router stats
|
|
173
|
-
```
|
|
97
|
+
## 🧠 How It Works: Under the Hood
|
|
174
98
|
|
|
175
|
-
|
|
99
|
+
1. **Indexing:** During `reindex`, the router connects to all configured MCP servers, fetches their manifests, and generates vector embeddings for every tool description.
|
|
100
|
+
2. **Storage:** These embeddings are stored in a local **LanceDB** instance for sub-millisecond retrieval.
|
|
101
|
+
3. **Runtime Discovery:** * Agent detects a task (e.g., "Analyze this CSV").
|
|
102
|
+
* Agent calls `mcp_search("read or analyze csv files")`.
|
|
103
|
+
* Router returns the `filesystem` tool schema.
|
|
104
|
+
* Agent executes the tool via `mcp_call`.
|
|
176
105
|
|
|
177
|
-
1. At gateway startup, the plugin connects to each MCP server in parallel (with retry and configurable timeouts), lists its tools, embeds each description via Ollama, and stores them in a local LanceDB index.
|
|
178
|
-
2. When the agent needs to use an MCP capability, it calls `mcp_search("what I want to do")` to find relevant tools.
|
|
179
|
-
3. The agent then calls `mcp_call("tool_name", '{"param": "value"}')` to execute the chosen tool.
|
|
180
106
|
|
|
181
|
-
Disabling the plugin (`openclaw plugins disable openclaw-mcp-router`) cancels any in-progress indexing immediately. Re-enabling starts fresh.
|
|
182
107
|
|
|
183
|
-
|
|
108
|
+
---
|
|
184
109
|
|
|
185
|
-
|
|
186
|
-
|-------|------|-------|
|
|
187
|
-
| `embeddinggemma` | 768 | Good balance, recommended default |
|
|
188
|
-
| `qwen3-embedding:0.6b` | 1024 | Higher quality, larger footprint |
|
|
189
|
-
| `all-minilm` | 384 | Fast and lightweight |
|
|
110
|
+
## 📈 Performance & Benchmarks
|
|
190
111
|
|
|
191
|
-
|
|
112
|
+
Based on the [Anthropic Tool Search](https://www.anthropic.com/engineering/advanced-tool-use) pattern, dynamic routing can improve tool selection accuracy significantly:
|
|
192
113
|
|
|
193
|
-
|
|
114
|
+
* **Standard Loading:** ~49% Accuracy (Large catalogs)
|
|
115
|
+
* **Dynamic Routing:** **~88% Accuracy** (Opus 4.5 benchmarks)
|
|
194
116
|
|
|
195
|
-
|
|
117
|
+
---
|
|
196
118
|
|
|
197
|
-
|
|
119
|
+
## 🤝 Contributing
|
|
198
120
|
|
|
199
|
-
|
|
200
|
-
- **LLM-based reranking.** After the initial vector search returns candidates, a small LLM could rerank them based on the full query context — catching semantic nuances that cosine similarity misses.
|
|
201
|
-
- **Tool use examples.** Indexing not just descriptions but example invocations (input/output pairs) would let the search match against concrete usage patterns, not just what the tool claims to do.
|
|
202
|
-
- **Programmatic tool calling.** Anthropic's guide describes letting the agent compose tool calls inside code blocks rather than pure JSON — reducing context pollution and enabling multi-step tool pipelines.
|
|
121
|
+
We are looking to implement **Hybrid Search (BM25)** and **LLM-based Reranking**. If you're interested in improving LLM orchestration efficiency, we'd love your help!
|
|
203
122
|
|
|
204
|
-
|
|
123
|
+
1. Fork the repo.
|
|
124
|
+
2. Create your feature branch.
|
|
125
|
+
3. Submit a PR.
|
|
205
126
|
|
|
206
|
-
## License
|
|
127
|
+
## 📄 License
|
|
207
128
|
|
|
208
|
-
MIT
|
|
129
|
+
Released under the [MIT License](https://www.google.com/search?q=LICENSE).
|
package/openclaw.plugin.json
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"mcpServersFile": {
|
|
27
27
|
"type": "string",
|
|
28
|
-
"description": "Path to a .mcp.json file. Default: ~/.openclaw/.mcp.json"
|
|
28
|
+
"description": "Path to a .mcp.json file. Default: ~/.openclaw/openclaw-mcp-router/.mcp.json"
|
|
29
29
|
},
|
|
30
30
|
"servers": {
|
|
31
31
|
"type": "array",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-mcp-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Dynamic MCP tool router for OpenClaw — semantic search over large MCP catalogs to eliminate context bloat",
|
|
6
6
|
"type": "module",
|
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
"ollama"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@clack/prompts": "^1.0.1",
|
|
21
22
|
"@lancedb/lancedb": "^0.26.2",
|
|
22
23
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
23
|
-
"@sinclair/typebox": "^0.34.48"
|
|
24
|
+
"@sinclair/typebox": "^0.34.48",
|
|
25
|
+
"json5": "^2.2.3",
|
|
26
|
+
"open": "^11.0.0"
|
|
24
27
|
},
|
|
25
28
|
"peerDependencies": {
|
|
26
29
|
"openclaw": "^2026.2.23"
|
|
@@ -37,6 +40,9 @@
|
|
|
37
40
|
"openclaw": {
|
|
38
41
|
"extensions": [
|
|
39
42
|
"./src/index.ts"
|
|
43
|
+
],
|
|
44
|
+
"skills": [
|
|
45
|
+
"./skills"
|
|
40
46
|
]
|
|
41
47
|
}
|
|
42
48
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mcp-router
|
|
3
|
+
description: Discover and route tasks to configured MCP tools using mcp_search + mcp_call. Use when a task needs external capabilities (APIs, SaaS, databases, web, files, messaging, infra) and the best tool is not already known in-session, especially before falling back to manual shell/curl/web workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MCP Router
|
|
7
|
+
|
|
8
|
+
Use MCP as the first integration layer for external capabilities.
|
|
9
|
+
|
|
10
|
+
## Core Rule
|
|
11
|
+
|
|
12
|
+
Before manual API calls, curl scripts, or ad-hoc web work, run:
|
|
13
|
+
|
|
14
|
+
- `mcp_search("<action-oriented intent>")`
|
|
15
|
+
|
|
16
|
+
If a relevant tool exists, use it with `mcp_call`.
|
|
17
|
+
|
|
18
|
+
## Fast Workflow
|
|
19
|
+
|
|
20
|
+
1. **Search capability**
|
|
21
|
+
- Use an action-oriented query: `"create github pull request"`, `"query postgres"`, `"send slack message"`.
|
|
22
|
+
2. **Select tool**
|
|
23
|
+
- Prefer best intent match + feasible required params.
|
|
24
|
+
3. **Read schema**
|
|
25
|
+
- Identify required fields, types, enums, nested structure.
|
|
26
|
+
4. **Call tool**
|
|
27
|
+
- `mcp_call("exact_tool_name", "{...valid JSON...}")`
|
|
28
|
+
5. **Recover on failure**
|
|
29
|
+
- Fix schema/type mismatch or re-search with rewritten query.
|
|
30
|
+
|
|
31
|
+
## Query Rewrite Ladder (Deterministic)
|
|
32
|
+
|
|
33
|
+
If search quality is poor, retry in this order:
|
|
34
|
+
|
|
35
|
+
1. **Action only**: `"read file"`
|
|
36
|
+
2. **Action + system**: `"read file from s3"`, `"github create issue"`
|
|
37
|
+
3. **Verb swap**: create/open, read/fetch/get, list/enumerate
|
|
38
|
+
4. **Scope adjust**: broaden then narrow
|
|
39
|
+
|
|
40
|
+
Stop once you have a high-confidence tool.
|
|
41
|
+
|
|
42
|
+
## Tool Selection Rules
|
|
43
|
+
|
|
44
|
+
When multiple tools match, rank by:
|
|
45
|
+
|
|
46
|
+
1. Intent fit (description matches requested outcome)
|
|
47
|
+
2. Required-input fit (you can provide required params now)
|
|
48
|
+
3. Simplicity (fewer fragile/optional parameters)
|
|
49
|
+
4. Score/order from search results (tie-breaker)
|
|
50
|
+
|
|
51
|
+
## `mcp_call` Parameter Checklist
|
|
52
|
+
|
|
53
|
+
`params_json` must be a **JSON string**.
|
|
54
|
+
|
|
55
|
+
- Include all required fields.
|
|
56
|
+
- Match exact types (`42` vs `"42"`, `true` vs `"true"`).
|
|
57
|
+
- Respect enums and nested object shapes.
|
|
58
|
+
- Do not add unsupported keys unless schema allows them.
|
|
59
|
+
|
|
60
|
+
Examples:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
✅ mcp_call("filesystem::read_file", '{"path":"/tmp/a.txt"}')
|
|
64
|
+
❌ mcp_call("filesystem::read_file", {"path":"/tmp/a.txt"})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
✅ mcp_call("db::query", '{"sql":"select * from t where id=$1","params":[123]}')
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Error Handling
|
|
72
|
+
|
|
73
|
+
- **Missing required / invalid type**: re-read schema and correct `params_json`.
|
|
74
|
+
- **Unknown tool name**: re-run `mcp_search` and use exact returned name.
|
|
75
|
+
- **Server-side error**: report clearly; retry only with changed inputs.
|
|
76
|
+
- **No relevant tools**: use native fallback tools/workflow.
|
|
77
|
+
|
|
78
|
+
## Practical Boundaries
|
|
79
|
+
|
|
80
|
+
- Reuse known tool names in the same task; avoid unnecessary re-search.
|
|
81
|
+
- Re-search when intent changes materially.
|
|
82
|
+
- Do not loop retries blindly; each retry must change query or params.
|
|
83
|
+
|
|
84
|
+
For full examples, see [references/workflows.md](references/workflows.md).
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Complete Workflow Examples
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Example 0: Check MCP before web search
|
|
6
|
+
|
|
7
|
+
**Goal:** Research a topic — but before using a built-in web search, check if a configured MCP server already handles this.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
mcp_search("search the web")
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Tool card returned:**
|
|
14
|
+
```
|
|
15
|
+
Tool: brave::web_search
|
|
16
|
+
Description: Search the web using the Brave Search API.
|
|
17
|
+
Input Schema:
|
|
18
|
+
- query (string, required): The search query
|
|
19
|
+
- count (number, optional): Number of results (default: 10)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Call:**
|
|
23
|
+
```
|
|
24
|
+
mcp_call("brave::web_search", '{"query": "MCP server authentication patterns", "count": 5}')
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If no web-search tool appears, fall back to whichever search capability is natively available.
|
|
28
|
+
|
|
29
|
+
**The pattern applies everywhere:**
|
|
30
|
+
- Need to fetch a URL? → `mcp_search("fetch a webpage")` before using curl
|
|
31
|
+
- Need to query a DB? → `mcp_search("run a SQL query")` before writing a connection script
|
|
32
|
+
- Need to post to Slack? → `mcp_search("send a Slack message")` before building an API request
|
|
33
|
+
- Need to read a file? → `mcp_search("read a local file")` before opening a shell
|
|
34
|
+
|
|
35
|
+
The configured MCP catalog is the toolbox. Exhaust it before doing things the hard way.
|
|
36
|
+
|
|
37
|
+
These end-to-end examples show the full search → read tool card → call sequence with realistic inputs.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Example 1: Read a local file
|
|
42
|
+
|
|
43
|
+
**Goal:** Read the contents of `/tmp/report.txt`.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
mcp_search("read a local file")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Tool card returned:**
|
|
50
|
+
```
|
|
51
|
+
Tool: filesystem::read_file
|
|
52
|
+
Description: Read the complete contents of a file from the local filesystem.
|
|
53
|
+
Input Schema:
|
|
54
|
+
- path (string, required): Absolute path to the file
|
|
55
|
+
- encoding (string, optional): File encoding (default: "utf-8")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Call:**
|
|
59
|
+
```
|
|
60
|
+
mcp_call("filesystem::read_file", '{"path": "/tmp/report.txt"}')
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Example 2: Create a GitHub pull request
|
|
66
|
+
|
|
67
|
+
**Goal:** Open a PR from branch `feature/add-auth` to `main`.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
mcp_search("create a GitHub pull request")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Tool card returned:**
|
|
74
|
+
```
|
|
75
|
+
Tool: github::create_pull_request
|
|
76
|
+
Description: Creates a new pull request in a GitHub repository.
|
|
77
|
+
Input Schema:
|
|
78
|
+
- owner (string, required): Repository owner (user or org)
|
|
79
|
+
- repo (string, required): Repository name
|
|
80
|
+
- title (string, required): PR title
|
|
81
|
+
- head (string, required): Branch containing the changes
|
|
82
|
+
- base (string, required): Branch to merge into
|
|
83
|
+
- body (string, optional): PR description in Markdown
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Call:**
|
|
87
|
+
```
|
|
88
|
+
mcp_call("github::create_pull_request", '{
|
|
89
|
+
"owner": "acme-corp",
|
|
90
|
+
"repo": "backend",
|
|
91
|
+
"title": "Add JWT authentication",
|
|
92
|
+
"head": "feature/add-auth",
|
|
93
|
+
"base": "main",
|
|
94
|
+
"body": "Implements JWT-based auth as described in issue #42."
|
|
95
|
+
}')
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Example 3: Query a database
|
|
101
|
+
|
|
102
|
+
**Goal:** Count active users in a Postgres database.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
mcp_search("execute a SQL query against a Postgres database")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Tool card returned:**
|
|
109
|
+
```
|
|
110
|
+
Tool: postgres::query
|
|
111
|
+
Description: Execute a read-only SQL query against the configured Postgres database.
|
|
112
|
+
Input Schema:
|
|
113
|
+
- sql (string, required): SQL statement to execute
|
|
114
|
+
- params (array, optional): Positional parameters for parameterized queries
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Call:**
|
|
118
|
+
```
|
|
119
|
+
mcp_call("postgres::query", '{"sql": "SELECT COUNT(*) FROM users WHERE active = true"}')
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Example 4: Multi-step workflow (search once, call multiple times)
|
|
125
|
+
|
|
126
|
+
**Goal:** List files in a directory, then read one of them.
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
mcp_search("list files in a directory")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Tool card returned:**
|
|
133
|
+
```
|
|
134
|
+
Tool: filesystem::list_directory
|
|
135
|
+
Description: List the files and subdirectories in a given directory.
|
|
136
|
+
Input Schema:
|
|
137
|
+
- path (string, required): Absolute path to the directory
|
|
138
|
+
- recursive (boolean, optional): Include subdirectories (default: false)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Call 1 — list:**
|
|
142
|
+
```
|
|
143
|
+
mcp_call("filesystem::list_directory", '{"path": "/tmp/project"}')
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Result:** `["README.md", "config.json", "src/"]`
|
|
147
|
+
|
|
148
|
+
**Call 2 — read (reuse known tool name `filesystem::read_file` from Example 1):**
|
|
149
|
+
```
|
|
150
|
+
mcp_call("filesystem::read_file", '{"path": "/tmp/project/config.json"}')
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
No second `mcp_search` needed — once a tool name is known, reuse it directly.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Example 5: Handling a failed search
|
|
158
|
+
|
|
159
|
+
**Goal:** Get the current weather for a city, but the first query returns nothing.
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
mcp_search("weather")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Result:** No matches.
|
|
166
|
+
|
|
167
|
+
**Rephrase with action verb + domain:**
|
|
168
|
+
```
|
|
169
|
+
mcp_search("get current weather conditions for a city")
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Tool card returned:**
|
|
173
|
+
```
|
|
174
|
+
Tool: weather-api::current
|
|
175
|
+
Description: Fetches current weather conditions for a given city or coordinates.
|
|
176
|
+
Input Schema:
|
|
177
|
+
- city (string, required): City name or "lat,lon" coordinates
|
|
178
|
+
- units (string, optional): "metric" or "imperial" (default: "metric")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Call:**
|
|
182
|
+
```
|
|
183
|
+
mcp_call("weather-api::current", '{"city": "San Francisco", "units": "imperial"}')
|
|
184
|
+
```
|