@tokenlabai/mcp-server 0.5.0 → 0.6.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 CHANGED
@@ -10,7 +10,7 @@ It exposes public catalog tools for agents that need to choose models, inspect s
10
10
 
11
11
  ## Generated Tool Profiles
12
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.5.0 generates 76 endpoint tools; two composite discovery tools are registered at runtime.
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.6.1 generates 76 endpoint tools; two composite discovery tools are registered at runtime.
14
14
 
15
15
  | Profile | Endpoint tools | Coverage |
16
16
  | --- | ---: | --- |
@@ -126,14 +126,14 @@ This repository includes `server.json` for the official MCP Registry.
126
126
 
127
127
  Release metadata:
128
128
 
129
- - npm package: `@tokenlabai/mcp-server@0.5.0`
129
+ - npm package: `@tokenlabai/mcp-server@0.6.1`
130
130
  - MCP registry name: `io.github.hedging8563/tokenlab`
131
131
  - `package.json.mcpName`: `io.github.hedging8563/tokenlab`
132
132
 
133
133
  For a new release:
134
134
 
135
135
  1. Bump the matching versions in `package.json`, `package-lock.json`, and `server.json`.
136
- 2. Push a matching tag such as `v0.5.0`.
136
+ 2. Push a matching tag such as `v0.6.0`.
137
137
  3. The publish workflow tests and publishes npm through trusted publishing, then publishes the MCP Registry entry through GitHub Actions OIDC.
138
138
 
139
139
  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.
@@ -69,6 +69,19 @@
69
69
  "landing_url": "https://tokenlab.sh/mcp",
70
70
  "docs_url": "https://docs.tokenlab.sh/integrations/tokenlab-mcp-server",
71
71
  "recommended_client_name": "tokenlab",
