Skip to main content

MCP-based tool-use fine-tuning framework

Project description

MCPTune

Fine-tune a small language model to call a specific MCP server's tools.

CI License: MIT Python

Give MCPTune an MCP server and a base model. It discovers the server's tools, generates a synthetic tool-use dataset, and fine-tunes the model to emit that server's tool calls in a format a runtime can execute. A built-in minimal runtime and evaluation let you measure whether the fine-tune actually worked.

The thesis MCPTune exists to test: small models can be trained to do reliable MCP tool-calling for a specific server, cheaply and locally. This release is the pipeline that produces and measures that - run examples/evaluate.py to get the base-vs-tuned number for your server and model.

Install

pip install mcptune                   # core: discovery, dataset generation, formats
pip install "mcptune[transformers]"   # add LoRA fine-tuning + the runtime model runner

From source (for development):

git clone https://github.com/TomasrRodrigues/mcptune
cd mcptune
pip install -e ".[dev]"

How it works

discover → sample args → synthesize intent → execute → synthesize answer → train → evaluate
adapter    sampling        synthesis        runtime      synthesis       LoRA      runtime

The model only ever emits a tool-call request as text. A runtime parses it, executes it against the MCP server, and feeds the result back. MCPTune trains the model to emit those requests well; the orchestration runtime is a separate concern (this repo ships a minimal one for evaluation and demos; production deployments use an MCP-aware framework).

Quickstart

import asyncio
from fastmcp import FastMCP
from mcptune import MCPTune

server = FastMCP("demo")

@server.tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"Sunny and 22C in {city}"

async def main():
    tuner = MCPTune(
        model="Qwen/Qwen2.5-1.5B-Instruct",
        mcpserver=server,
        llm_backend="ollama",        # natural intents + arguments (needs Ollama)
        llm_model="qwen2.5:3b",
        seed=42,
    )
    tools = await tuner.adapter.discover()
    dataset = tuner.build_dataset(tools, samples_per_tool=8)   # sample + intent (offline)
    dataset = await tuner.execute(dataset)                     # tool results + final answers

    for row in dataset[:3]:
        print(f"{row.user_intent}  ->  {row.tool_name}({row.arguments})")

asyncio.run(main())

Fine-tune on the dataset (needs mcptune[transformers]):

from mcptune.training.backends.transformers_backend import TransformersTrainerBackend

tuner = MCPTune(
    model="Qwen/Qwen2.5-1.5B-Instruct",
    mcpserver=server,
    llm_backend="ollama", llm_model="qwen2.5:3b",
    trainer=TransformersTrainerBackend(output_dir="./checkpoints"),
    seed=42,
)
tools = await tuner.adapter.discover()
dataset = await tuner.execute(tuner.build_dataset(tools, samples_per_tool=20))
trained = tuner.train(dataset, config={"epochs": 1})

Then measure base vs tuned with examples/evaluate.py, or run the model against your server through the minimal runtime with examples/run_agent.py.

What's in 0.1.0

Capability Status
Tool discovery + JSONSchema fidelity (FastMCP)
Structural + semantic argument sampling (seeded)
Intent synthesis (template / Ollama / transformers)
Native tool-use training format + SFT masking
Tool execution + answer synthesis (full loop)
LoRA fine-tuning (transformers + PEFT)
Minimal runtime + before/after evaluation
stdio / HTTP adapters 🚧 planned
Full evaluation pipeline, forward-mode generation 🚧 0.2.0
Production runtime, multi-turn, personas 🚧 1.0.0

Documentation

Supported models

Native tool-call emission targets Qwen (<tool_call>) first. Other open-weight families with tool-aware chat templates (Llama 3.1+, Mistral) need a parser entry in mcptune.runtime.parsing. MCPTune fine-tunes open-weight models only - it does not train closed APIs.

Contributing

See CONTRIBUTING.md for the workflow and architectural constraints. Issues are tracked by milestone (0.1.x, 0.2.0, 1.0.0).

License

MIT - see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcptune-0.1.2.tar.gz (36.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcptune-0.1.2-py3-none-any.whl (49.8 kB view details)

Uploaded Python 3

File details

Details for the file mcptune-0.1.2.tar.gz.

File metadata

  • Download URL: mcptune-0.1.2.tar.gz
  • Upload date:
  • Size: 36.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for mcptune-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d39094595bd13069625d880a62717257ac75618f9723f54390bfc6c9afed7d2d
MD5 4968b6355ec033a671b7f6626c0654cc
BLAKE2b-256 13113031417bf8130f5ab80e2939dcd7b75c9162d0b8501f2d56ed49bd3a9e51

See more details on using hashes here.

File details

Details for the file mcptune-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: mcptune-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 49.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for mcptune-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 af6d855fb40d79d1ccdccf05277ddcf8a02701677376ee7a13d6352dcef805d4
MD5 18ad13501ed910665ba8a2afd1d74511
BLAKE2b-256 034e3e7a1f2f0a8f0aade3bbb3503346cdea72aa801309199b134de04ca5830c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page