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.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.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.1.tar.gz (35.4 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.1-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mcptune-0.1.1.tar.gz
  • Upload date:
  • Size: 35.4 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.1.tar.gz
Algorithm Hash digest
SHA256 dea981538ce94be26e8fdcc1d5a64ab05eea402fef1f3bdb21af1f7187828517
MD5 6d3cd13b0445a9b9ec7cf16429441767
BLAKE2b-256 3a4b6b5d29678709908dcd5dddafb0a172db49c89ae6328b8d3afefaccc6e280

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mcptune-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 47.2 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 407d68ce21a308b85c83b47728bd31400feea64f9fe68d2b6e72d8af677c7738
MD5 e2300ed5f87659a61c764f31d83f4978
BLAKE2b-256 9563bc1679445f6382a5f82ce1ef70fe73566f7535e8e9fac3435cf2b09c1a30

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