72
+ "live_model_contract": {
73
+ "tool": "get_model",
74
+ "endpoint": "/v1/models/{model}",
75
+ "fields": [
76
+ "supported_operations",
77
+ "supported_parameters",
78
+ "request_endpoint",
79
+ "request_endpoint_by_operation",
80
+ "request_shape_mode",
81
+ "operation_constraints",
82
+ "recommended_request"
83
+ ]
84
+ },
72
85
  "composite_tools": [
73
86
  {
74
87
  "name": "compare_models",
@@ -162,6 +175,16 @@
162
175
  "getPricing"
163
176
  ],
164
177
  "operation_overrides": {
178
+ "listModels": {
179
+ "default_arguments": {
180
+ "view": "compact"
181
+ },
182
+ "input_property_overrides": {
183
+ "view": {
184
+ "description": "Compact model-selection output is the MCP default. Set view to full only when the complete OpenAI-compatible list shape is required."
185
+ }
186
+ }
187
+ },
165
188
  "cancelAnthropicMessageBatch": {
166
189
  "annotations": {
167
190
  "readOnlyHint": false,
@@ -1597,22 +1597,111 @@
1597
1597
  "Models"
1598
1598
  ],
1599
1599
  "summary": "List models",
1600
- "description": "Lists the currently available models. Default responses are trimmed for discovery. Non-chat models may include lightweight request-format metadata; `agent_preferences` appears only when `recommended_for` is present. Deprecated `lemondata` is still returned as a compatibility alias during the migration.",
1600
+ "description": "Lists the currently available models. Use `view=compact` for model selection and `view=full` for the existing OpenAI-compatible discovery shape. Native API calls default to `full`; integrations may choose `compact` as their default. Non-chat recommendations are available through `recommended_for`.",
1601
1601
  "operationId": "listModels",
1602
+ "parameters": [
1603
+ {
1604
+ "name": "provider",
1605
+ "in": "query",
1606
+ "required": false,
1607
+ "description": "Filter by public model provider, for example openai, anthropic, google, or minimax.",
1608
+ "schema": {
1609
+ "type": "string"
1610
+ }
1611
+ },
1612
+ {
1613
+ "name": "tag",
1614
+ "in": "query",
1615
+ "required": false,
1616
+ "description": "Filter by a public capability tag.",
1617
+ "schema": {
1618
+ "type": "string"
1619
+ }
1620
+ },
1621
+ {
1622
+ "name": "category",
1623
+ "in": "query",
1624
+ "required": false,
1625
+ "description": "Filter by model category.",
1626
+ "schema": {
1627
+ "type": "string",
1628
+ "enum": [
1629
+ "chat",
1630
+ "embedding",
1631
+ "translation",
1632
+ "image",
1633
+ "video",
1634
+ "audio",
1635
+ "tts",
1636
+ "stt",
1637
+ "rerank",
1638
+ "3d",
1639
+ "music"
1640
+ ]
1641
+ }
1642
+ },
1643
+ {
1644
+ "name": "recommended_for",
1645
+ "in": "query",
1646
+ "required": false,
1647
+ "description": "Sort supported non-chat models for a task category and include recommendation evidence.",
1648
+ "schema": {
1649
+ "type": "string",
1650
+ "enum": [
1651
+ "image",
1652
+ "video",
1653
+ "music",
1654
+ "3d",
1655
+ "tts",
1656
+ "stt",
1657
+ "embedding",
1658
+ "rerank",
1659
+ "translation"
1660
+ ]
1661
+ }
1662
+ },
1663
+ {
1664
+ "name": "view",
1665
+ "in": "query",
1666
+ "required": false,
1667
+ "description": "Choose compact model-selection fields or the full OpenAI-compatible list shape.",
1668
+ "schema": {
1669
+ "type": "string",
1670
+ "enum": [
1671
+ "compact",
1672
+ "full"
1673
+ ],
1674
+ "default": "full"
1675
+ }
1676
+ }
1677
+ ],
1602
1678
  "responses": {
1603
1679
  "200": {
1604
1680
  "description": "List of models",
1605
1681
  "content": {
1606
1682
  "application/json": {
1607
1683
  "schema": {
1608
- "$ref": "#/components/schemas/ModelsResponse"
1684
+ "oneOf": [
1685
+ {
1686
+ "$ref": "#/components/schemas/ModelsResponse"
1687
+ },
1688
+ {
1689
+ "$ref": "#/components/schemas/CompactModelsResponse"
1690
+ }
1691
+ ]
1609
1692
  }
1610
1693
  }
1611
1694
  }
1612
1695
  },
1696
+ "400": {
1697
+ "$ref": "#/components/responses/BadRequest"
1698
+ },
1613
1699
  "401": {
1614
1700
  "$ref": "#/components/responses/Unauthorized"
1615
1701
  },
1702
+ "429": {
1703
+ "$ref": "#/components/responses/RateLimitExceeded"
1704
+ },
1616
1705
  "500": {
1617
1706
  "$ref": "#/components/responses/ServerError"
1618
1707
  }
@@ -1625,7 +1714,7 @@
1625
1714
  "Models"
1626
1715
  ],
1627
1716
  "summary": "Get model",
1628
- "description": "Retrieves a model instance, providing basic information about the model.",
1717
+ "description": "Retrieves current model details, including supported operations, request parameters, request endpoints, selector limits, and pricing when available. Non-chat integrations should read these current model-specific request details before creating a request.",
1629
1718
  "operationId": "getModel",
1630
1719
  "parameters": [
1631
1720
  {
@@ -7178,21 +7267,11 @@
7178
7267
  },
7179
7268
  "size": {
7180
7269
  "type": "string",
7181
- "default": "1024x1024",
7182
- "description": "Image size. For gpt-image-2, use auto or WIDTHxHEIGHT; custom dimensions must both be multiples of 16, longest edge <= 3840px, long/short ratio <= 3:1, and total pixels between 655,360 and 8,294,400."
7270
+ "description": "Image size. Defaults are model-specific. For gpt-image-2, omit this field or use auto for automatic sizing, or send WIDTHxHEIGHT; custom dimensions must both be multiples of 16, longest edge <= 3840px, long/short ratio <= 3:1, and total pixels between 655,360 and 8,294,400."
7183
7271
  },
7184
7272
  "quality": {
7185
7273
  "type": "string",
7186
- "enum": [
7187
- "standard",
7188
- "hd",
7189
- "auto",
7190
- "low",
7191
- "medium",
7192
- "high"
7193
- ],
7194
- "default": "standard",
7195
- "description": "Image quality. GPT Image models such as gpt-image-2 use auto/low/medium/high. Other image families may use provider-specific values."
7274
+ "description": "Image quality. Defaults and accepted values are model-specific. For gpt-image-2, omit this field or use auto for automatic quality, or send low, medium, or high. Other image families may use provider-specific values."
7196
7275
  },
7197
7276
  "style": {
7198
7277
  "type": "string",
@@ -8356,7 +8435,180 @@
8356
8435
  "required": [
8357
8436
  "object",
8358
8437
  "data"
8359
- ]
8438
+ ],
8439
+ "additionalProperties": false
8440
+ },
8441
+ "CompactModelsResponse": {
8442
+ "type": "object",
8443
+ "description": "Compact model-selection response used by TokenLab MCP and other agent integrations.",
8444
+ "properties": {
8445
+ "object": {
8446
+ "type": "string",
8447
+ "enum": [
8448
+ "list"
8449
+ ]
8450
+ },
8451
+ "view": {
8452
+ "type": "string",
8453
+ "enum": [
8454
+ "compact"
8455
+ ]
8456
+ },
8457
+ "count": {
8458
+ "type": "integer",
8459
+ "minimum": 0
8460
+ },
8461
+ "data": {
8462
+ "type": "array",
8463
+ "items": {
8464
+ "$ref": "#/components/schemas/CompactModelListItem"
8465
+ }
8466
+ }
8467
+ },
8468
+ "required": [
8469
+ "object",
8470
+ "view",
8471
+ "count",
8472
+ "data"
8473
+ ],
8474
+ "additionalProperties": false
8475
+ },
8476
+ "CompactModelListItem": {
8477
+ "type": "object",
8478
+ "description": "Fields needed to shortlist a model before calling get_model or get_model_pricing.",
8479
+ "properties": {
8480
+ "id": {
8481
+ "type": "string",
8482
+ "description": "Model identifier"
8483
+ },
8484
+ "provider": {
8485
+ "type": "string",
8486
+ "description": "Public model provider"
8487
+ },
8488
+ "category": {
8489
+ "type": "string"
8490
+ },
8491
+ "capabilities": {
8492
+ "type": "array",
8493
+ "items": {
8494
+ "type": "string"
8495
+ }
8496
+ },
8497
+ "max_input_tokens": {
8498
+ "type": [
8499
+ "number",
8500
+ "null"
8501
+ ]
8502
+ },
8503
+ "max_output_tokens": {
8504
+ "type": [
8505
+ "number",
8506
+ "null"
8507
+ ]
8508
+ },
8509
+ "pricing": {
8510
+ "type": "object",
8511
+ "properties": {
8512
+ "unit": {
8513
+ "type": "string"
8514
+ },
8515
+ "currency": {
8516
+ "type": "string",
8517
+ "enum": [
8518
+ "USD"
8519
+ ]
8520
+ },
8521
+ "input_per_1m": {
8522
+ "type": "string"
8523
+ },
8524
+ "output_per_1m": {
8525
+ "type": "string"
8526
+ },
8527
+ "per_request": {
8528
+ "type": "string"
8529
+ },
8530
+ "min_price": {
8531
+ "type": "string",
8532
+ "description": "Minimum TokenLab price for a structured pricing model."
8533
+ },
8534
+ "max_price": {
8535
+ "type": "string",
8536
+ "description": "Maximum TokenLab price for a structured pricing model."
8537
+ },
8538
+ "has_complex_pricing": {
8539
+ "type": "boolean"
8540
+ }
8541
+ },
8542
+ "required": [
8543
+ "unit",
8544
+ "currency",
8545
+ "has_complex_pricing"
8546
+ ],
8547
+ "additionalProperties": false
8548
+ },
8549
+ "status": {
8550
+ "type": "string",
8551
+ "description": "Public model lifecycle stage."
8552
+ },
8553
+ "latest": {
8554
+ "type": "boolean"
8555
+ },
8556
+ "supported_operations": {
8557
+ "type": "array",
8558
+ "items": {
8559
+ "type": "string"
8560
+ }
8561
+ },
8562
+ "request_endpoint": {
8563
+ "type": "string"
8564
+ },
8565
+ "recommendation": {
8566
+ "type": "object",
8567
+ "properties": {
8568
+ "preferred_rank": {
8569
+ "type": [
8570
+ "number",
8571
+ "null"
8572
+ ]
8573
+ },
8574
+ "success_rate_24h": {
8575
+ "type": [
8576
+ "number",
8577
+ "null"
8578
+ ]
8579
+ },
8580
+ "sample_count_24h": {
8581
+ "type": "integer"
8582
+ },
8583
+ "status": {
8584
+ "type": "string",
8585
+ "enum": [
8586
+ "ready",
8587
+ "insufficient_samples"
8588
+ ]
8589
+ }
8590
+ },
8591
+ "required": [
8592
+ "preferred_rank",
8593
+ "success_rate_24h",
8594
+ "sample_count_24h",
8595
+ "status"
8596
+ ],
8597
+ "additionalProperties": false
8598
+ }
8599
+ },
8600
+ "required": [
8601
+ "id",
8602
+ "provider",
8603
+ "category",
8604
+ "capabilities",
8605
+ "max_input_tokens",
8606
+ "max_output_tokens",
8607
+ "pricing",
8608
+ "status",
8609
+ "latest"
8610
+ ],
8611
+ "additionalProperties": false
8360
8612
  },
8361
8613
  "Model": {
8362
8614
  "type": "object",
@@ -8383,15 +8635,6 @@
8383
8635
  },
8384
8636
  "tokenlab": {
8385
8637
  "$ref": "#/components/schemas/ModelTokenLabExtension"
8386
- },
8387
- "lemondata": {
8388
- "allOf": [
8389
- {
8390
- "$ref": "#/components/schemas/ModelLemondataExtension"
8391
- }
8392
- ],
8393
- "deprecated": true,
8394
- "description": "Deprecated alias for tokenlab. Retained for compatibility during the TokenLab migration."
8395
8638
  }
8396
8639
  },
8397
8640
  "required": [
@@ -9857,87 +10100,6 @@
9857
10100
  }
9858
10101
  }
9859
10102
  },
