@tokenlabai/mcp-server 0.2.2 → 0.4.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 CHANGED
@@ -1,20 +1,25 @@
1
1
  # TokenLab MCP Server
2
2
 
3
- Model Context Protocol server for TokenLab public model discovery, pricing, OpenAI-compatible Chat Completions, native endpoint guidance, and optional inference helpers.
3
+ [![CI](https://github.com/hedging8563/tokenlab-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/hedging8563/tokenlab-mcp-server/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/%40tokenlabai%2Fmcp-server)](https://www.npmjs.com/package/@tokenlabai/mcp-server)
5
+ [![npm downloads](https://img.shields.io/npm/dm/%40tokenlabai%2Fmcp-server)](https://www.npmjs.com/package/@tokenlabai/mcp-server)
4
6
 
5
- It exposes public catalog tools for agents that need to choose models, inspect supported request formats, or compare pricing before calling TokenLab APIs. Optional inference tools require `TOKENLAB_API_KEY`.
7
+ OpenAPI-generated Model Context Protocol server for TokenLab public model discovery, pricing, native LLM endpoints, multimodal generation, async tasks, files, embeddings, rerank, translation, and the broader developer API.
6
8
 
7
- ## Tools
9
+ It exposes public catalog tools for agents that need to choose models, inspect supported request formats, or compare pricing before calling TokenLab APIs. Credentialed tools cover text inference, image generation and editing, video, music, 3D, async task polling, embeddings, rerank, and text translation.
8
10
 
9
- - `list_models` - List public TokenLab models, optionally filtered by `recommended_for`.
10
- - `get_model` - Fetch public model details for one model ID.
11
- - `get_model_pricing` - Fetch pricing details for one model ID.
12
- - `compare_models` - Compare details and pricing for several model IDs.
13
- - `get_api_overview` - Fetch the agent-readable `llms.txt` overview.
14
- - `create_chat_completion` - Call TokenLab's OpenAI-compatible non-streaming Chat Completions API. Requires `TOKENLAB_API_KEY`.
15
- - `create_response` - Call TokenLab Responses API. Requires `TOKENLAB_API_KEY`.
16
- - `create_anthropic_message` - Call TokenLab Anthropic Messages API. Requires `TOKENLAB_API_KEY`.
17
- - `create_gemini_content` - Call TokenLab Gemini generateContent API. Requires `TOKENLAB_API_KEY`.
11
+ ## Generated Tool Profiles
12
+
13
+ The checked-in `generated/tools.json` manifest is generated from TokenLab's public OpenAPI document plus the small MCP-only overlay in `contract/mcp-overlay.json`. Version 0.4.0 generates 76 endpoint tools; two composite discovery tools are registered at runtime.
14
+
15
+ | Profile | Endpoint tools | Coverage |
16
+ | --- | ---: | --- |
17
+ | `core` (default) | 29 | Catalog and pricing; Chat Completions, Responses, Anthropic Messages, Gemini generateContent; images, video, music, 3D, speech and transcription; async tasks; files; embeddings, rerank, and translation |
18
+ | `full` | 76 | Every allowlisted developer API operation in the checked-in OpenAPI snapshot, including core plus response lifecycle, batches, worlds, and native model discovery |
19
+
20
+ Both profiles also include `compare_models` and `get_api_overview`. Realtime and streaming-only operations are excluded because stdio MCP tool calls return one final result. API operations that accept `stream` constrain it to `false` in the MCP overlay, and the Gemini query-string API key is intentionally hidden from tool arguments.
21
+
22
+ Set `TOKENLAB_MCP_TOOL_PROFILE=full` to expose the full profile. Tool names, descriptions, input JSON Schemas, HTTP bindings, content types, auth requirements, and task behavior can be inspected in [`generated/tools.json`](./generated/tools.json).
18
23
 
19
24
  ## Run
20
25
 
@@ -29,14 +34,25 @@ Install from npm:
29
34
  npx -y @tokenlabai/mcp-server
30
35
  ```
31
36
 
37
+ Agent-assisted installers can follow [`llms-install.md`](./llms-install.md) for a credential-safe setup and verification flow.
38
+
39
+ Run in Docker:
40
+
41
+ ```bash
42
+ docker build -t tokenlab-mcp-server .
43
+ docker run --rm -i tokenlab-mcp-server
44
+ ```
45
+
46
+ Add `-e TOKENLAB_API_KEY` when using credentialed API tools. Public catalog tools do not require a key.
47
+
32
48
  Claude Desktop style config:
33
49
 
34
50
  ```json
35
51
  {
36
52
  "mcpServers": {
37
53
  "tokenlab-model-catalog": {
38
- "command": "node",
39
- "args": ["/absolute/path/to/tokenlab-mcp-server/src/index.js"],
54
+ "command": "npx",
55
+ "args": ["-y", "@tokenlabai/mcp-server"],
40
56
  "env": {
41
57
  "TOKENLAB_API_BASE": "https://api.tokenlab.sh"
42
58
  }
@@ -45,29 +61,71 @@ Claude Desktop style config:
45
61
  }
46
62
  ```
47
63
 
48
- No TokenLab API key is required for the public catalog tools. Set `TOKENLAB_API_KEY` only when you want the inference helper tools to call paid TokenLab APIs. `create_chat_completion` supports OpenAI-compatible messages, multimodal content parts, function calling, and common generation controls. MCP tools return a normal JSON result, so streaming is intentionally disabled.
64
+ No TokenLab API key is required for public catalog and pricing operations. Set `TOKENLAB_API_KEY` when credentialed tools should call TokenLab APIs. Generated tools preserve the OpenAPI request shape for OpenAI-compatible and native endpoints instead of flattening them into a shared prompt format.
65
+
66
+ Multipart operations accept local file paths. Small image and audio responses are returned as native MCP content; larger or other binary responses are written to `TOKENLAB_ARTIFACT_DIR` and returned as a path with MIME type and byte count.
67
+
68
+ ## Sync and Async Media Results
69
+
70
+ Video, music, and 3D creation tools always return an async task. Image generation and editing may return a completed result or an async task depending on the selected model and request.
71
+
72
+ Media tools preserve the complete TokenLab API response under `response` and add a normalized `delivery` summary:
73
+
74
+ ```json
75
+ {
76
+ "delivery": {
77
+ "mode": "async",
78
+ "task_id": "ldtask_...",
79
+ "status": "pending",
80
+ "poll_url": "/v1/tasks/ldtask_...",
81
+ "terminal": false,
82
+ "next_tool": "get_task_status"
83
+ },
84
+ "response": {}
85
+ }
86
+ ```
87
+
88
+ Use `delivery.mode` instead of assuming all image requests are synchronous. For async tasks, call `get_task_status` with `{ "id": delivery.task_id }` until `delivery.terminal` is `true`. Completion is determined from `status`, not from an optional progress field.
49
89
 
50
90
  ## Environment
51
91
 
52
92
  - `TOKENLAB_API_BASE`: optional, defaults to `https://api.tokenlab.sh`
53
- - `TOKENLAB_API_KEY`: optional; required only for `create_chat_completion`, `create_response`, `create_anthropic_message`, and `create_gemini_content`
93
+ - `TOKENLAB_API_KEY`: optional; required for text inference, multimodal generation, async task, embedding, rerank, and translation tools
94
+ - `TOKENLAB_MCP_TOOL_PROFILE`: optional, `core` (default) or `full`
95
+ - `TOKENLAB_REQUEST_TIMEOUT_MS`: optional request timeout in milliseconds, defaults to `120000`
96
+ - `TOKENLAB_MCP_MAX_FILE_BYTES`: optional maximum local upload size per file, defaults to `104857600` (100 MiB)
97
+ - `TOKENLAB_MCP_INLINE_BYTES`: optional maximum binary/JSON response size returned inline, defaults to `2097152` (2 MiB)
98
+ - `TOKENLAB_ARTIFACT_DIR`: optional output directory for non-inline response artifacts, defaults to the OS temp directory under `tokenlab-mcp`
99
+
100
+ ## Contract Sync
101
+
102
+ The public OpenAPI document is the API contract source. The overlay contains only MCP-specific choices: profile exposure, stable tool aliases, secret omission, non-streaming constraints, content-type variants, and async task semantics.
103
+
104
+ ```bash
105
+ npm run contract:sync # fetch OpenAPI and regenerate the manifest
106
+ npm run contract:check # fail when generated output is stale
107
+ npm test # compile both profiles and test routing, tasks, files, and binary output
108
+ ```
109
+
110
+ The scheduled `Sync TokenLab OpenAPI contract` workflow runs this full sequence and commits only the verified OpenAPI snapshot and generated manifest to `main`. A failed fetch, generation, schema compilation, or test leaves `main` unchanged.
54
111
 
55
112
  ## MCP Registry Metadata
56
113
 
57
114
  This repository includes `server.json` for the official MCP Registry.
58
115
 
59
- Current publication:
116
+ Release metadata:
60
117
 
61
- - npm package: `@tokenlabai/mcp-server@0.2.2`
118
+ - npm package: `@tokenlabai/mcp-server@0.4.0`
62
119
  - MCP registry name: `io.github.hedging8563/tokenlab`
63
- - Official MCP Registry status: active
64
120
  - `package.json.mcpName`: `io.github.hedging8563/tokenlab`
65
121
 
66
122
  For a new release:
67
123
 
68
- 1. Publish the next `@tokenlabai/mcp-server` version to npm.
69
- 2. Authenticate with `mcp-publisher login github`.
70
- 3. Update `server.json` and run `mcp-publisher publish`.
124
+ 1. Bump the matching versions in `package.json`, `package-lock.json`, and `server.json`.
125
+ 2. Push a matching tag such as `v0.4.0`.
126
+ 3. The publish workflow tests and publishes npm through trusted publishing, then publishes the MCP Registry entry through GitHub Actions OIDC.
127
+
128
+ The same workflow can be run manually from `main` to republish only the current MCP Registry metadata. No npm or MCP Registry token is stored in GitHub.
71
129
 
72
130
  ## Links
73
131
 
@@ -0,0 +1,212 @@
1
+ {
2
+ "schema_version": 1,
3
+ "openapi_url": "https://docs.tokenlab.sh/openapi.json",
4
+ "default_profile": "core",
5
+ "profiles": {
6
+ "core": {
7
+ "operations": [
8
+ "listModels",
9
+ "getModel",
10
+ "getModelPricing",
11
+ "getPricing",
12
+ "createChatCompletion",
13
+ "createResponse",
14
+ "createAnthropicMessage",
15
+ "geminiGenerateContent",
16
+ "createEmbedding",
17
+ "createMultimodalEmbedding",
18
+ "rerankDocuments",
19
+ "createTranslation",
20
+ "createImage",
21
+ "editImage",
22
+ "createVideo",
23
+ "createMusic",
24
+ "create3D",
25
+ "getAsyncTask",
26
+ "cancelAsyncTask",
27
+ "createSpeech",
28
+ "createTranscription",
29
+ "createAudioTranslation",
30
+ "uploadFile",
31
+ "listFiles",
32
+ "retrieveFile",
33
+ "retrieveFileContent",
34
+ "deleteFile"
35
+ ]
36
+ },
37
+ "full": {
38
+ "include_tags": [
39
+ "Chat",
40
+ "Embeddings",
41
+ "Images",
42
+ "Audio",
43
+ "Video",
44
+ "Tasks",
45
+ "Models",
46
+ "Anthropic",
47
+ "Gemini",
48
+ "Files",
49
+ "Batches",
50
+ "Text",
51
+ "Worlds",
52
+ "Seedance Volc Compatible"
53
+ ],
54
+ "exclude_operations": [
55
+ "geminiStreamGenerateContent",
56
+ "connectRealtime"
57
+ ]
58
+ }
59
+ },
60
+ "public_auth_operations": [
61
+ "listModels",
62
+ "getModel",
63
+ "getModelPricing",
64
+ "getPricing"
65
+ ],
66
+ "operation_overrides": {
67
+ "createAnthropicMessage": {
68
+ "tool_name": "create_anthropic_message",
69
+ "input_property_overrides": {
70
+ "stream": {
71
+ "const": false,
72
+ "description": "MCP tool calls return one final result; omit stream or set it to false."
73
+ }
74
+ }
75
+ },
76
+ "geminiGenerateContent": {
77
+ "tool_name": "create_gemini_content",
78
+ "omit_arguments": ["key"]
79
+ },
80
+ "createChatCompletion": {
81
+ "input_property_overrides": {
82
+ "stream": {
83
+ "const": false,
84
+ "description": "MCP tool calls return one final result; omit stream or set it to false."
85
+ }
86
+ }
87
+ },
88
+ "createResponse": {
89
+ "input_property_overrides": {
90
+ "stream": {
91
+ "const": false,
92
+ "description": "MCP tool calls return one final result; omit stream or set it to false."
93
+ }
94
+ }
95
+ },
96
+ "getAsyncTask": {
97
+ "tool_name": "get_task_status",
98
+ "task": {
99
+ "mode": "status",
100
+ "id_fields": ["task_id", "id"],
101
+ "status_field": "status",
102
+ "poll_url_field": "poll_url",
103
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
104
+ }
105
+ },
106
+ "cancelAsyncTask": {
107
+ "tool_name": "cancel_task",
108
+ "task": {
109
+ "mode": "status",
110
+ "id_fields": ["task_id", "id"],
111
+ "status_field": "status",
112
+ "poll_url_field": "poll_url",
113
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
114
+ }
115
+ },
116
+ "createTranslation": {
117
+ "tool_name": "translate_text"
118
+ },
119
+ "createAudioTranslation": {
120
+ "tool_name": "translate_audio"
121
+ },
122
+ "createTranscription": {
123
+ "tool_name": "transcribe_audio"
124
+ },
125
+ "createImage": {
126
+ "all_content_types": true,
127
+ "tool_names_by_content_type": {
128
+ "application/json": "create_image",
129
+ "multipart/form-data": "create_image_file"
130
+ },
131
+ "input_property_overrides": {
132
+ "stream": {
133
+ "const": false,
134
+ "description": "Image streaming is not exposed through MCP tool calls; omit stream or set it to false."
135
+ }
136
+ },
137
+ "task": {
138
+ "mode": "hybrid",
139
+ "id_fields": ["task_id", "id"],
140
+ "status_field": "status",
141
+ "poll_url_field": "poll_url",
142
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
143
+ }
144
+ },
145
+ "editImage": {
146
+ "all_content_types": true,
147
+ "tool_names_by_content_type": {
148
+ "application/json": "edit_image",
149
+ "multipart/form-data": "edit_image_file"
150
+ },
151
+ "input_property_overrides": {
152
+ "stream": {
153
+ "const": false,
154
+ "description": "Image streaming is not exposed through MCP tool calls; omit stream or set it to false."
155
+ }
156
+ },
157
+ "task": {
158
+ "mode": "hybrid",
159
+ "id_fields": ["task_id", "id"],
160
+ "status_field": "status",
161
+ "poll_url_field": "poll_url",
162
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
163
+ }
164
+ },
165
+ "createVideo": {
166
+ "task": {
167
+ "mode": "async",
168
+ "id_fields": ["task_id", "id"],
169
+ "status_field": "status",
170
+ "poll_url_field": "poll_url",
171
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
172
+ }
173
+ },
174
+ "createMusic": {
175
+ "task": {
176
+ "mode": "async",
177
+ "id_fields": ["task_id", "id"],
178
+ "status_field": "status",
179
+ "poll_url_field": "poll_url",
180
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
181
+ }
182
+ },
183
+ "create3D": {
184
+ "tool_name": "create_3d_model",
185
+ "task": {
186
+ "mode": "async",
187
+ "id_fields": ["task_id", "id"],
188
+ "status_field": "status",
189
+ "poll_url_field": "poll_url",
190
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
191
+ }
192
+ },
193
+ "createWorld": {
194
+ "task": {
195
+ "mode": "async",
196
+ "id_fields": ["task_id", "id"],
197
+ "status_field": "status",
198
+ "poll_url_field": "poll_url",
199
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
200
+ }
201
+ },
202
+ "getWorldStatus": {
203
+ "task": {
204
+ "mode": "status",
205
+ "id_fields": ["task_id", "id"],
206
+ "status_field": "status",
207
+ "poll_url_field": "poll_url",
208
+ "terminal_statuses": ["completed", "succeeded", "failed", "cancelled", "canceled", "expired"]
209
+ }
210
+ }
211
+ }
212
+ }