pi-lemonade-link 1.0.2 → 2.0.0
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 +68 -21
- package/docs/README.md +23 -0
- package/docs/anthropic.md +183 -6
- package/docs/internal.md +1080 -0
- package/docs/lemonade.md +2453 -1665
- package/docs/llamacpp.md +385 -252
- package/docs/mcp.md +232 -128
- package/docs/ollama.md +967 -15
- package/docs/openai.md +1734 -634
- package/docs/router.md +201 -0
- package/index.ts +2038 -306
- package/lemonade.example.json +24 -2
- package/package.json +3 -3
package/docs/mcp.md
CHANGED
|
@@ -2,198 +2,302 @@
|
|
|
2
2
|
|
|
3
3
|
Lemonade exposes its inference capabilities as a Model Context Protocol (MCP) server, so any MCP-compatible client (GitHub Copilot, Claude Desktop, MCP Inspector, Cursor, the `mcp` Python client, etc.) can call your locally running models as tools.
|
|
4
4
|
|
|
5
|
-
The gateway implements the **MCP "Streamable HTTP" transport** (spec version `2025-06-18`) with the `tools` capability only. All traffic flows through a single endpoint:
|
|
5
|
+
The gateway implements the **MCP "Streamable HTTP" transport** (spec version `2025-06-18`) with the `tools` capability only, so `resources/*` and `prompts/*` are not implemented. All traffic flows through a single endpoint:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
| `
|
|
7
|
+
<!-- BEGIN GENERATED: mcp.summary -->
|
|
8
|
+
| Method | Endpoint | Status | Description |
|
|
9
|
+
|--------|----------|--------|-------------|
|
|
10
|
+
| `POST` | [`/mcp`](#post-mcp) | Supported | Call MCP methods over JSON-RPC 2.0 |
|
|
11
|
+
| `GET` | [`/mcp`](#get-mcp) | Not supported | Open a server-initiated event stream |
|
|
12
|
+
<!-- END GENERATED: mcp.summary -->
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
<!-- BEGIN GENERATED: mcp.rpc -->
|
|
15
|
+
## `POST /mcp`
|
|
16
|
+
<sub></sub>
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
Serves the MCP methods listed under [Supported Methods](#supported-methods) over JSON-RPC 2.0.
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
Requires `LEMONADE_API_KEY` when it is set.
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
### Parameters
|
|
23
|
+
|
|
24
|
+
| Parameter | Required | Description | Status |
|
|
25
|
+
|-----------|----------|-------------|--------|
|
|
26
|
+
| `jsonrpc` | Yes | JSON-RPC version: `"2.0"`. | <sub></sub> |
|
|
27
|
+
| `id` | No | Request id, echoed in the reply. Omit it to send a notification, which gets no reply. | <sub></sub> |
|
|
28
|
+
| `method` | Yes | One of the [supported methods](#supported-methods), e.g. `initialize`, `tools/list` or `tools/call`. | <sub></sub> |
|
|
29
|
+
| `params` | No | Method parameters; `tools/call` takes `name` and `arguments`. | <sub></sub> |
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
The body is one JSON-RPC message or a batch array of them. A JSON-RPC error is answered with `200` like any other JSON-RPC response; see [Error Model](#error-model). A request whose messages are all notifications answers `202` with no body.
|
|
32
|
+
|
|
33
|
+
### Supported Methods
|
|
26
34
|
|
|
27
35
|
| Method | Purpose |
|
|
28
36
|
|--------|---------|
|
|
29
|
-
| `initialize` |
|
|
37
|
+
| `initialize` | Return the server's protocol version, identity and capabilities. |
|
|
30
38
|
| `notifications/initialized` | Client acknowledgement; silently accepted. |
|
|
39
|
+
| `notifications/cancelled` | Client cancellation; silently accepted. |
|
|
31
40
|
| `tools/list` | Return the catalogue of callable tools (with JSON Schemas). |
|
|
32
41
|
| `tools/call` | Invoke one of the tools below. |
|
|
33
42
|
| `ping` | Liveness probe; returns `{}`. |
|
|
34
43
|
|
|
35
|
-
|
|
44
|
+
### Error Model
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
| Code | Meaning |
|
|
47
|
+
|------|---------|
|
|
48
|
+
| `-32700` | Body was not valid JSON. |
|
|
49
|
+
| `-32600` | Request was not a JSON-RPC object (or batch was empty / missing `method`). |
|
|
50
|
+
| `-32601` | Unknown JSON-RPC method (e.g. `resources/list`). |
|
|
51
|
+
| `-32602` | Invalid `params` for a known method. |
|
|
52
|
+
| `-32603` | Internal server error (an exception escaped a handler). |
|
|
38
53
|
|
|
39
|
-
|
|
54
|
+
Tool-level failures (bad arguments, model load errors, backend exceptions) are returned as **successful** JSON-RPC results with `"isError": true` and a text content block describing the failure, so MCP-aware models can self-correct.
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
### Limitations
|
|
57
|
+
|
|
58
|
+
- No session resumption (`Mcp-Session-Id` header is not issued).
|
|
59
|
+
- Tools return their whole result: `lemonade_chat` ignores `stream`. Use [`POST /v1/chat/completions`](./openai.md#post-v1chatcompletions) for streamed tokens.
|
|
60
|
+
- Embeddings and text-to-speech have no MCP tool; use [`/v1/embeddings`](./openai.md#post-v1embeddings) and [`/v1/audio/speech`](./openai.md#post-v1audiospeech).
|
|
61
|
+
|
|
62
|
+
### Examples
|
|
63
|
+
|
|
64
|
+
#### Request
|
|
65
|
+
|
|
66
|
+
=== "PowerShell"
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
Invoke-WebRequest `
|
|
70
|
+
-Uri "http://localhost:13305/mcp" `
|
|
71
|
+
-Method POST `
|
|
72
|
+
-Headers @{ "Content-Type" = "application/json" } `
|
|
73
|
+
-Body '{
|
|
74
|
+
"jsonrpc": "2.0",
|
|
75
|
+
"id": 1,
|
|
76
|
+
"method": "initialize",
|
|
77
|
+
"params": {"protocolVersion": "2025-06-18", "capabilities": {}}
|
|
78
|
+
}'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
=== "Bash"
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
curl http://localhost:13305/mcp \
|
|
85
|
+
-H "Content-Type: application/json" \
|
|
86
|
+
-d '{
|
|
87
|
+
"jsonrpc": "2.0",
|
|
88
|
+
"id": 1,
|
|
89
|
+
"method": "initialize",
|
|
90
|
+
"params": {"protocolVersion": "2025-06-18", "capabilities": {}}
|
|
91
|
+
}'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Response:** `200 OK`
|
|
42
95
|
|
|
43
96
|
```json
|
|
44
97
|
{
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
"
|
|
98
|
+
"jsonrpc": "2.0",
|
|
99
|
+
"id": 1,
|
|
100
|
+
"result": {
|
|
101
|
+
"capabilities": {"tools": {}},
|
|
102
|
+
"protocolVersion": "2025-06-18",
|
|
103
|
+
"serverInfo": {"name": "lemonade-mcp", "version": "2026.43.0~1686.1553ede6"}
|
|
49
104
|
}
|
|
50
105
|
}
|
|
51
106
|
```
|
|
52
107
|
|
|
53
|
-
|
|
108
|
+
#### Notification
|
|
54
109
|
|
|
55
|
-
|
|
110
|
+
=== "PowerShell"
|
|
56
111
|
|
|
57
|
-
|
|
112
|
+
```powershell
|
|
113
|
+
Invoke-WebRequest `
|
|
114
|
+
-Uri "http://localhost:13305/mcp" `
|
|
115
|
+
-Method POST `
|
|
116
|
+
-Headers @{ "Content-Type" = "application/json" } `
|
|
117
|
+
-Body '{"jsonrpc": "2.0", "method": "notifications/initialized"}'
|
|
118
|
+
```
|
|
58
119
|
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
"name": "lemonade_chat",
|
|
62
|
-
"arguments": {
|
|
63
|
-
"model": "Qwen3-1.7B-GGUF",
|
|
64
|
-
"messages": [
|
|
65
|
-
{"role": "system", "content": "You are concise."},
|
|
66
|
-
{"role": "user", "content": "Summarize MCP in one line."}
|
|
67
|
-
],
|
|
68
|
-
"max_tokens": 64,
|
|
69
|
-
"temperature": 0.2
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
120
|
+
=== "Bash"
|
|
73
121
|
|
|
74
|
-
|
|
122
|
+
```bash
|
|
123
|
+
curl http://localhost:13305/mcp \
|
|
124
|
+
-H "Content-Type: application/json" \
|
|
125
|
+
-d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'
|
|
126
|
+
```
|
|
75
127
|
|
|
76
|
-
|
|
128
|
+
**Response:** `202 Accepted`
|
|
77
129
|
|
|
78
|
-
|
|
130
|
+
### Response format
|
|
79
131
|
|
|
80
|
-
|
|
132
|
+
One JSON-RPC 2.0 response, or an array of them for a batch.
|
|
81
133
|
|
|
82
|
-
|
|
134
|
+
- `jsonrpc` - Always `2.0`.
|
|
135
|
+
- `id` - The `id` of the request this answers; `null` when it could not be read.
|
|
136
|
+
- `result` - The method's result.
|
|
137
|
+
- `error` - A JSON-RPC error, such as `-32601` for an unknown method.
|
|
138
|
+
- `code` - The JSON-RPC error code.
|
|
139
|
+
- `message` - What went wrong.
|
|
83
140
|
|
|
84
|
-
|
|
85
|
-
{
|
|
86
|
-
"name": "lemonade_transcribe_audio",
|
|
87
|
-
"arguments": {
|
|
88
|
-
"model": "Whisper-Large-v3-Turbo",
|
|
89
|
-
"audio_path": "C:/clips/meeting.wav",
|
|
90
|
-
"response_format": "verbose_json"
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
```
|
|
141
|
+
### Errors
|
|
94
142
|
|
|
95
|
-
|
|
143
|
+
| Status | Code | When |
|
|
144
|
+
|--------|------|------|
|
|
145
|
+
| `500` | `-32603` | An exception escapes the JSON-RPC handling, such as a number too large for a double or invalid UTF-8 in the body |
|
|
146
|
+
<!-- END GENERATED: mcp.rpc -->
|
|
96
147
|
|
|
97
|
-
|
|
148
|
+
<!-- BEGIN GENERATED: mcp.sse -->
|
|
149
|
+
## `GET /mcp`
|
|
150
|
+
<sub></sub>
|
|
98
151
|
|
|
99
|
-
|
|
152
|
+
Lemonade opens no server-initiated event stream, so tools return their full result in the [`POST /mcp`](#post-mcp) reply.
|
|
100
153
|
|
|
101
|
-
|
|
102
|
-
{
|
|
103
|
-
"name": "lemonade_generate_image",
|
|
104
|
-
"arguments": {
|
|
105
|
-
"model": "SDXL-Turbo",
|
|
106
|
-
"prompt": "a lemon-shaped car driving across the moon",
|
|
107
|
-
"size": "512x512",
|
|
108
|
-
"output_path": "lemon-car.png"
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
```
|
|
154
|
+
Requires `LEMONADE_API_KEY` when it is set.
|
|
112
155
|
|
|
113
|
-
|
|
156
|
+
### Errors
|
|
114
157
|
|
|
115
|
-
|
|
158
|
+
| Status | Code | When |
|
|
159
|
+
|--------|------|------|
|
|
160
|
+
| `405` | `-32600` | Always, since MCP calls go to `POST /mcp`; the reply carries `Allow: POST` |
|
|
161
|
+
<!-- END GENERATED: mcp.sse -->
|
|
116
162
|
|
|
117
|
-
|
|
118
|
-
- Override with the `LEMONADE_MCP_IMAGE_DIR` environment variable (absolute path).
|
|
119
|
-
- Relative paths resolve against the sandbox root; absolute paths must stay within it. Paths that escape the sandbox (via `..` or symlinks) are rejected.
|
|
120
|
-
- `output_dir` writes use auto-generated, unique filenames (`image_<token>_<i>.png`), so concurrent callers never clobber one another's images — the returned `paths` tell you the exact names. Use `output_path` when you need an exact, caller-chosen filename (it is written as named, replacing any existing file at that path).
|
|
163
|
+
## Tools
|
|
121
164
|
|
|
122
|
-
|
|
165
|
+
`lemonade_omni` runs the server's collection orchestrator; see the [Lemonade Omni documentation](../dev/lemonade-omni.md) for the collection model and component behavior.
|
|
123
166
|
|
|
124
|
-
|
|
167
|
+
<!--
|
|
168
|
+
The tool reference below is generated from a live Lemonade server's `tools/list`
|
|
169
|
+
response. Tool names, descriptions, input schemas, result contracts, and MCP
|
|
170
|
+
annotations therefore have a single source of truth in the server registry instead
|
|
171
|
+
of being copied into the docs.
|
|
172
|
+
-->
|
|
125
173
|
|
|
126
|
-
|
|
174
|
+
<!-- BEGIN GENERATED: mcp-tools -->
|
|
175
|
+
<!-- Generated from live /mcp tools/list. Do not edit this region by hand. -->
|
|
127
176
|
|
|
128
|
-
|
|
177
|
+
### `lemonade_list_models`
|
|
129
178
|
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
"name": "lemonade_omni",
|
|
133
|
-
"arguments": {
|
|
134
|
-
"messages": [
|
|
135
|
-
{"role": "user", "content": "Generate an image of a lemon car, then read out a one-line description."}
|
|
136
|
-
],
|
|
137
|
-
"output_dir": "omni"
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
```
|
|
179
|
+
List models known to the Lemonade server. ALWAYS call this first if you don't already know the exact model name to use for chat/transcribe/image — passing a wrong name may trigger a multi-GB download. Returns a summary text block plus a JSON block with `{loaded, available, suggested_to_pull, recommended_chat_model}`.
|
|
141
180
|
|
|
142
|
-
**
|
|
181
|
+
**Returns**
|
|
143
182
|
|
|
144
|
-
|
|
183
|
+
Success returns two `text` content blocks: a human-readable summary, then a JSON-stringified object with `loaded`, `available`, `suggested_to_pull`, and `recommended_chat_model`.
|
|
145
184
|
|
|
146
|
-
|
|
185
|
+
| Argument | Required | Schema | Description |
|
|
186
|
+
|---|:---:|---|---|
|
|
187
|
+
| `include_available` | no | `{"type":"boolean"}` | Include downloaded models in the `available` list. |
|
|
188
|
+
| `include_suggested` | no | `{"type":"boolean"}` | Include suggested, not-yet-downloaded models in `suggested_to_pull`. |
|
|
147
189
|
|
|
148
|
-
|
|
190
|
+
### `lemonade_chat`
|
|
149
191
|
|
|
150
|
-
|
|
192
|
+
Chat completion against a locally hosted LLM. Pass a `messages` array (OpenAI chat format). `model` is OPTIONAL: when omitted, the server reuses an already-loaded LLM, else an already-downloaded one; if neither exists it asks you to either pass a `model` or `allow_download: true` (which downloads the default, Qwen3.5-4B-MTP-GGUF). Call `lemonade_list_models` first if you want to choose explicitly — a wrong name may trigger a multi-GB download.
|
|
151
193
|
|
|
152
|
-
|
|
194
|
+
**Returns**
|
|
153
195
|
|
|
154
|
-
|
|
155
|
-
{
|
|
156
|
-
"name": "lemonade_docs",
|
|
157
|
-
"arguments": {
|
|
158
|
-
"page": "api/lemonade"
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
```
|
|
196
|
+
Success returns one `text` content block with the assistant output. If the model emits tool calls, a second `text` block prefixed with `tool_calls: ` contains the JSON tool-call array. If normal content is empty but reasoning content is present, the first block contains the reasoning fallback instead of an empty string.
|
|
162
197
|
|
|
163
|
-
|
|
198
|
+
| Argument | Required | Schema | Description |
|
|
199
|
+
|---|:---:|---|---|
|
|
200
|
+
| `allow_download` | no | `{"type":"boolean"}` | Permit downloading the default model when none is loaded or downloaded. Defaults to false. |
|
|
201
|
+
| `chat_template_kwargs` | no | `{"type":"object"}` | e.g. {"enable_thinking": true} to enable reasoning blocks; disabled by default |
|
|
202
|
+
| `max_tokens` | no | `{"type":"integer"}` | Maximum number of output tokens. |
|
|
203
|
+
| `messages` | yes | `{"items":{"type":"object"},"type":"array"}` | Conversation messages in OpenAI chat format. |
|
|
204
|
+
| `model` | no | `{"type":"string"}` | Optional. Omit to auto-select a loaded/downloaded LLM; defaults to Qwen3.5-4B-MTP-GGUF only with allow_download=true. |
|
|
205
|
+
| `response_format` | no | `{"type":"object"}` | OpenAI-compatible response format configuration. |
|
|
206
|
+
| `seed` | no | `{"type":"integer"}` | Optional random seed for reproducible sampling. |
|
|
207
|
+
| `stop` | no | `{}` | stop sequences (string or array) |
|
|
208
|
+
| `temperature` | no | `{"type":"number"}` | Sampling temperature. |
|
|
209
|
+
| `tool_choice` | no | `{}` | auto \| none \| required \| {type: function, ...} |
|
|
210
|
+
| `tools` | no | `{"items":{"type":"object"},"type":"array"}` | OpenAI-compatible tool definitions available to the model. |
|
|
211
|
+
| `top_p` | no | `{"type":"number"}` | Nucleus sampling probability. |
|
|
164
212
|
|
|
165
|
-
|
|
213
|
+
### `lemonade_transcribe_audio`
|
|
166
214
|
|
|
167
|
-
|
|
168
|
-
|------|---------|
|
|
169
|
-
| `-32700` | Body was not valid JSON. |
|
|
170
|
-
| `-32600` | Request was not a JSON-RPC object (or batch was empty / missing `method`). |
|
|
171
|
-
| `-32601` | Unknown JSON-RPC method (e.g. `resources/list`). |
|
|
172
|
-
| `-32602` | Invalid `params` for a known method. |
|
|
173
|
-
| `-32603` | Internal server error (an exception escaped a handler). |
|
|
215
|
+
Transcribe an audio clip with a Whisper-class model. The Lemonade MCP server always runs on the same machine as the caller, so prefer `audio_path` (an absolute path to a local audio file: wav, mp3, m4a, ogg, flac, webm). Use `audio_base64` only when you genuinely have audio bytes in memory. If both are provided, `audio_path` takes precedence. `model` is OPTIONAL: when omitted, the server reuses an already-loaded transcription model, else an already-downloaded one; if neither exists it asks you to pass a `model` or `allow_download: true` (which downloads the default, Whisper-Tiny).
|
|
174
216
|
|
|
175
|
-
|
|
217
|
+
**Returns**
|
|
176
218
|
|
|
177
|
-
|
|
219
|
+
Success returns two `text` content blocks: the transcript, then the JSON-stringified full transcription response, including timestamps or segments when provided by the backend.
|
|
178
220
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
221
|
+
| Argument | Required | Schema | Description |
|
|
222
|
+
|---|:---:|---|---|
|
|
223
|
+
| `allow_download` | no | `{"type":"boolean"}` | Permit downloading the default model when none is loaded or downloaded. Defaults to false. |
|
|
224
|
+
| `audio_base64` | no | `{"type":"string"}` | Base64-encoded audio data. Used when `audio_path` is not provided. |
|
|
225
|
+
| `audio_path` | no | `{"type":"string"}` | Path to a local audio file. Preferred over `audio_base64`; absolute paths avoid working-directory ambiguity. |
|
|
226
|
+
| `filename` | no | `{"type":"string"}` | Original audio filename, used as an input-format hint. |
|
|
227
|
+
| `language` | no | `{"type":"string"}` | Optional source language hint. |
|
|
228
|
+
| `model` | no | `{"type":"string"}` | Optional. Omit to auto-select a loaded/downloaded model; defaults to Whisper-Tiny only with allow_download=true. |
|
|
229
|
+
| `prompt` | no | `{"type":"string"}` | Optional text prompt to guide transcription. |
|
|
230
|
+
| `response_format` | no | `{"enum":["json","text","srt","verbose_json","vtt"],"type":"string"}` | Transcription response format. |
|
|
231
|
+
| `temperature` | no | `{"type":"number"}` | Sampling temperature for transcription. |
|
|
184
232
|
|
|
185
|
-
|
|
233
|
+
### `lemonade_generate_image`
|
|
186
234
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
235
|
+
Generate one or more images from a text prompt. The Lemonade MCP server always runs on the same machine as the caller, so PREFER writing the result directly to disk by passing `output_path` (single image) or `output_dir` (one or more). When you do, the tool returns absolute file path(s) as text — no base64 round-trip and dramatically fewer tokens. Only omit both arguments when you genuinely need the image inline. For safety, disk writes are confined to a sandbox directory (<cache_dir>/mcp-images, or LEMONADE_MCP_IMAGE_DIR if set); paths outside it are rejected. `output_dir` writes get unique auto-generated filenames (so concurrent callers never clobber each other); use `output_path` when you need an exact name. `model` is OPTIONAL: when omitted, the server reuses an already-loaded image model, else an already-downloaded one; if neither exists it asks you to pass a `model` or `allow_download: true` (which downloads the default, SD-Turbo).
|
|
236
|
+
|
|
237
|
+
**Returns**
|
|
238
|
+
|
|
239
|
+
Without `output_path` or `output_dir`, success returns one native MCP `image` content block per generated PNG. With disk output, success returns a summary `text` block, optional per-image path blocks when multiple files are written, and a final JSON-stringified `paths` object in a `text` block.
|
|
240
|
+
|
|
241
|
+
| Argument | Required | Schema | Description |
|
|
242
|
+
|---|:---:|---|---|
|
|
243
|
+
| `allow_download` | no | `{"type":"boolean"}` | Permit downloading the default model when none is loaded or downloaded. Defaults to false. |
|
|
244
|
+
| `cfg_scale` | no | `{"type":"number"}` | Classifier-free guidance scale. |
|
|
245
|
+
| `model` | no | `{"type":"string"}` | Optional. Omit to auto-select a loaded/downloaded image model; defaults to SD-Turbo only with allow_download=true. |
|
|
246
|
+
| `n` | no | `{"minimum":1,"type":"integer"}` | Number of images to generate. |
|
|
247
|
+
| `negative_prompt` | no | `{"type":"string"}` | Text describing content to avoid in the generated image. |
|
|
248
|
+
| `output_dir` | no | `{"type":"string"}` | Directory to write generated images into, inside the MCP image sandbox. Filenames are auto-generated and unique (image_{token}_{index}.png); the returned paths tell you the exact names. Relative paths resolve against the sandbox root; absolute paths must stay within it. |
|
|
249
|
+
| `output_path` | no | `{"type":"string"}` | Exact path of the PNG file to write, inside the MCP image sandbox (<cache_dir>/mcp-images or LEMONADE_MCP_IMAGE_DIR). Relative paths resolve against the sandbox root; absolute paths must stay within it. Written as named (overwrites if it already exists). Only valid when n == 1. |
|
|
250
|
+
| `prompt` | yes | `{"type":"string"}` | Text prompt describing the image to generate. |
|
|
251
|
+
| `seed` | no | `{"type":"integer"}` | Optional random seed for reproducible generation. |
|
|
252
|
+
| `size` | no | `{"type":"string"}` | Requested image size as WIDTHxHEIGHT, for example 512x512. |
|
|
253
|
+
| `steps` | no | `{"type":"integer"}` | Number of diffusion sampling steps. |
|
|
254
|
+
|
|
255
|
+
### `lemonade_omni`
|
|
256
|
+
|
|
257
|
+
Multimodal turn against a Lemonade Omni collection (one tool call -> text + images + speech in the same response). The server runs an internal tool-calling loop against the collection's planner LLM and executes its image / image-edit / TTS tools by routing to the bundled component models; the result comes back as a text block plus native MCP `image` / `audio` content blocks (one per artifact). `model` is OPTIONAL: when omitted, the server reuses an already-downloaded Omni collection; if none is downloaded it asks you to pass a `model` or `allow_download: true` (which downloads the default, `LMX-Omni-5.5B-Lite`). Pass `model='LMX-Omni-52B-Halo'` (or any other recipe='collection.omni' model from `lemonade_list_models`) to opt into a larger collection; that model may be multi-GB. Same-machine deployment: PREFER `output_dir` to write artifacts to disk and avoid expensive inline base64 blobs. For plain text chat against a regular LLM, use `lemonade_chat` instead.
|
|
258
|
+
|
|
259
|
+
**Returns**
|
|
260
|
+
|
|
261
|
+
Success always starts with one `text` block containing the final text. Artifacts follow in the order they were produced. Inline mode then appends one native MCP `image` or `audio` block per artifact. Disk mode instead appends one `text` block per artifact path in the same order, plus a final JSON-stringified `paths` object. If application tool calls are emitted, a final `text` block prefixed with `tool_calls: ` is appended.
|
|
262
|
+
|
|
263
|
+
| Argument | Required | Schema | Description |
|
|
264
|
+
|---|:---:|---|---|
|
|
265
|
+
| `allow_download` | no | `{"type":"boolean"}` | Permit downloading the default collection when none is downloaded. Defaults to false. |
|
|
266
|
+
| `chat_template_kwargs` | no | `{"type":"object"}` | Additional chat-template arguments forwarded to the planner LLM. |
|
|
267
|
+
| `max_tokens` | no | `{"type":"integer"}` | Maximum number of planner output tokens. |
|
|
268
|
+
| `messages` | yes | `{"items":{"type":"object"},"type":"array"}` | Conversation messages in OpenAI chat format. |
|
|
269
|
+
| `model` | no | `{"type":"string"}` | Optional. Omni collection name (recipe='collection.omni'). Omit to reuse a downloaded collection; defaults to LMX-Omni-5.5B-Lite only with allow_download=true. |
|
|
270
|
+
| `output_dir` | no | `{"type":"string"}` | Directory to write produced artifacts into, inside the MCP image sandbox (<cache_dir>/mcp-images or LEMONADE_MCP_IMAGE_DIR). Filenames are auto-generated and unique (omni_{token}_{index}.{ext}); the returned paths tell you the exact names. Relative paths resolve against the sandbox root; absolute paths must stay within it. PREFER this to inline base64 when caller and server share a filesystem. Omit to receive artifacts inline as MCP content blocks. |
|
|
271
|
+
| `response_format` | no | `{"type":"object"}` | OpenAI-compatible response format configuration for the planner. |
|
|
272
|
+
| `seed` | no | `{"type":"integer"}` | Optional random seed forwarded to the planner LLM. |
|
|
273
|
+
| `stop` | no | `{}` | stop sequences (string or array) |
|
|
274
|
+
| `temperature` | no | `{"type":"number"}` | Sampling temperature for the planner LLM. |
|
|
275
|
+
| `tool_choice` | no | `{}` | auto \| none \| required \| {type: function, ...} |
|
|
276
|
+
| `tools` | no | `{"items":{"type":"object"},"type":"array"}` | OpenAI-compatible application tool definitions passed to the planner. |
|
|
277
|
+
| `top_p` | no | `{"type":"number"}` | Nucleus sampling probability for the planner LLM. |
|
|
191
278
|
|
|
192
|
-
|
|
279
|
+
### `lemonade_docs`
|
|
280
|
+
|
|
281
|
+
Read this server's own API reference. Call with no arguments to list the pages it ships, then pass `page` (an `id` from that list) to read one as markdown. The docs are bundled with the server, so they describe the version actually running and work offline. Use this before hand-writing requests against Lemonade endpoints.
|
|
282
|
+
|
|
283
|
+
**Returns**
|
|
284
|
+
|
|
285
|
+
With `page`, success returns one `text` block containing the raw bundled Markdown page. With no arguments, success normally returns a summary `text` block followed by a JSON-stringified `pages` object containing `id`, `title`, and `bytes` for each page; if no bundled documentation is installed, it returns one explanatory `text` block instead. Unknown pages return `isError: true` with one explanatory `text` block. The same bundled documentation is also available through `GET /v1/docs`.
|
|
286
|
+
|
|
287
|
+
| Argument | Required | Schema | Description |
|
|
288
|
+
|---|:---:|---|---|
|
|
289
|
+
| `page` | no | `{"type":"string"}` | Optional. Page id from the listing, e.g. 'api/lemonade'. Omit to list. |
|
|
290
|
+
|
|
291
|
+
<!-- END GENERATED: mcp-tools -->
|
|
292
|
+
|
|
293
|
+
## Quick Test with curl
|
|
294
|
+
|
|
295
|
+
After the `initialize` request in [`POST /mcp`](#post-mcp), list the tools and call one:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
193
298
|
curl -s http://localhost:13305/mcp -H "Content-Type: application/json" \
|
|
194
299
|
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
|
|
195
300
|
|
|
196
|
-
# 3. Call lemonade_chat
|
|
197
301
|
curl -s http://localhost:13305/mcp -H "Content-Type: application/json" \
|
|
198
302
|
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"lemonade_chat","arguments":{"model":"Qwen3-1.7B-GGUF","messages":[{"role":"user","content":"hi"}],"max_tokens":16}}}'
|
|
199
303
|
```
|