9860
- "ModelListLemondataExtension": {
9861
- "type": "object",
9862
- "description": "TokenLab discovery fields for the list route. Detail-only metadata such as capability flags, pricing provenance, full model details, and empty recommendation snapshots are omitted.",
9863
- "properties": {
9864
- "aliases": {
9865
- "type": "array",
9866
- "items": {
9867
- "type": "string"
9868
- }
9869
- },
9870
- "pricing": {
9871
- "type": "object",
9872
- "additionalProperties": true
9873
- },
9874
- "capabilities": {
9875
- "type": "array",
9876
- "items": {
9877
- "type": "string"
9878
- }
9879
- },
9880
- "providers": {
9881
- "type": "array",
9882
- "items": {
9883
- "type": "string"
9884
- }
9885
- },
9886
- "max_input_tokens": {
9887
- "type": [
9888
- "number",
9889
- "null"
9890
- ]
9891
- },
9892
- "max_output_tokens": {
9893
- "type": [
9894
- "number",
9895
- "null"
9896
- ]
9897
- },
9898
- "category": {
9899
- "type": "string"
9900
- },
9901
- "pricing_unit": {
9902
- "type": "string"
9903
- },
9904
- "cache_pricing": {
9905
- "type": [
9906
- "object",
9907
- "null"
9908
- ],
9909
- "additionalProperties": true
9910
- },
9911
- "has_complex_pricing": {
9912
- "type": "boolean"
9913
- },
9914
- "pricing_summary": {
9915
- "type": [
9916
- "object",
9917
- "null"
9918
- ],
9919
- "additionalProperties": true
9920
- },
9921
- "agent_preferences": {
9922
- "type": "object",
9923
- "additionalProperties": true
9924
- },
9925
- "request_format_summary": {
9926
- "$ref": "#/components/schemas/ModelListRequestFormatSummary"
9927
- }
9928
- },
9929
- "required": [
9930
- "aliases",
9931
- "pricing",
9932
- "capabilities",
9933
- "max_input_tokens",
9934
- "max_output_tokens",
9935
- "category",
9936
- "pricing_unit",
9937
- "has_complex_pricing"
9938
- ],
9939
- "additionalProperties": false
9940
- },
9941
10103
  "ModelListItem": {
9942
10104
  "type": "object",
9943
10105
  "properties": {
@@ -9961,15 +10123,6 @@
9961
10123
  "description": "Model provider",
9962
10124
  "example": "openai"
9963
10125
  },
9964
- "lemondata": {
9965
- "allOf": [
9966
- {
9967
- "$ref": "#/components/schemas/ModelListLemondataExtension"
9968
- }
9969
- ],
9970
- "deprecated": true,
9971
- "description": "Deprecated alias for tokenlab. Retained for compatibility during the TokenLab migration."
9972
- },
9973
10126
  "tokenlab": {
9974
10127
  "$ref": "#/components/schemas/ModelListTokenLabExtension"
9975
10128
  }
@@ -9983,89 +10136,6 @@
9983
10136
  ],
