Skip to content

Commit 637552d

Browse files
committed
feat: add README
1 parent ecafd1c commit 637552d

1 file changed

Lines changed: 180 additions & 0 deletions

File tree

README.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# skillful-mcp
2+
3+
An MCP middleware that aggregates multiple downstream MCP servers into
4+
mcp-native Agent Skills. Each server becomes a Skill that an AI agent can
5+
discover and execute those tools through code mode.
6+
7+
## Why
8+
9+
MCP servers solve connectivity — any tool can expose a standard interface. But
10+
connecting an agent to many servers creates a new problem: [tool
11+
bloat](https://kvg.dev/posts/20260125-skills-and-mcp/).
12+
13+
An agent with access to 5 MCP servers might have 80+ tools. Every tool schema
14+
gets loaded into the context window before the user says a word. The model's
15+
attention is diluted across dozens of options, accuracy drops, and latency
16+
increases. Adding more capabilities makes the agent worse.
17+
18+
skillful-mcp fixes this through **progressive disclosure**. Instead of injecting
19+
all tool definitions upfront, the agent sees just 4 tools (`list_skills`,
20+
`use_skill`, `read_resource`, `execute_code`). It discovers specific tool
21+
schemas on-demand by calling `use_skill`, keeping the context window lean. This
22+
collapses thousands of tokens of tool definitions down to a lightweight index —
23+
and only loads what's needed, when it's needed.
24+
25+
## How it works
26+
27+
```
28+
Agent <--MCP--> skillful-mcp <--MCP--> Database Server
29+
<--MCP--> Filesystem Server
30+
<--MCP--> API Server
31+
```
32+
33+
skillful-mcp reads a standard `mcp.json` config (same format as Claude Code /
34+
Claude Desktop), connects to each downstream server, and exposes four tools:
35+
36+
| Tool | Description |
37+
|------|-------------|
38+
| `list_skills` | Returns the names of all configured downstream servers |
39+
| `use_skill` | Lists the tools and resources available in a specific skill |
40+
| `read_resource` | Reads a resource from a specific skill |
41+
| `execute_code` | Runs Python code in a secure [Monty](https://github.com/pydantic/monty) sandbox |
42+
43+
The typical agent workflow is:
44+
45+
1. Call `list_skills` to see what's available
46+
2. Call `use_skill` to inspect a skill's tools and their input schemas
47+
3. Use `execute_code` to orchestrate tool calls in a single round-trip
48+
49+
## Configuration
50+
51+
Create an `mcp.json` file:
52+
53+
```json
54+
{
55+
"mcpServers": {
56+
"<mcp-name>": { ... }
57+
}
58+
}
59+
```
60+
61+
Each entry in `mcpServers` is a downstream server that becomes a skill. The key
62+
is the skill name. The value depends on the transport type:
63+
64+
### STDIO server
65+
66+
Spawns the server as a child process. Only env vars explicitly listed in `env`
67+
are passed to the child — the parent environment is not inherited.
68+
69+
| Field | Required | Description |
70+
|-------|----------|-------------|
71+
| `command` | yes | Executable to run |
72+
| `args` | no | Arguments array |
73+
| `env` | no | Environment variables for the child process |
74+
75+
```json
76+
{
77+
"mcpServers": {
78+
"database": {
79+
"command": "npx",
80+
"args": ["-y", "@modelcontextprotocol/server-sqlite", "mydb.db"],
81+
"env": {
82+
"PATH": "/usr/local/bin:/usr/bin"
83+
}
84+
}
85+
}
86+
}
87+
```
88+
89+
### HTTP server
90+
91+
Connects via Streamable HTTP.
92+
93+
| Field | Required | Description |
94+
|-------|----------|-------------|
95+
| `type` | yes | Must be `"http"` |
96+
| `url` | yes | Server endpoint URL |
97+
| `headers` | no | HTTP headers (e.g. auth tokens) |
98+
99+
```json
100+
{
101+
"mcpServers": {
102+
"remote-api": {
103+
"type": "http",
104+
"url": "https://api.example.com/mcp",
105+
"headers": {
106+
"Authorization": "Bearer ${API_KEY}"
107+
}
108+
}
109+
}
110+
}
111+
```
112+
113+
### SSE server
114+
115+
Connects via Server-Sent Events.
116+
117+
| Field | Required | Description |
118+
|-------|----------|-------------|
119+
| `type` | yes | Must be `"sse"` |
120+
| `url` | yes | SSE endpoint URL |
121+
| `headers` | no | HTTP headers |
122+
123+
## Running
124+
125+
### Build and run
126+
127+
```sh
128+
go build -o skillful-mcp .
129+
./skillful-mcp --config mcp.json
130+
```
131+
132+
### Run directly
133+
134+
```sh
135+
go run . --config mcp.json
136+
go run . --config mcp.json --transport http --port 8080
137+
### Flags
138+
139+
| Flag | Default | Description |
140+
|------|---------|-------------|
141+
| `--config` | `./mcp.json` | Path to the config file |
142+
| `--transport` | `stdio` | Upstream transport: `stdio` or `http` |
143+
| `--host` | `localhost` | HTTP listen host |
144+
| `--port` | `8080` | HTTP listen port |
145+
146+
### Use with MCP clients
147+
148+
**Gemini CLI** (`~/.gemini/settings.json`):
149+
150+
```json
151+
{
152+
"mcpServers": {
153+
"skillful": {
154+
"command": "./skillful-mcp",
155+
"args": ["--config", "/path/to/mcp.json"]
156+
}
157+
}
158+
}
159+
```
160+
161+
**Claude Code** (`.claude/settings.json`):
162+
163+
```json
164+
{
165+
"mcpServers": {
166+
"skillful": {
167+
"command": "./skillful-mcp",
168+
"args": ["--config", "/path/to/mcp.json"]
169+
}
170+
}
171+
}
172+
```
173+
174+
**Codex CLI** (`~/.codex/config.toml`):
175+
176+
```toml
177+
[mcp_servers.skillful]
178+
command = "./skillful-mcp"
179+
args = ["--config", "/path/to/mcp.json"]
180+
```

0 commit comments

Comments
 (0)