An MCP server that turns natural language prompts into structured, schema-valid function calls. It uses a local LLM (Qwen/Qwen3-0.6B) with constrained decoding, so the model can only ever produce a registered function name and correctly typed parameters - never broken JSON, hallucinated fields, or wrong types.
{"prompt": "add 23 and 245", "name": "fn_add_numbers", "parameters": {"a": 23, "b": 245}}It runs locally as a stdio process - no networking, no API keys, no account required.
git clone https://github.com/Diogo-Serra/intentCast-mcp.git
cd intentCast-mcp
make installReplace /absolute/path/to/intentCast-mcp with the folder you just
cloned.
Merge this into your config file - do not replace the whole file - then restart Claude Desktop.
| OS | Config file |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"intentcast": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/intentCast-mcp", "python", "-m", "src.server"]
}
}
}Add this to ~/.cursor/mcp.json (%USERPROFILE%\.cursor\mcp.json on
Windows) and restart Cursor:
{
"mcpServers": {
"intentcast": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/intentCast-mcp", "python", "-m", "src.server"]
}
}
}Add this to ~/.copilot/mcp-config.json (or run /mcp add inside
Copilot CLI for an interactive form):
{
"mcpServers": {
"intentcast": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/intentCast-mcp", "python", "-m", "src.server"]
}
}
}Add this to .vscode/mcp.json in your workspace:
{
"servers": {
"intentcast": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/intentCast-mcp", "python", "-m", "src.server"]
}
}
}Once registered, the client starts the server on demand and routes
matching requests to its call_function tool.
Ask your AI client to invoke intentcast explicitly and to return its raw result, for example:
Use intentcast on "24 + 24" and return the result.
By default, a client may compute or paraphrase an answer instead of returning the tool's actual output. Asking to "return the result" makes the tool's exact output reliable.
Expected reply:
{"prompt": "24 + 24", "name": "fn_add_numbers", "parameters": {"a": 24, "b": 24}}call_function resolves intent into a schema-valid function call - it
does not execute it. Pass the returned name and parameters to your
own function dispatcher to get an actual result.
call_function
| Parameter | Default | Description |
|---|---|---|
prompt |
required | Natural-language request to resolve |
Returns the resolved name (matched function), parameters (typed
arguments), and the original prompt.
list_functions() - lists all registered functions with descriptions
and parameter schemas.
Copy the example environment file and adjust as needed:
cp .env.example .env| Variable | Description |
|---|---|
HF_TOKEN |
Optional Hugging Face token, for higher model download rate limits |
INTENTCAST_REGISTRY |
Optional path to a custom function registry JSON file |
Functions are declared in src/data/functions_definition.json:
{
"name": "fn_add_numbers",
"description": "Add two numbers together and return their sum.",
"parameters": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"returns": { "type": "number" }
}Supported parameter types: number, boolean, string.
make run # start the server manually over stdio
make lint # flake8 + mypy
make clean # remove the virtualenvintentCast-mcp/
├── src/
│ ├── server.py # MCP entry point: call_function, list_functions
│ ├── classes/
│ │ ├── config.py # environment configuration, registry path resolution
│ │ ├── constants.py # shared regex constants
│ │ ├── decoder.py # ConstrainedDecoder: token-level constrained generation
│ │ ├── models.py # FunctionDefinition, FunctionCallResult, Vocabulary
│ │ └── resolver.py # IntentResolver: registry loading and prompt resolution
│ ├── data/
│ │ └── functions_definition.json # default function registry
│ └── llm_sdk/
│ └── llm_sdk/__init__.py # Small_LLM_Model: local model wrapper
├── Makefile
├── pyproject.toml
└── .env.example
See CONTRIBUTING.md for setup, coding standards, and the pull request process.
MIT - see LICENSE.