9984
10137
  "additionalProperties": false
9985
10138
  },
9986
- "ModelLemondataExtension": {
9987
- "type": "object",
9988
- "description": "TokenLab extension fields for the detail route, including pricing, capabilities, recommendation metadata, and detailed non-chat request metadata.",
9989
- "properties": {
9990
- "aliases": {
9991
- "type": "array",
9992
- "items": {
9993
- "type": "string"
9994
- }
9995
- },
9996
- "pricing": {
9997
- "type": "object",
9998
- "additionalProperties": true
9999
- },
10000
- "capabilities": {
10001
- "type": "array",
10002
- "items": {
10003
- "type": "string"
10004
- }
10005
- },
10006
- "providers": {
10007
- "type": "array",
10008
- "items": {
10009
- "type": "string"
10010
- }
10011
- },
10012
- "max_input_tokens": {
10013
- "type": [
10014
- "number",
10015
- "null"
10016
- ]
10017
- },
10018
- "max_output_tokens": {
10019
- "type": [
10020
- "number",
10021
- "null"
10022
- ]
10023
- },
10024
- "category": {
10025
- "type": "string"
10026
- },
10027
- "pricing_unit": {
10028
- "type": "string"
10029
- },
10030
- "cache_pricing": {
10031
- "type": [
10032
- "object",
10033
- "null"
10034
- ],
10035
- "additionalProperties": true
10036
- },
10037
- "has_complex_pricing": {
10038
- "type": "boolean"
10039
- },
10040
- "supported_operations": {
10041
- "type": "array",
10042
- "items": {
10043
- "type": "string"
10044
- }
10045
- },
10046
- "pricing_summary": {
10047
- "type": [
10048
- "object",
10049
- "null"
10050
- ],
10051
- "additionalProperties": true
10052
- },
10053
- "pricing_provenance": {
10054
- "type": [
10055
- "object",
10056
- "null"
10057
- ],
10058
- "additionalProperties": true
10059
- },
10060
- "request_format_summary": {
10061
- "$ref": "#/components/schemas/NonChatRequestFormatSummary"
10062
- },
10063
- "request_format_details": {
10064
- "$ref": "#/components/schemas/NonChatRequestFormatDetails"
10065
- }
10066
- },
10067
- "additionalProperties": true
10068
- },
10069
10139
  "ModelPricingResponse": {
10070
10140
  "type": "object",
10071
10141
  "properties": {
@@ -11811,6 +11881,81 @@
11811
11881
  },
11812
11882
  "additionalProperties": false
11813
11883
  },
11884
+ "NonChatOperationConstraint": {
11885
+ "type": "object",
11886
+ "properties": {
11887
+ "operation": {
11888
+ "type": "string"
11889
+ },
11890
+ "request_endpoint": {
11891
+ "type": [
11892
+ "string",
11893
+ "null"
11894
+ ]
11895
+ },
11896
+ "request_shape_mode": {
11897
+ "type": [
11898
+ "string",
11899
+ "null"
11900
+ ]
11901
+ },
11902
+ "status_mode": {
11903
+ "type": [
11904
+ "string",
11905
+ "null"
11906
+ ]
11907
+ },
11908
+ "supported_parameters": {
11909
+ "type": "array",
11910
+ "items": {
11911
+ "type": "string"
11912
+ }
11913
+ },
11914
+ "required_selectors": {
11915
+ "type": "array",
11916
+ "items": {
11917
+ "type": "string"
11918
+ }
11919
+ },
11920
+ "optional_selectors": {
11921
+ "type": "array",
11922
+ "items": {
11923
+ "type": "string"
11924
+ }
11925
+ },
11926
+ "documented_inputs": {
11927
+ "type": "array",
11928
+ "items": {
11929
+ "type": "string"
11930
+ }
11931
+ },
11932
+ "allowed_resolutions": {
11933
+ "type": "array",
11934
+ "items": {
11935
+ "type": "string"
11936
+ }
11937
+ },
11938
+ "allowed_durations": {
11939
+ "type": "array",
11940
+ "items": {
11941
+ "type": "string"
11942
+ }
11943
+ },
11944
+ "allowed_aspect_ratios": {
11945
+ "type": "array",
11946
+ "items": {
11947
+ "type": "string"
11948
+ }
11949
+ },
11950
+ "notes": {
11951
+ "type": "array",
11952
+ "items": {
11953
+ "type": "string"
11954
+ }
11955
+ }
11956
+ },
11957
+ "additionalProperties": false
11958
+ },
11814
11959
  "NonChatRequestFormatSummary": {
11815
11960
  "type": [
11816
11961
  "object",
@@ -11829,6 +11974,54 @@
11829
11974
  "type": "string"
11830
11975
  }
11831
11976
  },
11977
+ "feature_flags": {
11978
+ "type": "object",
11979
+ "additionalProperties": {
11980
+ "type": "boolean"
11981
+ }
11982
+ },
11983
+ "output_formats": {
11984
+ "type": "array",
11985
+ "items": {
11986
+ "type": "string"
11987
+ }
11988
+ },
11989
+ "service_limits": {
11990
+ "type": [
11991
+ "object",
11992
+ "null"
11993
+ ],
11994
+ "properties": {
11995
+ "online_rpm": {
11996
+ "type": [
11997
+ "number",
11998
+ "null"
11999
+ ]
12000
+ },
12001
+ "concurrency": {
12002
+ "type": [
12003
+ "number",
12004
+ "null"
12005
+ ]
12006
+ },
12007
+ "offline_inference": {
12008
+ "type": "boolean"
12009
+ },
12010
+ "offline_tpd": {
12011
+ "type": [
12012
+ "string",
12013
+ "null"
12014
+ ]
12015
+ },
12016
+ "prompt_max_characters": {
12017
+ "type": [
12018
+ "number",
12019
+ "null"
12020
+ ]
12021
+ }
12022
+ },
12023
+ "additionalProperties": false
12024
+ },
11832
12025
  "required_selectors": {
11833
12026
  "type": "array",
11834
12027
  "items": {
@@ -11847,18 +12040,36 @@
11847
12040
  "type": "string"
11848
12041
  }
11849
12042
  },
12043
+ "resolutions_label": {
12044
+ "type": [
12045
+ "string",
12046
+ "null"
12047
+ ]
12048
+ },
11850
12049
  "durations": {
11851
12050
  "type": "array",
11852
12051
  "items": {
11853
12052
  "type": "string"
11854
12053
  }
11855
12054
  },
12055
+ "durations_label": {
12056
+ "type": [
12057
+ "string",
12058
+ "null"
12059
+ ]
12060
+ },
11856
12061
  "aspect_ratios": {
11857
12062
  "type": "array",
11858
12063
  "items": {
11859
12064
  "type": "string"
11860
12065
  }
11861
12066
  },
12067
+ "aspect_ratios_label": {
12068
+ "type": [
12069
+ "string",
12070
+ "null"
12071
+ ]
12072
+ },
11862
12073
  "request_endpoint": {
11863
12074
  "type": [
11864
12075
  "string",
@@ -11871,6 +12082,12 @@
11871
12082
  "null"
11872
12083
  ]
11873
12084
  },
12085
+ "request_shape_mode": {
12086
+ "type": [
12087
+ "string",
12088
+ "null"
12089
+ ]
12090
+ },
11874
12091
  "recommended_request_summary": {
11875
12092
  "type": [
11876
12093
  "object",
@@ -11886,6 +12103,12 @@
11886
12103
  "null"
11887
12104
  ]
11888
12105
  }
12106
+ },
12107
+ "operation_constraints": {
12108
+ "type": "array",
12109
+ "items": {
12110
+ "$ref": "#/components/schemas/NonChatOperationConstraint"
12111
+ }
11889
12112
  }
11890
12113
  },
11891
12114
  "additionalProperties": true
@@ -5,7 +5,7 @@
5
5
  "id": "tokenlab-mcp-server",
6
6
  "name": "@tokenlabai/mcp-server",
7
7
  "title": "TokenLab MCP Server",
8
- "version": "0.5.0",
8
+ "version": "0.6.1",
9
9
  "registry_name": "io.github.hedging8563/tokenlab",
10
10
  "source_url": "https://github.com/hedging8563/tokenlab-mcp-server",
11
11
  "landing_url": "https://tokenlab.sh/mcp",
@@ -25,8 +25,8 @@
25
25
  "openapi": "3.0.3",
26
26
  "title": "TokenLab AI Gateway",
27
27
  "version": "1.0.0",
28
- "sha256": "f494fcfb2b4d67aaddc88a2ec164739c807bb59331a7e5270fd9d9fa282745e0",
29
- "tool_manifest_sha256": "a2690dd92f5e7dbc47ce4fe25b327eaafd4848224f0e329bee0f1c2797c4521d"
28
+ "sha256": "1b60d2976d994b4007a17984d9aa4ad4c11d791fb4e8096e1f86144bcee366f1",
29
+ "tool_manifest_sha256": "6647f8fbec7a80e4588640d9582a2931ba5fd675b3c01589ae6e833c0fdf6d69"
30
30
  },
31
31
  "profiles": {
32
32
  "catalog": {
@@ -242,6 +242,19 @@
242
242
  "features": {
243
243
  "structured_content": true,
244
244
  "tool_annotations": true,
245
+ "live_model_contract": {
246
+ "tool": "get_model",
247
+ "endpoint": "/v1/models/{model}",
248
+ "fields": [
249
+ "supported_operations",
250
+ "supported_parameters",
251
+ "request_endpoint",
252
+ "request_endpoint_by_operation",
253
+ "request_shape_mode",
254
+ "operation_constraints",
255
+ "recommended_request"
256
+ ]
257
+ },
245
258
  "composite_tools": [
246
259
  {
247
260
  "name": "compare_models",
@@ -6,7 +6,7 @@
6
6
  "openapi": "3.0.3",
7
7
  "title": "TokenLab AI Gateway",
8
8
  "version": "1.0.0",
9
- "sha256": "f494fcfb2b4d67aaddc88a2ec164739c807bb59331a7e5270fd9d9fa282745e0"
9
+ "sha256": "1b60d2976d994b4007a17984d9aa4ad4c11d791fb4e8096e1f86144bcee366f1"
10
10
  },
11
11
  "default_profile": "core",
12
12
  "profiles": [
@@ -2255,21 +2255,11 @@
2255
2255
  },
2256
2256
  "size": {
2257
2257
  "type": "string",
2258
- "default": "1024x1024",
2259
- "description": "Image size. For gpt-image-2, use auto or WIDTHxHEIGHT; custom dimensions must both be multiples of 16, longest edge <= 3840px, long/short ratio <= 3:1, and total pixels between 655,360 and 8,294,400."
2258
+ "description": "Image size. Defaults are model-specific. For gpt-image-2, omit this field or use auto for automatic sizing, or send WIDTHxHEIGHT; custom dimensions must both be multiples of 16, longest edge <= 3840px, long/short ratio <= 3:1, and total pixels between 655,360 and 8,294,400."
2260
2259
  },
2261
2260
  "quality": {
2262
2261
  "type": "string",
2263
- "enum": [
2264
- "standard",
2265
- "hd",
2266
- "auto",
2267
- "low",
2268
- "medium",
2269
- "high"
2270
- ],
2271
- "default": "standard",
2272
- "description": "Image quality. GPT Image models such as gpt-image-2 use auto/low/medium/high. Other image families may use provider-specific values."
2262
+ "description": "Image quality. Defaults and accepted values are model-specific. For gpt-image-2, omit this field or use auto for automatic quality, or send low, medium, or high. Other image families may use provider-specific values."
2273
2263
  },
2274
2264
  "style": {
2275
2265
  "type": "string",
@@ -5283,7 +5273,7 @@
5283
5273
  "core",
5284
5274
  "full"
5285
5275
  ],
5286
- "description": "Get model Retrieves a model instance, providing basic information about the model.",
5276
+ "description": "Get model Retrieves current model details, including supported operations, request parameters, request endpoints, selector limits, and pricing when available. Non-chat integrations should read these current model-specific request details before creating a request.",
5287
5277
  "input_schema": {
5288
5278
  "type": "object",
5289
5279
  "properties": {
@@ -6054,19 +6044,78 @@
6054
6044
  "core",
6055
6045
  "full"
6056
6046
  ],
6057
- "description": "List models Lists the currently available models. Default responses are trimmed for discovery. Non-chat models may include lightweight request-format metadata; `agent_preferences` appears only when `recommended_for` is present. Deprecated `lemondata` is still returned as a compatibility alias during the migration.",
6047
+ "description": "List models Lists the currently available models. Use `view=compact` for model selection and `view=full` for the existing OpenAI-compatible discovery shape. Native API calls default to `full`; integrations may choose `compact` as their default. Non-chat recommendations are available through `recommended_for`.",
6058
6048
  "input_schema": {
6059
6049
  "type": "object",
6060
- "properties": {},
6050
+ "properties": {
6051
+ "provider": {
6052
+ "type": "string",
6053
+ "description": "Filter by public model provider, for example openai, anthropic, google, or minimax."
6054
+ },
6055
+ "tag": {
6056
+ "type": "string",
6057
+ "description": "Filter by a public capability tag."
6058
+ },
6059
+ "category": {
6060
+ "type": "string",
6061
+ "enum": [
6062
+ "chat",
6063
+ "embedding",
6064
+ "translation",
6065
+ "image",
6066
+ "video",
6067
+ "audio",
6068
+ "tts",
6069
+ "stt",
6070
+ "rerank",
6071
+ "3d",
6072
+ "music"
6073
+ ],
6074
+ "description": "Filter by model category."
6075
+ },
6076
+ "recommended_for": {
6077
+ "type": "string",
6078
+ "enum": [
6079
+ "image",
6080
+ "video",
6081
+ "music",
6082
+ "3d",
6083
+ "tts",
6084
+ "stt",
6085
+ "embedding",
6086
+ "rerank",
6087
+ "translation"
6088
+ ],
6089
+ "description": "Sort supported non-chat models for a task category and include recommendation evidence."
6090
+ },
6091
+ "view": {
6092
+ "type": "string",
6093
+ "enum": [
6094
+ "compact",
6095
+ "full"
6096
+ ],
6097
+ "default": "compact",
6098
+ "description": "Compact model-selection output is the MCP default. Set view to full only when the complete OpenAI-compatible list shape is required."
6099
+ }
6100
+ },
6061
6101
  "additionalProperties": false
6062
6102
  },
6063
6103
  "bindings": {
6064
6104
  "path": [],
6065
- "query": [],
6105
+ "query": [
6106
+ "provider",
6107
+ "tag",
6108
+ "category",
6109
+ "recommended_for",
6110
+ "view"
6111
+ ],
6066
6112
  "header": [],
6067
6113
  "body": [],
6068
6114
  "files": []
6069
6115
  },
6116
+ "default_arguments": {
6117
+ "view": "compact"
6118
+ },
6070
6119
  "annotations": {
6071
6120
  "readOnlyHint": true,
6072
6121
  "destructiveHint": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenlabai/mcp-server",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "OpenAPI-generated TokenLab MCP server with catalog, native AI, multimodal, resource, prompt, and async task support.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -25,6 +25,7 @@
25
25
  "contract:generate": "node ./scripts/generate-contract.mjs",
26
26
  "contract:check": "node ./scripts/generate-contract.mjs --check",
27
27
  "contract:sync": "node ./scripts/sync-contract.mjs",
28
+ "version": "node ./scripts/sync-version.mjs && npm run contract:generate",
28
29
  "test": "node --check ./src/index.js && node --check ./scripts/generate-contract.mjs && npm run contract:check && node --test"
29
30
  },
30
31
  "keywords": [
@@ -216,6 +216,17 @@ function applyInputOverrides(schema, bindings, override) {
216
216
  if (!schema.properties[name]) throw new Error(`Cannot override unknown MCP argument: ${name}`);
217
217
  schema.properties[name] = { ...schema.properties[name], ...patch };
218
218
  }
219
+ for (const [name, value] of Object.entries(override.default_arguments || {})) {
220
+ if (!schema.properties[name]) throw new Error(`Cannot default unknown MCP argument: ${name}`);
221
+ const property = schema.properties[name];
222
+ if (Array.isArray(property.enum) && !property.enum.includes(value)) {
223
+ throw new Error(`Default MCP argument ${name} is outside its enum`);
224
+ }
225
+ if (Object.hasOwn(property, "const") && property.const !== value) {
226
+ throw new Error(`Default MCP argument ${name} does not match its const value`);
227
+ }
228
+ schema.properties[name] = { ...schema.properties[name], default: value };
229
+ }
219
230
  }
220
231
 
221
232
  function annotations(method) {
@@ -262,6 +273,7 @@ for (const [operationId, indexed] of operations) {
262
273
  description,
263
274
  input_schema: schema,
264
275
  bindings,
276
+ ...(override.default_arguments ? { default_arguments: override.default_arguments } : {}),
265
277
  annotations: { ...annotations(indexed.method), ...(override.annotations || {}) },
266
278
  ...(override.task ? { task: override.task } : {})
267
279
  });
@@ -302,6 +314,17 @@ for (const tool of compositeTools) {
302
314
  }
303
315
  }
304
316
 
317
+ const liveModelContract = publicConfig.live_model_contract;
318
+ if (!liveModelContract || liveModelContract.tool !== "get_model" || liveModelContract.endpoint !== "/v1/models/{model}") {
319
+ throw new Error("MCP public contract must use get_model as its live model-contract source");
320
+ }
321
+ if (!Array.isArray(liveModelContract.fields) || liveModelContract.fields.length === 0) {
322
+ throw new Error("MCP live model contract must list its public fields");
323
+ }
324
+ if (new Set(liveModelContract.fields).size !== liveModelContract.fields.length) {
325
+ throw new Error("MCP live model contract fields contain duplicates");
326
+ }
327
+
305
328
  const profiles = Object.fromEntries(profileEntries.map(([profileName]) => {
306
329
  const endpointTools = tools.filter((tool) => tool.profiles.includes(profileName)).map((tool) => tool.name);
307
330
  const composite = compositeTools.filter((tool) => tool.profiles.includes(profileName)).map((tool) => tool.name);
@@ -361,6 +384,7 @@ const publicContract = {
361
384
  features: {
362
385
  structured_content: true,
363
386
  tool_annotations: true,
387
+ live_model_contract: liveModelContract,
364
388
  composite_tools: compositeTools,
365
389
  async_delivery_tools: tools.filter((tool) => tool.task).map((tool) => tool.name),
366
390
  resources: publicConfig.resources || [],
package/src/index.js CHANGED
@@ -109,12 +109,14 @@ async function appendMultipart(form, name, value, isFile) {
109
109
  }
110
110
 
111
111
  function collectArguments(tool, input) {
112
- const pathArguments = Object.fromEntries(tool.bindings.path.map((name) => [name, input[name]]));
113
- const queryArguments = Object.fromEntries(tool.bindings.query.map((name) => [name, input[name]]));
114
- const headerArguments = Object.fromEntries(tool.bindings.header.map((name) => [name, input[name]]));
112
+ const resolvedInput = { ...(tool.default_arguments || {}), ...input };
113
+
114
+ const pathArguments = Object.fromEntries(tool.bindings.path.map((name) => [name, resolvedInput[name]]));
115
+ const queryArguments = Object.fromEntries(tool.bindings.query.map((name) => [name, resolvedInput[name]]));
116
+ const headerArguments = Object.fromEntries(tool.bindings.header.map((name) => [name, resolvedInput[name]]));
115
117
  const bodyArguments = tool.bindings.body.includes("body")
116
- ? input.body
117
- : Object.fromEntries(tool.bindings.body.map((name) => [name, input[name]]));
118
+ ? resolvedInput.body
119
+ : Object.fromEntries(tool.bindings.body.map((name) => [name, resolvedInput[name]]));
118
120
  return { pathArguments, queryArguments, headerArguments, bodyArguments };
119
121
  }
120
122
 
@@ -291,13 +293,21 @@ server.registerTool(
291
293
  executePublicJson(`/v1/models/${encoded}/pricing`).catch((error) => ({ error: error.message }))
292
294
  ]);
293
295
  if (include_raw) return { model, details, pricing };
296
+ const tokenlab = details?.tokenlab && typeof details.tokenlab === "object" ? details.tokenlab : {};
297
+ const requestContract = tokenlab.request_format_details
298
+ || tokenlab.request_format_summary
299
+ || tokenlab.public_contract
300
+ || tokenlab.public_contract_summary
301
+ || {};
294
302
  return {
295
303
  id: details.id || details.model || model,
296
- request_endpoint: details.request_endpoint,
297
- request_shape_mode: details.request_shape_mode,
298
- supported_operations: details.supported_operations,
299
- supported_parameters: details.supported_parameters,
300
- recommended_request: details.recommended_request,
304
+ request_endpoint: requestContract.request_endpoint,
305
+ request_endpoint_by_operation: requestContract.request_endpoint_by_operation,
306
+ request_shape_mode: requestContract.request_shape_mode,
307
+ supported_operations: tokenlab.supported_operations || requestContract.public_operations,
308
+ supported_parameters: requestContract.supported_parameters,
309
+ operation_constraints: requestContract.operation_constraints,
310
+ recommended_request: requestContract.recommended_request || requestContract.recommended_request_summary,
301
311
  pricing
302
312
  };
303
313
  }));