// catalog/

Every capability, on every surface.

ToolForte does one kind of thing: it takes a question with a definite answer (is this IBAN well formed, what is the VAT on this amount, what does this YAML look like as JSON) and answers it exactly. This page lists every such capability once, and shows the three ways to ask it.

In your browser

149 of these have a page under /tools. Free, and the work happens on your own device.

From your own code

All 150 answer at POST /api/v1/tools/<id> with a key from /developers. A GET on the same address describes the tool.

From an AI assistant

All 150 are tools on the MCP server at https://toolforte.com/api/mcp, so Claude, ChatGPT, Cursor and others can call them. Setup is on /mcp.

Any of these can also be a step in a workflow, where the answer of one becomes the input of the next. Open an entry below for the fields it takes, an example you can copy, and what comes back.

Text

Text Diffpagetext-difftext_diff1 credit a call

Compare two texts line by line and return which lines were added, removed or left alone, with counts.

What it takes

original
string
The text you are comparing against, the before side.
e.g. one two three
modified
string
The text to compare, the after side.
e.g. one two point five three

What comes back

{
  "ok": true,
  "data": {
    "lines": [
      {
        "type": "unchanged",
        "text": "one",
        "lineNum": {
          "left": 1,
          "right": 1
        }
      }
    ],
    "stats": {
      "added": 1,
      "removed": 1,
      "unchanged": 2
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool text_diff (Text Diff) with original: one
two
three, modified: one
two point five
three.

The assistant then makes this tool call:

{
  "name": "text_diff",
  "arguments": {
    "original": "one\ntwo\nthree",
    "modified": "one\ntwo point five\nthree"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/text-diff \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"original":"one\ntwo\nthree","modified":"one\ntwo point five\nthree"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/text-diff", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "original": "one\ntwo\nthree",
    "modified": "one\ntwo point five\nthree"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/text-diff",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"original":"one\ntwo\nthree","modified":"one\ntwo point five\nthree"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/text-diff · Page: /tools/diff-checker

Markdown to HTMLpagemarkdown-to-htmlmarkdown_to_html1 credit a call

Convert Markdown to sanitized HTML, including GitHub tables, code blocks and task lists.

What it takes

markdown
string
The Markdown source to convert.
e.g. # Hello This is **bold** text.

What comes back

{
  "ok": true,
  "data": {
    "html": "<h1>Hello</h1>\n<p>This is <strong>bold</strong> text.</p>"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool markdown_to_html (Markdown to HTML) with markdown: # Hello

This is **bold** text..

The assistant then makes this tool call:

{
  "name": "markdown_to_html",
  "arguments": {
    "markdown": "# Hello\n\nThis is **bold** text."
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/markdown-to-html \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"markdown":"# Hello\n\nThis is **bold** text."}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/markdown-to-html", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "markdown": "# Hello\n\nThis is **bold** text."
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/markdown-to-html",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"markdown":"# Hello\n\nThis is **bold** text."},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/markdown-to-html · Page: /tools/markdown-to-html

Word Counterpageword-countercount_words1 credit a call

Count words, characters, sentences and paragraphs in a text, with reading time and top keywords.

What it takes

text
string
The text to measure, at most 500,000 characters.
e.g. The quick brown fox jumps over the lazy dog.

What comes back

{
  "ok": true,
  "data": {
    "words": 9,
    "characters": 44,
    "sentences": 1,
    "readingTimeMinutes": 1
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool count_words (Word) with text: The quick brown fox jumps over the lazy dog..

The assistant then makes this tool call:

{
  "name": "count_words",
  "arguments": {
    "text": "The quick brown fox jumps over the lazy dog."
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/word-counter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"The quick brown fox jumps over the lazy dog."}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/word-counter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "The quick brown fox jumps over the lazy dog."
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/word-counter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"The quick brown fox jumps over the lazy dog."},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/word-counter · Page: /tools/word-counter

Slug Generatorpageslug-generatorgenerate_slug1 credit a call

Turn any text into a URL-safe slug, folding diacritics and stripping punctuation.

What it takes

text
string
The text to turn into a slug, such as a page title.
e.g. Hello World! This is a Test.
separator?
string
What to join words with. Defaults to "-".
e.g. -
lowercase?
boolean
Lower-case the result. Defaults to true.
e.g. true
max_length?
number
Cut the slug at this length. 0, the default, means no cut.
e.g. 0

What comes back

{
  "ok": true,
  "data": {
    "slug": "hello-world-this-is-a-test",
    "originalLength": 27,
    "slugLength": 26
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_slug (Slug) with text: Hello World! This is a Test., separator: -, lowercase: true, max_length: 0.

The assistant then makes this tool call:

{
  "name": "generate_slug",
  "arguments": {
    "text": "Hello World! This is a Test.",
    "separator": "-",
    "lowercase": true,
    "max_length": 0
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/slug-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello World! This is a Test.","separator":"-","lowercase":true,"max_length":0}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/slug-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "Hello World! This is a Test.",
    "separator": "-",
    "lowercase": true,
    "max_length": 0
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/slug-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"Hello World! This is a Test.","separator":"-","lowercase":true,"max_length":0},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/slug-generator · Page: /tools/slug-generator

Text Case Converterpagetext-case-converterconvert_case1 credit a call

Convert a text to one case style: upper, lower, title, sentence, camel, pascal, snake or kebab. Returns the converted string.

What it takes

text
string
The text to convert.
e.g. hello world from ToolForte
mode
string
The target case: "upper", "lower", "title", "sentence", "camel", "pascal", "snake" or "kebab".
e.g. snake

What comes back

{
  "ok": true,
  "data": {
    "result": "hello_world_from_tool_forte",
    "mode": "snake"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_case (Text Case) with text: hello world from ToolForte, mode: snake.

The assistant then makes this tool call:

{
  "name": "convert_case",
  "arguments": {
    "text": "hello world from ToolForte",
    "mode": "snake"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/text-case-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"hello world from ToolForte","mode":"snake"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/text-case-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "hello world from ToolForte",
    "mode": "snake"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/text-case-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"hello world from ToolForte","mode":"snake"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/text-case-converter · Page: /tools/text-case-converter

Sort Linespagesort-linessort_lines1 credit a call

Sort the lines of a text A to Z, Z to A, by length, in natural numeric order, or shuffle them with a seed. Can drop duplicates and ignore case. Returns the sorted text and line count.

What it takes

text
string
The text to sort, one item per line.
e.g. banana apple Cherry item10 item2
mode?
string
"az" (default), "za", "length", "natural" (item2 before item10) or "random".
e.g. natural
caseInsensitive?
boolean
Treat Apple and apple as equal. Defaults to true.
e.g. true
removeDuplicates?
boolean
Keep only the first of identical lines. Defaults to false.
e.g. false
reverse?
boolean
Flip the result after sorting. Defaults to false.
e.g. false
seed?
number
Only used by random mode. Defaults to 1.
e.g. 1

What comes back

{
  "ok": true,
  "data": {
    "result": "apple\nbanana\nCherry\nitem2\nitem10",
    "mode": "natural",
    "lines": 5,
    "removedDuplicates": 0
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool sort_lines (Sort Lines) with text: banana
apple
Cherry
item10
item2, mode: natural, caseInsensitive: true, removeDuplicates: false, reverse: false, seed: 1.

The assistant then makes this tool call:

{
  "name": "sort_lines",
  "arguments": {
    "text": "banana\napple\nCherry\nitem10\nitem2",
    "mode": "natural",
    "caseInsensitive": true,
    "removeDuplicates": false,
    "reverse": false,
    "seed": 1
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/sort-lines \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"banana\napple\nCherry\nitem10\nitem2","mode":"natural","caseInsensitive":true,"removeDuplicates":false,"reverse":false,"seed":1}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/sort-lines", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "banana\napple\nCherry\nitem10\nitem2",
    "mode": "natural",
    "caseInsensitive": true,
    "removeDuplicates": false,
    "reverse": false,
    "seed": 1
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/sort-lines",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"banana\napple\nCherry\nitem10\nitem2","mode":"natural","caseInsensitive":true,"removeDuplicates":false,"reverse":false,"seed":1},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/sort-lines · Page: /tools/sort-lines

Remove Duplicate Linespageremove-duplicate-linesdedupe_lines1 credit a call

Remove repeated lines from a text while keeping the original order. Returns the cleaned text with how many lines were removed.

What it takes

text
string
The text to deduplicate, one item per line.
e.g. apple banana apple banana cherry
caseInsensitive?
boolean
Apple and apple count as the same line. Defaults to false.
e.g. false
trim?
boolean
Compare with surrounding spaces removed, output keeps the line as is. Defaults to true.
e.g. true
keepFirst?
boolean
Keep the first copy of a line (true, default) or the last one (false).
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "result": "apple\nbanana\ncherry",
    "total": 5,
    "kept": 3,
    "removed": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dedupe_lines (Remove Duplicate Lines) with text: apple
banana
apple
 banana
cherry, caseInsensitive: false, trim: true, keepFirst: true.

The assistant then makes this tool call:

{
  "name": "dedupe_lines",
  "arguments": {
    "text": "apple\nbanana\napple\n banana\ncherry",
    "caseInsensitive": false,
    "trim": true,
    "keepFirst": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/remove-duplicate-lines \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"apple\nbanana\napple\n banana\ncherry","caseInsensitive":false,"trim":true,"keepFirst":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/remove-duplicate-lines", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "apple\nbanana\napple\n banana\ncherry",
    "caseInsensitive": false,
    "trim": true,
    "keepFirst": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/remove-duplicate-lines",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"apple\nbanana\napple\n banana\ncherry","caseInsensitive":false,"trim":true,"keepFirst":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/remove-duplicate-lines · Page: /tools/remove-duplicate-lines

Reverse Textpagereverse-textreverse_text1 credit a call

Reverse a text by characters, by word order per line, or by the characters of each line. Returns the reversed string.

What it takes

text
string
The text to reverse.
e.g. one two three
mode?
string
"characters" (default, hello becomes olleh), "words" (one two becomes two one) or "lines" (each line flipped separately).
e.g. words

What comes back

{
  "ok": true,
  "data": {
    "result": "three two one",
    "mode": "words"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool reverse_text (Reverse Text) with text: one two three, mode: words.

The assistant then makes this tool call:

{
  "name": "reverse_text",
  "arguments": {
    "text": "one two three",
    "mode": "words"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/reverse-text \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"one two three","mode":"words"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/reverse-text", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "one two three",
    "mode": "words"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/reverse-text",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"one two three","mode":"words"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/reverse-text · Page: /tools/reverse-text

Find and Replacepagefind-and-replacefind_and_replace1 credit a call

Replace every occurrence of a string or regular expression in a text. Supports case sensitivity, whole word matching and regex groups in the replacement. Returns the new text and the number of replacements.

What it takes

text
string
The text to search through.
e.g. The cat sat on the mat with another cat.
find
string
What to look for, plain text or a regex when useRegex is true.
e.g. cat
replace?
string
The replacement. In regex mode $1 and $& work. Defaults to empty, which deletes matches.
e.g. dog
caseSensitive?
boolean
Match Cat and cat separately. Defaults to false.
e.g. false
wholeWord?
boolean
Skip matches inside longer words. Defaults to false.
e.g. true
useRegex?
boolean
Read find as a regular expression. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "result": "The dog sat on the mat with another dog.",
    "count": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool find_and_replace (Find and Replace) with text: The cat sat on the mat with another cat., find: cat, replace: dog, caseSensitive: false, wholeWord: true, useRegex: false.

The assistant then makes this tool call:

{
  "name": "find_and_replace",
  "arguments": {
    "text": "The cat sat on the mat with another cat.",
    "find": "cat",
    "replace": "dog",
    "caseSensitive": false,
    "wholeWord": true,
    "useRegex": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/find-and-replace \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"The cat sat on the mat with another cat.","find":"cat","replace":"dog","caseSensitive":false,"wholeWord":true,"useRegex":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/find-and-replace", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "The cat sat on the mat with another cat.",
    "find": "cat",
    "replace": "dog",
    "caseSensitive": false,
    "wholeWord": true,
    "useRegex": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/find-and-replace",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"The cat sat on the mat with another cat.","find":"cat","replace":"dog","caseSensitive":false,"wholeWord":true,"useRegex":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/find-and-replace · Page: /tools/find-and-replace

Word Frequency Counterpageword-frequency-counterword_frequency1 credit a call

Count how often each word occurs in a text and return a ranked table, most frequent first, with counts and percentages. Can ignore case, skip short words and drop common stop words.

What it takes

text
string
The text to count words in.
e.g. the cat and the dog and the bird
ignoreCase?
boolean
Merge The and the. Defaults to true.
e.g. true
minLength?
number
Only count words with at least this many characters, 1 to 20. Defaults to 1.
e.g. 1
excludeStopWords?
boolean
Skip common English filler words. Defaults to false.
e.g. false
limit?
number
Top N words to return, 1 to 1000. Defaults to 100.
e.g. 3

What comes back

{
  "ok": true,
  "data": {
    "words": [
      {
        "rank": 1,
        "word": "the",
        "count": 3,
        "percent": 37.5
      },
      {
        "rank": 2,
        "word": "and",
        "count": 2,
        "percent": 25
      },
      {
        "rank": 3,
        "word": "bird",
        "count": 1,
        "percent": 12.5
      }
    ],
    "totalWords": 8,
    "uniqueWords": 5
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool word_frequency (Word Frequency) with text: the cat and the dog and the bird, ignoreCase: true, minLength: 1, excludeStopWords: false, limit: 3.

The assistant then makes this tool call:

{
  "name": "word_frequency",
  "arguments": {
    "text": "the cat and the dog and the bird",
    "ignoreCase": true,
    "minLength": 1,
    "excludeStopWords": false,
    "limit": 3
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/word-frequency-counter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"the cat and the dog and the bird","ignoreCase":true,"minLength":1,"excludeStopWords":false,"limit":3}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/word-frequency-counter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "the cat and the dog and the bird",
    "ignoreCase": true,
    "minLength": 1,
    "excludeStopWords": false,
    "limit": 3
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/word-frequency-counter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"the cat and the dog and the bird","ignoreCase":true,"minLength":1,"excludeStopWords":false,"limit":3},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/word-frequency-counter · Page: /tools/word-frequency-counter

Reading Time Calculatorpagereading-time-calculatorreading_time1 credit a call

Estimate how long a text takes to read and to speak aloud, from the text itself or a word count, at a chosen words-per-minute plus slow, average and fast presets.

What it takes

text?
string
The text to estimate. Give this or wordCount.
e.g. Knowing how long your content takes to read helps you plan articles, document...
wordCount?
number
Number of words, when you do not have the text itself. Ignored when text is given.
readingWpm?
number
Reading speed, 50 to 1000 words per minute. Defaults to 238, the average adult.
e.g. 238
speakingWpm?
number
Speaking speed, 50 to 500 words per minute. Defaults to 150, normal speech.
e.g. 150

What comes back

{
  "ok": true,
  "data": {
    "wordCount": 23,
    "characters": 135,
    "sentences": 2,
    "reading": {
      "label": "Custom",
      "wpm": 238,
      "minutes": 0.1,
      "time": "< 1 min"
    },
    "speaking": {
      "label": "Custom",
      "wpm": 150,
      "minutes": 0.15,
      "time": "< 1 min"
    },
    "readingPresets": [
      {
        "label": "Slow Reader",
        "wpm": 150,
        "minutes": 0.15,
        "time": "< 1 min"
      }
    ],
    "speakingPresets": [
      {
        "label": "Slow Speech",
        "wpm": 100,
        "minutes": 0.23,
        "time": "< 1 min"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool reading_time (Reading Time) with text: Knowing how long your content takes to read helps you pla..., readingWpm: 238, speakingWpm: 150.

The assistant then makes this tool call:

{
  "name": "reading_time",
  "arguments": {
    "text": "Knowing how long your content takes to read helps you plan articles, documentation and talks. This short paragraph is here as a sample.",
    "readingWpm": 238,
    "speakingWpm": 150
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/reading-time-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Knowing how long your content takes to read helps you plan articles, documentation and talks. This short paragraph is here as a sample.","readingWpm":238,"speakingWpm":150}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/reading-time-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "Knowing how long your content takes to read helps you plan articles, documentation and talks. This short paragraph is here as a sample.",
    "readingWpm": 238,
    "speakingWpm": 150
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/reading-time-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"Knowing how long your content takes to read helps you plan articles, documentation and talks. This short paragraph is here as a sample.","readingWpm":238,"speakingWpm":150},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/reading-time-calculator · Page: /tools/reading-time-calculator

ROT13 Cipherpagerot13rot131 credit a call

Apply ROT13, or any Caesar shift from 1 to 25, to a text. Letters rotate and keep their case; digits and punctuation stay as they are. Decoding with shift 13 gives the original back.

What it takes

text
string
The text to rotate.
e.g. Hello, World!
shift?
number
Rotation amount, 1 to 25. Defaults to 13, which is ROT13.
e.g. 13
decode?
boolean
Rotate back instead of forward. Defaults to false. With shift 13 both give the same result.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "result": "Uryyb, Jbeyq!",
    "shift": 13,
    "decode": false
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool rot13 (ROT13) with text: Hello, World!, shift: 13, decode: false.

The assistant then makes this tool call:

{
  "name": "rot13",
  "arguments": {
    "text": "Hello, World!",
    "shift": 13,
    "decode": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/rot13 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello, World!","shift":13,"decode":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/rot13", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "Hello, World!",
    "shift": 13,
    "decode": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/rot13",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"Hello, World!","shift":13,"decode":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/rot13 · Page: /tools/rot13

Morse Code Translatorpagemorse-code-translatormorse_code1 credit a call

Translate text to International Morse code or Morse back to text. Letters are separated by a space and words by a slash; characters without a Morse code are dropped.

What it takes

text
string
Plain text when encoding. When decoding: dots and dashes, letters separated by a space, words by " / ".
e.g. SOS help
mode?
string
"encode" (default) or "decode".
e.g. encode

What comes back

{
  "ok": true,
  "data": {
    "result": "... --- ... / .... . .-.. .--.",
    "mode": "encode"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool morse_code (Morse Code Translator) with text: SOS help, mode: encode.

The assistant then makes this tool call:

{
  "name": "morse_code",
  "arguments": {
    "text": "SOS help",
    "mode": "encode"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/morse-code-translator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"SOS help","mode":"encode"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/morse-code-translator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "SOS help",
    "mode": "encode"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/morse-code-translator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"SOS help","mode":"encode"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/morse-code-translator · Page: /tools/morse-code-translator

Numbers to Wordspagenumbers-to-wordsnumbers_to_words1 credit a call

Write a number out in English words, up to 999 quadrillion, with decimals read digit by digit or as a currency amount in dollars, euros or pounds. Optional British style with "and".

What it takes

number
string
The number to spell out. Digits, an optional minus sign and decimal point; commas are ignored. Up to 18 integer digits.
e.g. 1234.56
mode?
string
"plain" (default) or "currency" for amounts on cheques and invoices.
e.g. plain
currency?
string
For currency mode: "dollars" (default), "euros" or "pounds".
e.g. dollars
british?
boolean
Add "and" after hundreds, British style. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "words": "One thousand two hundred thirty-four point five six",
    "number": "1234.56"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool numbers_to_words (Numbers to Words) with number: 1234.56, mode: plain, currency: dollars, british: false.

The assistant then makes this tool call:

{
  "name": "numbers_to_words",
  "arguments": {
    "number": "1234.56",
    "mode": "plain",
    "currency": "dollars",
    "british": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/numbers-to-words \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"number":"1234.56","mode":"plain","currency":"dollars","british":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/numbers-to-words", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "number": "1234.56",
    "mode": "plain",
    "currency": "dollars",
    "british": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/numbers-to-words",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"number":"1234.56","mode":"plain","currency":"dollars","british":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/numbers-to-words · Page: /tools/numbers-to-words

Roman Numeral Converterpageroman-numeral-converterroman_numerals1 credit a call

Convert a whole number from 1 to 3999 into a Roman numeral, or a Roman numeral back into a number, with strict validation and a symbol-by-symbol breakdown. Detects the direction from the input unless a mode is given.

What it takes

value
string
A whole number from 1 to 3999, or a Roman numeral such as MCMXCIV.
e.g. 1994
mode?
string
"auto" (default) reads digits as a number and letters as a numeral; "toRoman" or "toNumber" force one direction.
e.g. auto

What comes back

{
  "ok": true,
  "data": {
    "direction": "toRoman",
    "roman": "MCMXCIV",
    "number": 1994,
    "parts": [
      {
        "value": 1000,
        "symbol": "M"
      }
    ],
    "breakdown": "M (1000) + CM (900) + XC (90) + IV (4)"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool roman_numerals (Roman Numeral) with value: 1994, mode: auto.

The assistant then makes this tool call:

{
  "name": "roman_numerals",
  "arguments": {
    "value": "1994",
    "mode": "auto"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/roman-numeral-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":"1994","mode":"auto"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/roman-numeral-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "value": "1994",
    "mode": "auto"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/roman-numeral-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"value":"1994","mode":"auto"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/roman-numeral-converter · Page: /tools/roman-numeral-converter

Text Cleanerpagetext-cleanerclean_text1 credit a call

Clean up messy text: collapse extra spaces, trim lines, drop empty lines, strip HTML tags, remove punctuation, digits, emojis or control characters, and straighten smart quotes. Returns the cleaned text and how many characters each step removed.

What it takes

text
string
The text to clean.
e.g. <p>Hello world</p> “quoted” text
extraSpaces?
boolean
Turn double spaces into single ones. Defaults to true.
e.g. true
trimLines?
boolean
Trim each line. Defaults to true.
e.g. true
emptyLines?
boolean
Drop lines that are empty or only spaces. Defaults to false.
e.g. true
lineBreaks?
boolean
Replace all line breaks with a space. Defaults to false.
e.g. false
htmlTags?
boolean
Remove <tags>, keeping the text between them. Defaults to false.
e.g. true
punctuation?
boolean
Remove . , ! ? and other punctuation. Defaults to false.
e.g. false
numbers?
boolean
Remove all digits. Defaults to false.
e.g. false
emojis?
boolean
Remove emoji and their joiners. Defaults to false.
e.g. false
plainQuotes?
boolean
Convert curly quotes to plain ' and ". Defaults to false.
e.g. true
controlChars?
boolean
Remove non-printable characters, keeping tabs and newlines. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "result": "Hello world\n\"quoted\" text",
    "charactersBefore": 41,
    "charactersAfter": 25,
    "charactersRemoved": 16,
    "steps": [
      {
        "option": "htmlTags",
        "charactersRemoved": 7
      }
    ],
    "changed": [
      "htmlTags",
      "plainQuotes",
      "trimLines",
      "emptyLines",
      "extraSpaces"
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool clean_text (Text Cleaner) with text: <p>Hello   world</p>


  “quoted”  text  , extraSpaces: true, trimLines: true, emptyLines: true, lineBreaks: false, htmlTags: true, punctuation: false, numbers: false, emojis: false, plainQuotes: true, controlChars: false.

The assistant then makes this tool call:

{
  "name": "clean_text",
  "arguments": {
    "text": "<p>Hello   world</p>\n\n\n  “quoted”  text  ",
    "extraSpaces": true,
    "trimLines": true,
    "emptyLines": true,
    "lineBreaks": false,
    "htmlTags": true,
    "punctuation": false,
    "numbers": false,
    "emojis": false,
    "plainQuotes": true,
    "controlChars": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/text-cleaner \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"<p>Hello   world</p>\n\n\n  “quoted”  text  ","extraSpaces":true,"trimLines":true,"emptyLines":true,"lineBreaks":false,"htmlTags":true,"punctuation":false,"numbers":false,"emojis":false,"plainQuotes":true,"controlChars":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/text-cleaner", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "<p>Hello   world</p>\n\n\n  “quoted”  text  ",
    "extraSpaces": true,
    "trimLines": true,
    "emptyLines": true,
    "lineBreaks": false,
    "htmlTags": true,
    "punctuation": false,
    "numbers": false,
    "emojis": false,
    "plainQuotes": true,
    "controlChars": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/text-cleaner",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"<p>Hello   world</p>\n\n\n  “quoted”  text  ","extraSpaces":true,"trimLines":true,"emptyLines":true,"lineBreaks":false,"htmlTags":true,"punctuation":false,"numbers":false,"emojis":false,"plainQuotes":true,"controlChars":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/text-cleaner · Page: /tools/text-cleaner

Subtitle Converterpagesubtitle-converterconvert_subtitles1 credit a call

Convert subtitles between SRT and WebVTT or to a plain transcript, shift or stretch the timing, append a second part, and repair order, overlaps, empty and flashing cues. Returns the rewritten subtitle text and a report of what changed.

What it takes

text
string
The subtitle file content, SRT or WebVTT; the format is detected.
e.g. 1 00:00:01,000 --> 00:00:03,500 Hello there.
format?
string
Output format: "srt" (default), "vtt", or "txt" for a plain transcript.
e.g. vtt
shiftSeconds?
number
Seconds to move every cue; negative moves earlier. Default 0.
e.g. -2.5
scalePercent?
number
Linear stretch of the timing in percent. Default 100. 104.271 turns 25 fps timing into 23.976 fps.
e.g. 104.271
repair?
boolean
Fix order, overlaps, empty cues, negative times and cues shorter than 300 ms. Default true.
e.g. true
appendText?
string
A second subtitle file to append after the first.
e.g. 1 00:00:00,500 --> 00:00:02,000 Part two begins.
appendOffsetSeconds?
number
Start of part two in seconds; defaults to the end of part one.
e.g. 5400

What comes back

{
  "ok": true,
  "data": {
    "result": "WEBVTT\n\n00:00:01.000 --> 00:00:03.500\nHello there.\n",
    "format": "vtt",
    "inputFormat": "srt",
    "cues": 1,
    "durationMs": 3500,
    "notes": [],
    "repairs": {
      "reordered": false,
      "emptyRemoved": 0,
      "overlapsFixed": 0,
      "negativeClamped": 0,
      "tooShortExtended": 0
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_subtitles (Subtitle) with text: 1
00:00:01,000 --> 00:00:03,500
Hello there., format: vtt, shiftSeconds: -2.5, scalePercent: 104.271, repair: true, appendText: 1
00:00:00,500 --> 00:00:02,000
Part two begins., appendOffsetSeconds: 5400.

The assistant then makes this tool call:

{
  "name": "convert_subtitles",
  "arguments": {
    "text": "1\n00:00:01,000 --> 00:00:03,500\nHello there.",
    "format": "vtt",
    "shiftSeconds": -2.5,
    "scalePercent": 104.271,
    "repair": true,
    "appendText": "1\n00:00:00,500 --> 00:00:02,000\nPart two begins.",
    "appendOffsetSeconds": 5400
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/subtitle-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"1\n00:00:01,000 --> 00:00:03,500\nHello there.","format":"vtt","shiftSeconds":-2.5,"scalePercent":104.271,"repair":true,"appendText":"1\n00:00:00,500 --> 00:00:02,000\nPart two begins.","appendOffsetSeconds":5400}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/subtitle-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "1\n00:00:01,000 --> 00:00:03,500\nHello there.",
    "format": "vtt",
    "shiftSeconds": -2.5,
    "scalePercent": 104.271,
    "repair": true,
    "appendText": "1\n00:00:00,500 --> 00:00:02,000\nPart two begins.",
    "appendOffsetSeconds": 5400
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/subtitle-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"1\n00:00:01,000 --> 00:00:03,500\nHello there.","format":"vtt","shiftSeconds":-2.5,"scalePercent":104.271,"repair":true,"appendText":"1\n00:00:00,500 --> 00:00:02,000\nPart two begins.","appendOffsetSeconds":5400},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/subtitle-converter · Page: /tools/subtitle-converter

Add Line Numberspageadd-line-numbersadd_line_numbers1 credit a call

Put a sequential number in front of every line of a text, with a chosen first number, step and separator. Blank lines can keep their place without taking a number, and the numbers can be padded so the text after them lines up. Use it to cite log lines, contract clauses or manuscript lines.

What it takes

text
string
The text whose lines should be numbered.
e.g. alpha beta gamma
start?
number
The number the first numbered line gets. Defaults to 1.
e.g. 1
step?
number
How much the counter grows per numbered line. Defaults to 1. A negative step counts down.
e.g. 1
separator?
string
What goes between the number and the line. Defaults to ". ". Common choices are ") ", ": " and a tab.
e.g. .
skipEmptyLines?
boolean
Keep blank lines but give them no number, so the counter only counts content lines. Defaults to false.
e.g. false
padNumbers?
boolean
Pad every number to the width of the largest one so the text lines up. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "result": "1. alpha\n2. beta\n3. gamma",
    "lines": 3,
    "numbered": 3,
    "lastNumber": 3
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool add_line_numbers (Add Line Numbers) with text: alpha
beta
gamma, start: 1, step: 1, separator: . , skipEmptyLines: false, padNumbers: false.

The assistant then makes this tool call:

{
  "name": "add_line_numbers",
  "arguments": {
    "text": "alpha\nbeta\ngamma",
    "start": 1,
    "step": 1,
    "separator": ". ",
    "skipEmptyLines": false,
    "padNumbers": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/add-line-numbers \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"alpha\nbeta\ngamma","start":1,"step":1,"separator":". ","skipEmptyLines":false,"padNumbers":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/add-line-numbers", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "alpha\nbeta\ngamma",
    "start": 1,
    "step": 1,
    "separator": ". ",
    "skipEmptyLines": false,
    "padNumbers": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/add-line-numbers",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"alpha\nbeta\ngamma","start":1,"step":1,"separator":". ","skipEmptyLines":false,"padNumbers":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/add-line-numbers · Page: /tools/add-line-numbers

Add Prefix and Suffixpageadd-prefix-suffixadd_prefix_suffix1 credit a call

Put the same text in front of and behind every line of a text. Nothing is escaped or interpreted, so quotes, commas, brackets and HTML tags all pass through as typed. Use it to wrap a column of values in quotes for a SQL IN clause, turn a keyword list into hashtags, or build list markup from plain lines.

What it takes

text
string
The text whose lines should be wrapped, one item per line.
e.g. apple banana cherry
prefix?
string
Put in front of each line, for example "- " or "<li>". Defaults to nothing.
e.g. '
suffix?
string
Put behind each line, for example "," or "</li>". Defaults to nothing.
e.g. ',
skipEmptyLines?
boolean
Leave blank lines untouched. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "result": "'apple',\n'banana',\n'cherry',",
    "lines": 3,
    "changed": 3
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool add_prefix_suffix (Add Prefix and Suffix) with text: apple
banana
cherry, prefix: ', suffix: ',, skipEmptyLines: true.

The assistant then makes this tool call:

{
  "name": "add_prefix_suffix",
  "arguments": {
    "text": "apple\nbanana\ncherry",
    "prefix": "'",
    "suffix": "',",
    "skipEmptyLines": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/add-prefix-suffix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"apple\nbanana\ncherry","prefix":"'","suffix":"',","skipEmptyLines":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/add-prefix-suffix", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "apple\nbanana\ncherry",
    "prefix": "'",
    "suffix": "',",
    "skipEmptyLines": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/add-prefix-suffix",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"apple\nbanana\ncherry","prefix":"'","suffix":"',","skipEmptyLines":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/add-prefix-suffix · Page: /tools/add-prefix-suffix

Remove Line Breakspageremove-line-breaksremove_line_breaks1 credit a call

Join lines that were broken in the wrong places back into flowing text. Each line is trimmed and blank lines are dropped before the join, and the separator can be a space, nothing, or any string such as a comma. Keeping paragraph breaks treats a blank line as a boundary, so a document keeps its shape instead of becoming one wall of text.

What it takes

text
string
The text with the unwanted line breaks.
e.g. A sentence that was broken in three. A second paragraph.
separator?
string
What goes between two joined lines. Defaults to a single space. Use "" to glue them together or ", " to build a list.
e.g.
keepParagraphs?
boolean
Treat a blank line as a paragraph boundary and keep exactly one blank line there. Defaults to false.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "result": "A sentence that was broken in three.\n\nA second paragraph.",
    "linesJoined": 4,
    "paragraphs": 2,
    "breaksRemoved": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool remove_line_breaks (Remove Line Breaks) with text: A sentence that
was broken
in three.

A second paragraph., separator:  , keepParagraphs: true.

The assistant then makes this tool call:

{
  "name": "remove_line_breaks",
  "arguments": {
    "text": "A sentence that\nwas broken\nin three.\n\nA second paragraph.",
    "separator": " ",
    "keepParagraphs": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/remove-line-breaks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"A sentence that\nwas broken\nin three.\n\nA second paragraph.","separator":" ","keepParagraphs":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/remove-line-breaks", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "A sentence that\nwas broken\nin three.\n\nA second paragraph.",
    "separator": " ",
    "keepParagraphs": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/remove-line-breaks",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"A sentence that\nwas broken\nin three.\n\nA second paragraph.","separator":" ","keepParagraphs":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/remove-line-breaks · Page: /tools/remove-line-breaks

Character Counterpagecharacter-countercount_characters1 credit a call

Count the characters, characters without spaces, words, sentences, lines and paragraphs of a text, and rank how often each character appears. The shared counts are defined exactly as the word counter defines them, so the two never disagree about the same paragraph. Use it against a field limit: 280 for a post, 160 for an SMS, 155 for a meta description.

What it takes

text
string
The text to measure.
e.g. Hello world. This is a test!
limit?
number
How many rows of character frequency to return, most common first. Defaults to 20.
e.g. 5

What comes back

{
  "ok": true,
  "data": {
    "characters": 28,
    "charactersNoSpaces": 23,
    "words": 6,
    "sentences": 2,
    "lines": 1,
    "paragraphs": 1,
    "readingTime": {
      "minutes": 0,
      "seconds": 2,
      "text": "2 sec"
    },
    "frequencies": [
      {
        "character": "l",
        "count": 3,
        "percent": 13.04
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool count_characters (Character) with text: Hello world. This is a test!, limit: 5.

The assistant then makes this tool call:

{
  "name": "count_characters",
  "arguments": {
    "text": "Hello world. This is a test!",
    "limit": 5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/character-counter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello world. This is a test!","limit":5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/character-counter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "Hello world. This is a test!",
    "limit": 5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/character-counter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"Hello world. This is a test!","limit":5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/character-counter · Page: /tools/character-counter

Upside Down Textpageupside-down-textupside_down_text1 credit a call

Flip text upside down, or mirror it left to right, using Unicode characters that look like rotated or reflected Latin letters. The string is reversed after mapping, so it reads correctly when the screen is turned round or held up to a mirror. The result is ordinary text, so it can be pasted into a bio, a username or a chat message.

What it takes

text
string
The text to flip.
e.g. hello world
mode?
string
"upside" (default) turns the text 180 degrees, "mirror" reflects it left to right.
e.g. upside

What comes back

{
  "ok": true,
  "data": {
    "result": "plɹoʍ ollǝɥ",
    "mode": "upside",
    "mapped": 10,
    "unchanged": 1
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool upside_down_text (Upside Down Text) with text: hello world, mode: upside.

The assistant then makes this tool call:

{
  "name": "upside_down_text",
  "arguments": {
    "text": "hello world",
    "mode": "upside"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/upside-down-text \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"hello world","mode":"upside"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/upside-down-text", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "hello world",
    "mode": "upside"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/upside-down-text",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"hello world","mode":"upside"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/upside-down-text · Page: /tools/upside-down-text

Leetspeak Translatorpageleetspeak-translatorleetspeak1 credit a call

Write text in leetspeak at one of three intensities, or read leetspeak back into plain text. Basic swaps the six canonical letters (a4 e3 i1 o0 s5 t7), advanced adds four more, and extreme builds most of the alphabet out of punctuation. Decoding is best effort because leet is ambiguous: the digit 1 stands for both i and l, and this resolves it to l.

What it takes

text
string
The text to translate, plain going out or leet coming back.
e.g. paste your leet here
action?
string
"encode" (default) writes leet, "decode" reads it.
e.g. encode
intensity?
string
"basic" (default) swaps a e i o s t, "advanced" adds l b g z, "extreme" builds letters out of punctuation. Ignored when decoding.
e.g. basic

What comes back

{
  "ok": true,
  "data": {
    "result": "p4573 y0ur l337 h3r3",
    "action": "encode",
    "intensity": "basic",
    "substitutions": 10
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool leetspeak (Leetspeak Translator) with text: paste your leet here, action: encode, intensity: basic.

The assistant then makes this tool call:

{
  "name": "leetspeak",
  "arguments": {
    "text": "paste your leet here",
    "action": "encode",
    "intensity": "basic"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/leetspeak-translator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"paste your leet here","action":"encode","intensity":"basic"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/leetspeak-translator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "paste your leet here",
    "action": "encode",
    "intensity": "basic"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/leetspeak-translator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"paste your leet here","action":"encode","intensity":"basic"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/leetspeak-translator · Page: /tools/leetspeak-translator

Keyword Density Analyzerpagekeyword-density-analyzerkeyword_density1 credit a call

Count how often each word or phrase appears in a text and what share of it they take up. Phrases are one to five words long, stop words are left out of the table but still counted in the total, and one target keyword can be reported separately whatever its count. Each row is banded: under 1 percent is sparse, 1 to 3 is good, over 5 reads as stuffing.

What it takes

text
string
The content to analyse.
e.g. Keyword density matters. Keyword density is the share of a page a keyword tak...
phraseLength?
number
1 for single words (default), 2 or 3 for phrases. Up to 5 is allowed.
e.g. 2
minCount?
number
Drop keywords seen fewer times than this. Defaults to 2, which is what keeps one-off words out of the table.
e.g. 2
limit?
number
How many rows to return. Defaults to 10. Pass 0 for all of them.
e.g. 10
excludeStopWords?
boolean
Leave stop words out of the table. A phrase is only dropped when its first and last word are both stop words. Defaults to true.
e.g. true
sortBy?
string
"count" (default) or "density". Both give the same order, since density is a share of one total.
e.g. count
order?
string
"desc" (default) puts the most used keyword first, "asc" the least.
e.g. desc
targetKeyword?
string
One word or phrase to report on separately, whatever its count and whether or not it is a stop word.
e.g. keyword density

What comes back

{
  "ok": true,
  "data": {
    "totalWords": 24,
    "characters": 138,
    "uniqueKeywords": 2,
    "averageWordLength": 4.67,
    "keywords": [
      {
        "keyword": "keyword density",
        "count": 3,
        "density": 12.5,
        "band": "overstuffed"
      }
    ],
    "target": {
      "keyword": "keyword density",
      "count": 3,
      "density": 12.5,
      "band": "overstuffed"
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool keyword_density (Keyword Density Analyzer) with text: Keyword density matters. Keyword density is the share of ..., phraseLength: 2, minCount: 2, limit: 10, excludeStopWords: true, sortBy: count, order: desc, targetKeyword: keyword density.

The assistant then makes this tool call:

{
  "name": "keyword_density",
  "arguments": {
    "text": "Keyword density matters. Keyword density is the share of a page a keyword takes up. Good keyword density is between one and three percent.",
    "phraseLength": 2,
    "minCount": 2,
    "limit": 10,
    "excludeStopWords": true,
    "sortBy": "count",
    "order": "desc",
    "targetKeyword": "keyword density"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/keyword-density-analyzer \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Keyword density matters. Keyword density is the share of a page a keyword takes up. Good keyword density is between one and three percent.","phraseLength":2,"minCount":2,"limit":10,"excludeStopWords":true,"sortBy":"count","order":"desc","targetKeyword":"keyword density"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/keyword-density-analyzer", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "Keyword density matters. Keyword density is the share of a page a keyword takes up. Good keyword density is between one and three percent.",
    "phraseLength": 2,
    "minCount": 2,
    "limit": 10,
    "excludeStopWords": true,
    "sortBy": "count",
    "order": "desc",
    "targetKeyword": "keyword density"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/keyword-density-analyzer",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"Keyword density matters. Keyword density is the share of a page a keyword takes up. Good keyword density is between one and three percent.","phraseLength":2,"minCount":2,"limit":10,"excludeStopWords":true,"sortBy":"count","order":"desc","targetKeyword":"keyword density"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/keyword-density-analyzer · Page: /tools/keyword-density-analyzer

Readability Checkerpagereadability-checkerreadability_scores1 credit a call

Score how hard a text is to read with six named formulas: Flesch Reading Ease, Flesch-Kincaid Grade, Gunning Fog, SMOG, Coleman-Liau and the Automated Readability Index. Each is returned under its own name alongside the word, sentence and syllable counts it was built from, plus the mean grade, the school year it maps to and the audience that suits.

What it takes

text
string
The text to score. The formulas and the syllable heuristic are English, so scores for other languages mean little.
e.g. The quick brown fox jumps over the lazy dog. This is a sample text to demonst...

What comes back

{
  "ok": true,
  "data": {
    "words": 20,
    "sentences": 2,
    "syllables": 31,
    "complexWords": 3,
    "letters": 90,
    "averageWordsPerSentence": 10,
    "averageSyllablesPerWord": 1.55,
    "scores": {
      "fleschReadingEase": 65.56,
      "fleschKincaidGrade": 6.6,
      "gunningFog": 10,
      "smogIndex": 9.71,
      "colemanLiauIndex": 7.7,
      "automatedReadabilityIndex": 4.77
    },
    "averageGrade": 7.75,
    "gradeLabel": "8th grade",
    "audience": "Middle school",
    "fleschLabel": "Standard"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool readability_scores (Readability) with text: The quick brown fox jumps over the lazy dog. This is a sa....

The assistant then makes this tool call:

{
  "name": "readability_scores",
  "arguments": {
    "text": "The quick brown fox jumps over the lazy dog. This is a sample text to demonstrate the readability checker tool."
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/readability-checker \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"The quick brown fox jumps over the lazy dog. This is a sample text to demonstrate the readability checker tool."}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/readability-checker", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "The quick brown fox jumps over the lazy dog. This is a sample text to demonstrate the readability checker tool."
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/readability-checker",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"The quick brown fox jumps over the lazy dog. This is a sample text to demonstrate the readability checker tool."},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/readability-checker · Page: /tools/readability-checker

Text Similarity Analyzerpagetext-similarity-analyzertext_similarity1 credit a call

Compare two texts with five named measures instead of one unexplained percentage: Jaccard over the word sets, cosine over the word counts, word overlap, Levenshtein edit distance with a ratio, and the longest common subsequence of words. It also returns the words the two share and the words only one of them has, plus word, character and sentence counts for each.

What it takes

textA
string
The first text.
e.g. The quick brown fox jumps over the lazy dog.
textB
string
The second text.
e.g. The quick brown cat jumps over the lazy dog.
commonWordLimit?
number
How many shared words to list. Defaults to 50.
e.g. 50
uniqueWordLimit?
number
How many words unique to each text to list. Defaults to 30.
e.g. 30

What comes back

{
  "ok": true,
  "data": {
    "overall": 0.84,
    "jaccard": 0.78,
    "cosine": 0.91,
    "wordOverlap": 0.78,
    "levenshteinDistance": 3,
    "levenshteinRatio": 0.93,
    "levenshteinTruncated": false,
    "longestCommonSubsequence": 8,
    "a": {
      "words": 9,
      "characters": 44,
      "sentences": 1
    },
    "b": {
      "words": 9,
      "characters": 44,
      "sentences": 1
    },
    "commonWords": [
      "the",
      "quick",
      "brown",
      "jumps",
      "over",
      "lazy",
      "dog"
    ],
    "onlyInA": [
      "fox"
    ],
    "onlyInB": [
      "cat"
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool text_similarity (Text Similarity Analyzer) with textA: The quick brown fox jumps over the lazy dog., textB: The quick brown cat jumps over the lazy dog., commonWordLimit: 50, uniqueWordLimit: 30.

The assistant then makes this tool call:

{
  "name": "text_similarity",
  "arguments": {
    "textA": "The quick brown fox jumps over the lazy dog.",
    "textB": "The quick brown cat jumps over the lazy dog.",
    "commonWordLimit": 50,
    "uniqueWordLimit": 30
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/text-similarity-analyzer \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"textA":"The quick brown fox jumps over the lazy dog.","textB":"The quick brown cat jumps over the lazy dog.","commonWordLimit":50,"uniqueWordLimit":30}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/text-similarity-analyzer", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "textA": "The quick brown fox jumps over the lazy dog.",
    "textB": "The quick brown cat jumps over the lazy dog.",
    "commonWordLimit": 50,
    "uniqueWordLimit": 30
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/text-similarity-analyzer",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"textA":"The quick brown fox jumps over the lazy dog.","textB":"The quick brown cat jumps over the lazy dog.","commonWordLimit":50,"uniqueWordLimit":30},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/text-similarity-analyzer · Page: /tools/text-similarity-analyzer

Data formats

JSON Formatterpagejson-formatterformat_json1 credit a call

Pretty-print, minify or validate a JSON string with a real parser, reporting the line and column of any syntax error.

What it takes

json
string
The JSON text to work on, as a string, not an object.
e.g. {"name":"ToolForte","version":1}
action?
string
What to do with it: "format" (default), "minify" or "validate".
e.g. format
indent?
number
Spaces per level when formatting. Defaults to 2.
e.g. 2

What comes back

{
  "ok": true,
  "data": {
    "output": "{\n  \"name\": \"ToolForte\",\n  \"version\": 1\n}",
    "valid": true
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool format_json (JSON) with json: {"name":"ToolForte","version":1}, action: format, indent: 2.

The assistant then makes this tool call:

{
  "name": "format_json",
  "arguments": {
    "json": "{\"name\":\"ToolForte\",\"version\":1}",
    "action": "format",
    "indent": 2
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/json-formatter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"json":"{\"name\":\"ToolForte\",\"version\":1}","action":"format","indent":2}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/json-formatter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "json": "{\"name\":\"ToolForte\",\"version\":1}",
    "action": "format",
    "indent": 2
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/json-formatter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"json":"{\"name\":\"ToolForte\",\"version\":1}","action":"format","indent":2},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/json-formatter · Page: /tools/json-formatter

CSV to JSONpagecsv-to-jsoncsv_to_json1 credit a call

Parse CSV text into JSON objects, detecting the delimiter and handling quoted fields.

What it takes

csv
string
The CSV text, rows separated by newlines.
e.g. name,age Alice,30 Bob,25
first_row_headers?
boolean
Whether the first row holds column names. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "json": [
      {
        "name": "Alice",
        "age": "30"
      }
    ],
    "delimiter": ",",
    "row_count": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool csv_to_json (CSV to JSON) with csv: name,age
Alice,30
Bob,25, first_row_headers: true.

The assistant then makes this tool call:

{
  "name": "csv_to_json",
  "arguments": {
    "csv": "name,age\nAlice,30\nBob,25",
    "first_row_headers": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/csv-to-json \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"csv":"name,age\nAlice,30\nBob,25","first_row_headers":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/csv-to-json", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "csv": "name,age\nAlice,30\nBob,25",
    "first_row_headers": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/csv-to-json",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"csv":"name,age\nAlice,30\nBob,25","first_row_headers":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/csv-to-json · Page: /tools/csv-to-json

JSON to CSVpagejson-to-csvjson_to_csv1 credit a call

Turn a JSON array of objects, or a JSON string holding one, into CSV text. Nested objects become dotted column names such as address.city, arrays are written as JSON inside the cell, and every key seen in any row becomes a column.

What it takes

json
string
The rows to convert: a JSON string of an array of objects, or the array itself.
e.g. [{"name":"Alice","address":{"city":"Utrecht"}},{"name":"Bob","address":{"city...
delimiter?
string
Column separator: ",", ";", "|" or "tab". Defaults to a comma.
e.g. ,
includeHeader?
boolean
Whether the first line lists the column names. Defaults to true.
e.g. true
flatten?
boolean
Whether nested objects become dotted columns like address.city. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "csv": "name,address.city\nAlice,Utrecht\nBob,Leiden",
    "columns": [
      "name",
      "address.city"
    ],
    "rowCount": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool json_to_csv (JSON to CSV) with json: [{"name":"Alice","address":{"city":"Utrecht"}},{"name":"B..., delimiter: ,, includeHeader: true, flatten: true.

The assistant then makes this tool call:

{
  "name": "json_to_csv",
  "arguments": {
    "json": "[{\"name\":\"Alice\",\"address\":{\"city\":\"Utrecht\"}},{\"name\":\"Bob\",\"address\":{\"city\":\"Leiden\"}}]",
    "delimiter": ",",
    "includeHeader": true,
    "flatten": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/json-to-csv \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"json":"[{\"name\":\"Alice\",\"address\":{\"city\":\"Utrecht\"}},{\"name\":\"Bob\",\"address\":{\"city\":\"Leiden\"}}]","delimiter":",","includeHeader":true,"flatten":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/json-to-csv", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "json": "[{\"name\":\"Alice\",\"address\":{\"city\":\"Utrecht\"}},{\"name\":\"Bob\",\"address\":{\"city\":\"Leiden\"}}]",
    "delimiter": ",",
    "includeHeader": true,
    "flatten": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/json-to-csv",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"json":"[{\"name\":\"Alice\",\"address\":{\"city\":\"Utrecht\"}},{\"name\":\"Bob\",\"address\":{\"city\":\"Leiden\"}}]","delimiter":",","includeHeader":true,"flatten":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/json-to-csv · Page: /tools/json-to-csv

JSON to YAMLpagejson-to-yamljson_to_yaml1 credit a call

Convert a JSON string to YAML text. Strings are quoted only when a YAML reader would otherwise see a number, boolean, date or empty value, multi-line strings become block scalars, and keys can be sorted.

What it takes

json
string
The JSON text to convert, as a string.
e.g. {"name":"ToolForte","tags":["fast","free"],"owner":null}
indent?
number
Spaces per nesting level, 1 to 8. Defaults to 2.
e.g. 2
sortKeys?
boolean
Sort object keys alphabetically. Defaults to false.
e.g. false
nullStyle?
string
How to write null: "null" (default) writes the word, "empty" leaves the value blank.
e.g. null

What comes back

{
  "ok": true,
  "data": {
    "yaml": "name: ToolForte\ntags:\n  - fast\n  - free\nowner: null"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool json_to_yaml (JSON to YAML) with json: {"name":"ToolForte","tags":["fast","free"],"owner":null}, indent: 2, sortKeys: false, nullStyle: null.

The assistant then makes this tool call:

{
  "name": "json_to_yaml",
  "arguments": {
    "json": "{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"],\"owner\":null}",
    "indent": 2,
    "sortKeys": false,
    "nullStyle": "null"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/json-to-yaml \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"json":"{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"],\"owner\":null}","indent":2,"sortKeys":false,"nullStyle":"null"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/json-to-yaml", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "json": "{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"],\"owner\":null}",
    "indent": 2,
    "sortKeys": false,
    "nullStyle": "null"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/json-to-yaml",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"json":"{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"],\"owner\":null}","indent":2,"sortKeys":false,"nullStyle":"null"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/json-to-yaml · Page: /tools/json-to-yaml

YAML to JSONpageyaml-to-jsonyaml_to_json1 credit a call

Parse YAML text and return both the value and its JSON text. Reads maps, lists, inline [lists] and {maps}, quoted and block scalars and comments. Anchors, aliases, merge keys, tags and multi-document files are not supported and are reported with the line number.

What it takes

yaml
string
The YAML text to parse, one document.
e.g. name: ToolForte tags: - fast - free port: 8080
indent?
number
Spaces per level in the JSON text, 0 to 8. 0 gives minified JSON. Defaults to 2.
e.g. 2

What comes back

{
  "ok": true,
  "data": {
    "value": {
      "name": "ToolForte",
      "tags": [
        "fast",
        "free"
      ],
      "port": 8080
    },
    "json": "{\n  \"name\": \"ToolForte\",\n  \"tags\": [\n    \"fast\",\n    \"free\"\n  ],\n  \"port\": 8080\n}"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool yaml_to_json (YAML to JSON) with yaml: name: ToolForte
tags:
  - fast
  - free
port: 8080, indent: 2.

The assistant then makes this tool call:

{
  "name": "yaml_to_json",
  "arguments": {
    "yaml": "name: ToolForte\ntags:\n  - fast\n  - free\nport: 8080",
    "indent": 2
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/yaml-to-json \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"yaml":"name: ToolForte\ntags:\n  - fast\n  - free\nport: 8080","indent":2}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/yaml-to-json", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "yaml": "name: ToolForte\ntags:\n  - fast\n  - free\nport: 8080",
    "indent": 2
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/yaml-to-json",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"yaml":"name: ToolForte\ntags:\n  - fast\n  - free\nport: 8080","indent":2},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/yaml-to-json · Page: /tools/yaml-to-json

XML to JSONpagexml-to-jsonxml_to_json1 credit a call

Parse XML into a JSON object keyed by the root element. Attributes become keys with a prefix ("@id"), text beside attributes or children lands under "#text", repeated elements become arrays, and namespace prefixes can be dropped. Malformed XML is reported with the line number; DTD-declared entities are not expanded.

What it takes

xml
string
The XML document to parse.
e.g. <order id="42"><item sku="A1">Bolts</item><item sku="B2">Nuts</item></order>
attributePrefix?
string
Text put in front of attribute names, so "id" becomes "@id". Defaults to "@".
e.g. @
dropNamespaces?
boolean
Strip namespace prefixes such as soap: and xmlns declarations. Defaults to true.
e.g. true
indent?
number
Spaces per level in the JSON text, 0 to 8. 0 gives minified JSON. Defaults to 2.
e.g. 2

What comes back

{
  "ok": true,
  "data": {
    "value": {
      "order": {
        "@id": "42",
        "item": [
          {
            "@sku": "A1",
            "#text": "Bolts"
          },
          {
            "@sku": "B2",
            "#text": "Nuts"
          }
        ]
      }
    },
    "json": "{\n  \"order\": {\n    \"@id\": \"42\",\n    \"item\": [\n      {\n        \"@sku\": \"A1\",\n        \"#text\": \"Bolts\"\n      },\n      {\n        \"@sku\": \"B2\",\n        \"#text\": \"Nuts\"\n      }\n    ]\n  }\n}",
    "elements": 3
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool xml_to_json (XML to JSON) with xml: <order id="42"><item sku="A1">Bolts</item><item sku="B2">..., attributePrefix: @, dropNamespaces: true, indent: 2.

The assistant then makes this tool call:

{
  "name": "xml_to_json",
  "arguments": {
    "xml": "<order id=\"42\"><item sku=\"A1\">Bolts</item><item sku=\"B2\">Nuts</item></order>",
    "attributePrefix": "@",
    "dropNamespaces": true,
    "indent": 2
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/xml-to-json \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"xml":"<order id=\"42\"><item sku=\"A1\">Bolts</item><item sku=\"B2\">Nuts</item></order>","attributePrefix":"@","dropNamespaces":true,"indent":2}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/xml-to-json", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "xml": "<order id=\"42\"><item sku=\"A1\">Bolts</item><item sku=\"B2\">Nuts</item></order>",
    "attributePrefix": "@",
    "dropNamespaces": true,
    "indent": 2
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/xml-to-json",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"xml":"<order id=\"42\"><item sku=\"A1\">Bolts</item><item sku=\"B2\">Nuts</item></order>","attributePrefix":"@","dropNamespaces":true,"indent":2},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/xml-to-json · Page: /tools/xml-to-json

JSON to XMLpagejson-to-xmljson_to_xml1 credit a call

Serialise a JSON string as XML. Object keys become element names, array items repeat the parent key, null and empty objects become self-closing tags, and the root element name is yours to choose. A top-level array is wrapped in the root with one item element per entry.

What it takes

json
string
The JSON text to convert, as a string.
e.g. {"name":"ToolForte","tags":["fast","free"]}
rootName?
string
Name of the outermost element. Defaults to "root".
e.g. product
declaration?
boolean
Whether to start the output with the XML declaration line. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<product>\n  <name>ToolForte</name>\n  <tags>fast</tags>\n  <tags>free</tags>\n</product>"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool json_to_xml (JSON to XML) with json: {"name":"ToolForte","tags":["fast","free"]}, rootName: product, declaration: true.

The assistant then makes this tool call:

{
  "name": "json_to_xml",
  "arguments": {
    "json": "{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"]}",
    "rootName": "product",
    "declaration": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/json-to-xml \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"json":"{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"]}","rootName":"product","declaration":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/json-to-xml", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "json": "{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"]}",
    "rootName": "product",
    "declaration": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/json-to-xml",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"json":"{\"name\":\"ToolForte\",\"tags\":[\"fast\",\"free\"]}","rootName":"product","declaration":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/json-to-xml · Page: /tools/json-to-xml

XML Formatterpagexml-formatterformat_xml1 credit a call

Pretty-print XML with consistent indentation, or minify it by removing the whitespace between tags. Elements that hold only text stay on one line, and comments, CDATA and processing instructions are kept. Malformed XML is reported with the line number rather than reshaped.

What it takes

xml
string
The XML document to format.
e.g. <a><b x="1">text</b><c/></a>
mode?
string
"pretty" (default) indents each level, "minify" removes whitespace between tags.
e.g. pretty
indent?
number
Spaces per level when pretty-printing, 1 to 8. Defaults to 2.
e.g. 2

What comes back

{
  "ok": true,
  "data": {
    "xml": "<a>\n  <b x=\"1\">text</b>\n  <c/>\n</a>"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool format_xml (XML) with xml: <a><b x="1">text</b><c/></a>, mode: pretty, indent: 2.

The assistant then makes this tool call:

{
  "name": "format_xml",
  "arguments": {
    "xml": "<a><b x=\"1\">text</b><c/></a>",
    "mode": "pretty",
    "indent": 2
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/xml-formatter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"xml":"<a><b x=\"1\">text</b><c/></a>","mode":"pretty","indent":2}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/xml-formatter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "xml": "<a><b x=\"1\">text</b><c/></a>",
    "mode": "pretty",
    "indent": 2
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/xml-formatter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"xml":"<a><b x=\"1\">text</b><c/></a>","mode":"pretty","indent":2},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/xml-formatter · Page: /tools/xml-formatter

CSV to Markdownpagecsv-to-markdowncsv_to_markdown1 credit a call

Turn CSV text into a GitHub-style Markdown table. Detects the delimiter (comma, semicolon, tab or pipe) unless told, reads quoted fields with embedded delimiters and newlines, and can align columns and pad cells so the table lines up in plain text.

What it takes

csv
string
The CSV text, rows separated by newlines.
e.g. name,age Alice,30 Bob,25
delimiter?
string
Column separator: ",", ";", "|" or "tab". Defaults to "auto", which reads the first line.
e.g. auto
firstRowHeader?
boolean
Whether the first row holds the column names. Defaults to true.
e.g. true
padded?
boolean
Pad cells so the columns line up in plain text. Defaults to true.
e.g. true
alignment?
string
Column alignment: "left" (default), "center" or "right", or an array with one value per column.
e.g. left

What comes back

{
  "ok": true,
  "data": {
    "markdown": "| name  | age |\n| :---- | :-- |\n| Alice | 30  |\n| Bob   | 25  |",
    "rows": 2,
    "columns": 2,
    "delimiter": ",",
    "raggedLines": []
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool csv_to_markdown (CSV to Markdown) with csv: name,age
Alice,30
Bob,25, delimiter: auto, firstRowHeader: true, padded: true, alignment: left.

The assistant then makes this tool call:

{
  "name": "csv_to_markdown",
  "arguments": {
    "csv": "name,age\nAlice,30\nBob,25",
    "delimiter": "auto",
    "firstRowHeader": true,
    "padded": true,
    "alignment": "left"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/csv-to-markdown \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"csv":"name,age\nAlice,30\nBob,25","delimiter":"auto","firstRowHeader":true,"padded":true,"alignment":"left"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/csv-to-markdown", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "csv": "name,age\nAlice,30\nBob,25",
    "delimiter": "auto",
    "firstRowHeader": true,
    "padded": true,
    "alignment": "left"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/csv-to-markdown",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"csv":"name,age\nAlice,30\nBob,25","delimiter":"auto","firstRowHeader":true,"padded":true,"alignment":"left"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/csv-to-markdown · Page: /tools/csv-to-markdown

UTM Builderpageutm-builderbuild_utm_url1 credit a call

Add utm_source, utm_medium, utm_campaign, utm_term and utm_content to a URL, keeping any query parameters it already has. Returns the tagged link plus warnings about upper case or missing required tags.

What it takes

url
string
The full URL to tag, including https://.
e.g. https://example.com/pricing?ref=1
source?
string
Where the visitor comes from: google, newsletter, linkedin.
e.g. newsletter
medium?
string
The channel: cpc, email, social.
e.g. email
campaign?
string
A name for this campaign.
e.g. spring_sale
term?
string
Paid keywords, if any.
e.g. running_shoes
content?
string
Which link or ad variant this is.
e.g. header_banner

What comes back

{
  "ok": true,
  "data": {
    "url": "https://example.com/pricing?ref=1&utm_source=newsletter&utm_medium=email&utm_campaign=spring_sale&utm_term=running_shoes&utm_content=header_banner",
    "baseUrl": "https://example.com/pricing?ref=1",
    "params": {
      "utm_source": "newsletter",
      "utm_medium": "email",
      "utm_campaign": "spring_sale",
      "utm_term": "running_shoes",
      "utm_content": "header_banner"
    },
    "warnings": []
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool build_utm_url (UTM) with url: https://example.com/pricing?ref=1, source: newsletter, medium: email, campaign: spring_sale, term: running_shoes, content: header_banner.

The assistant then makes this tool call:

{
  "name": "build_utm_url",
  "arguments": {
    "url": "https://example.com/pricing?ref=1",
    "source": "newsletter",
    "medium": "email",
    "campaign": "spring_sale",
    "term": "running_shoes",
    "content": "header_banner"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/utm-builder \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/pricing?ref=1","source":"newsletter","medium":"email","campaign":"spring_sale","term":"running_shoes","content":"header_banner"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/utm-builder", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "url": "https://example.com/pricing?ref=1",
    "source": "newsletter",
    "medium": "email",
    "campaign": "spring_sale",
    "term": "running_shoes",
    "content": "header_banner"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/utm-builder",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"url":"https://example.com/pricing?ref=1","source":"newsletter","medium":"email","campaign":"spring_sale","term":"running_shoes","content":"header_banner"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/utm-builder · Page: /tools/utm-builder

CSV Mergepagecsv-mergemerge_csv1 credit a call

Append several CSV files into one. By header, columns are matched by name (case-insensitive) and the headers are unioned, so files with different column orders or an extra column combine cleanly; by position, rows are appended under the first file's header. Optionally adds a Source column with each file's name. Returns the merged CSV.

What it takes

files
array
Objects with text (the CSV) and an optional name, 2 to 20 of them.
e.g. [{"name":"jan.csv","text":"id,amount\n1,10\n"},{"name":"feb.csv","text":"amount,id\n20,2\n"}]
mode?
string
"byHeader" (default) matches columns by name; "byPosition" appends rows under the first header.
e.g. byHeader
sourceColumn?
boolean
Add a Source column with the file name. Default false.
e.g. true
delimiter?
string
Output delimiter, one character. Default comma.
e.g. ;

What comes back

{
  "ok": true,
  "data": {
    "result": "id,amount,Source\n1,10,jan.csv\n2,20,feb.csv\n",
    "header": [
      "id",
      "amount",
      "Source"
    ],
    "rows": 2,
    "files": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool merge_csv (CSV Merge) with files: [{"name":"jan.csv","text":"id,amount\n1,10\n"},{"name":"feb.csv","text":"amount,id\n20,2\n"}], mode: byHeader, sourceColumn: true, delimiter: ;.

The assistant then makes this tool call:

{
  "name": "merge_csv",
  "arguments": {
    "files": [
      {
        "name": "jan.csv",
        "text": "id,amount\n1,10\n"
      },
      {
        "name": "feb.csv",
        "text": "amount,id\n20,2\n"
      }
    ],
    "mode": "byHeader",
    "sourceColumn": true,
    "delimiter": ";"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/csv-merge \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"files":[{"name":"jan.csv","text":"id,amount\n1,10\n"},{"name":"feb.csv","text":"amount,id\n20,2\n"}],"mode":"byHeader","sourceColumn":true,"delimiter":";"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/csv-merge", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "files": [
      {
        "name": "jan.csv",
        "text": "id,amount\n1,10\n"
      },
      {
        "name": "feb.csv",
        "text": "amount,id\n20,2\n"
      }
    ],
    "mode": "byHeader",
    "sourceColumn": true,
    "delimiter": ";"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/csv-merge",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"files":[{"name":"jan.csv","text":"id,amount\n1,10\n"},{"name":"feb.csv","text":"amount,id\n20,2\n"}],"mode":"byHeader","sourceColumn":true,"delimiter":";"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/csv-merge · Page: /tools/spreadsheet-merge-split

CSV Splitpagecsv-splitsplit_csv1 credit a call

Split one CSV into parts, either every N rows or one part per distinct value of a column. Every part keeps the header. Returns the parts as CSV text with a name each.

What it takes

text
string
The CSV to split, with a header row.
e.g. id,country 1,NL 2,BE 3,NL
by
string
"rows" for fixed-size chunks or "column" for one part per value.
e.g. column
size?
number
Rows per part, when splitting by rows.
e.g. 1000
column?
string
Column to split on, when splitting by column.
e.g. country
name?
string
Base name for the parts.
e.g. orders

What comes back

{
  "ok": true,
  "data": {
    "parts": [
      {
        "name": "orders-NL",
        "rows": 2,
        "csv": "id,country\n1,NL\n3,NL\n"
      },
      {
        "name": "orders-BE",
        "rows": 1,
        "csv": "id,country\n2,BE\n"
      }
    ],
    "count": 2,
    "totalRows": 3
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool split_csv (CSV Split) with text: id,country
1,NL
2,BE
3,NL
, by: column, size: 1000, column: country, name: orders.

The assistant then makes this tool call:

{
  "name": "split_csv",
  "arguments": {
    "text": "id,country\n1,NL\n2,BE\n3,NL\n",
    "by": "column",
    "size": 1000,
    "column": "country",
    "name": "orders"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/csv-split \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"id,country\n1,NL\n2,BE\n3,NL\n","by":"column","size":1000,"column":"country","name":"orders"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/csv-split", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "id,country\n1,NL\n2,BE\n3,NL\n",
    "by": "column",
    "size": 1000,
    "column": "country",
    "name": "orders"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/csv-split",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"id,country\n1,NL\n2,BE\n3,NL\n","by":"column","size":1000,"column":"country","name":"orders"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/csv-split · Page: /tools/spreadsheet-merge-split

Average Calculatorpageaverage-calculatoraverage1 credit a call

Every average of a list of numbers in one call: mean, median, mode, sum, count, minimum, maximum, range, and the geometric and harmonic means. A list where nothing repeats has no mode, and the two positive-only means come back null when any value is zero or below.

What it takes

values
array
The list of numbers to average, as an array of numbers.
e.g. [12,15,9,21,15,18]

What comes back

{
  "ok": true,
  "data": {
    "count": 6,
    "sum": 90,
    "mean": 15,
    "median": 15,
    "modes": [
      15
    ],
    "min": 9,
    "max": 21,
    "range": 12,
    "geometricMean": 14.47,
    "harmonicMean": 13.92,
    "sorted": [
      9,
      12,
      15,
      15,
      18,
      21
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool average (Average) with values: [12,15,9,21,15,18].

The assistant then makes this tool call:

{
  "name": "average",
  "arguments": {
    "values": [
      12,
      15,
      9,
      21,
      15,
      18
    ]
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/average-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"values":[12,15,9,21,15,18]}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/average-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "values": [
      12,
      15,
      9,
      21,
      15,
      18
    ]
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/average-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"values":[12,15,9,21,15,18]},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/average-calculator · Page: /tools/average-calculator

Standard Deviation Calculatorpagestandard-deviation-calculatorstandard_deviation1 credit a call

Standard deviation and variance of a list of numbers, both the sample and the population figures, plus the mean, the sum and the sum of squared deviations. The `type` field says which of the two the headline standardDeviation reports: the sample one unless asked otherwise, or the population one when there is a single value.

What it takes

values
array
The list of numbers, as an array of numbers.
e.g. [4,8,15,16,23,42]
type?
string
sample or population. Left out, it is sample whenever there are two values or more.
e.g. sample

What comes back

{
  "ok": true,
  "data": {
    "type": "sample",
    "count": 6,
    "sum": 108,
    "mean": 18,
    "sumOfSquares": 910,
    "sampleStandardDeviation": 13.49,
    "sampleVariance": 182,
    "populationStandardDeviation": 12.32,
    "populationVariance": 151.67,
    "standardDeviation": 13.49,
    "variance": 182,
    "min": 4,
    "max": 42,
    "values": [
      4,
      8,
      15,
      16,
      23,
      42
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool standard_deviation (Standard Deviation) with values: [4,8,15,16,23,42], type: sample.

The assistant then makes this tool call:

{
  "name": "standard_deviation",
  "arguments": {
    "values": [
      4,
      8,
      15,
      16,
      23,
      42
    ],
    "type": "sample"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/standard-deviation-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"values":[4,8,15,16,23,42],"type":"sample"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/standard-deviation-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "values": [
      4,
      8,
      15,
      16,
      23,
      42
    ],
    "type": "sample"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/standard-deviation-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"values":[4,8,15,16,23,42],"type":"sample"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/standard-deviation-calculator · Page: /tools/standard-deviation-calculator

TSV to CSVpagetsv-to-csvtsv_to_csv1 credit a call

Convert tab separated text to CSV, or CSV back to TSV, quoting every field that needs it. A field holding the output delimiter, a double quote, a line break or outer whitespace is wrapped in quotes with inner quotes doubled, which is what stops a value such as Hex bolt, stainless from silently gaining a column. Semicolon output and a UTF-8 byte order mark are there for Excel in comma-decimal locales.

What it takes

text
string
The delimited text to convert: tab separated going to CSV, comma or semicolon separated coming back.
e.g. product description price AB-12 Hex bolt, stainless 0,45
direction?
string
"tsv-to-csv" (default) or "csv-to-tsv".
e.g. tsv-to-csv
delimiter?
string
The delimiter on the CSV side: "," (default) or ";" for Excel in the Netherlands, Germany, France and Spain.
e.g. ,
crlf?
boolean
End rows with CRLF instead of a line feed. Defaults to false.
e.g. false
byteOrderMark?
boolean
Start the output with a UTF-8 byte order mark. Excel wants it, databases and importers do not. Defaults to false.
e.g. false
trailingNewline?
boolean
End the last row with a line ending too. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "result": "product,description,price\nAB-12,\"Hex bolt, stainless\",\"0,45\"",
    "rows": 2,
    "columns": 3,
    "quotedFields": 2,
    "raggedLines": [],
    "delimiter": ","
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool tsv_to_csv (TSV to CSV) with text: product	description	price
AB-12	Hex bolt, stainless	0,45, direction: tsv-to-csv, delimiter: ,, crlf: false, byteOrderMark: false, trailingNewline: false.

The assistant then makes this tool call:

{
  "name": "tsv_to_csv",
  "arguments": {
    "text": "product\tdescription\tprice\nAB-12\tHex bolt, stainless\t0,45",
    "direction": "tsv-to-csv",
    "delimiter": ",",
    "crlf": false,
    "byteOrderMark": false,
    "trailingNewline": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/tsv-to-csv \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"product\tdescription\tprice\nAB-12\tHex bolt, stainless\t0,45","direction":"tsv-to-csv","delimiter":",","crlf":false,"byteOrderMark":false,"trailingNewline":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/tsv-to-csv", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "product\tdescription\tprice\nAB-12\tHex bolt, stainless\t0,45",
    "direction": "tsv-to-csv",
    "delimiter": ",",
    "crlf": false,
    "byteOrderMark": false,
    "trailingNewline": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/tsv-to-csv",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"product\tdescription\tprice\nAB-12\tHex bolt, stainless\t0,45","direction":"tsv-to-csv","delimiter":",","crlf":false,"byteOrderMark":false,"trailingNewline":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/tsv-to-csv · Page: /tools/tsv-to-csv

CSV Column Extractorpagecsv-column-extractorcsv_extract_columns1 credit a call

Keep, drop or reorder the columns of a CSV. Columns are named by header text or by 1-based position, and the order they are asked for is the order they come back in, so the same call also reorders. The delimiter is detected when not given, quoted fields holding commas and line breaks survive, and the result is either CSV or one value per line.

What it takes

csv
string
The CSV text to read.
e.g. name,email,city Alice,alice@example.com,Amsterdam Bob,bob@example.com,Utrecht
columns?
array
Which columns to take, by header name or 1-based position, in the order wanted. Leave it out to take every column.
e.g. ["city","name"]
exclude?
boolean
Drop the named columns instead of keeping them. Defaults to false.
e.g. false
delimiter?
string
The field separator: a single character, or "auto" (default) to detect comma, semicolon, tab or pipe from the first line.
e.g. auto
firstRowHeader?
boolean
Whether the first row holds the column names. Defaults to true. Without it, columns are labelled Column 1, Column 2 and so on.
e.g. true
format?
string
"csv" (default) keeps the table with its header, "values" writes one value per line with no header.
e.g. csv

What comes back

{
  "ok": true,
  "data": {
    "result": "city,name\nAmsterdam,Alice\nUtrecht,Bob",
    "headers": [
      "city",
      "name"
    ],
    "columns": 2,
    "rows": 2,
    "delimiter": ","
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool csv_extract_columns (CSV Column Extractor) with csv: name,email,city
Alice,alice@example.com,Amsterdam
Bob,bob..., columns: ["city","name"], exclude: false, delimiter: auto, firstRowHeader: true, format: csv.

The assistant then makes this tool call:

{
  "name": "csv_extract_columns",
  "arguments": {
    "csv": "name,email,city\nAlice,alice@example.com,Amsterdam\nBob,bob@example.com,Utrecht",
    "columns": [
      "city",
      "name"
    ],
    "exclude": false,
    "delimiter": "auto",
    "firstRowHeader": true,
    "format": "csv"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/csv-column-extractor \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"csv":"name,email,city\nAlice,alice@example.com,Amsterdam\nBob,bob@example.com,Utrecht","columns":["city","name"],"exclude":false,"delimiter":"auto","firstRowHeader":true,"format":"csv"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/csv-column-extractor", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "csv": "name,email,city\nAlice,alice@example.com,Amsterdam\nBob,bob@example.com,Utrecht",
    "columns": [
      "city",
      "name"
    ],
    "exclude": false,
    "delimiter": "auto",
    "firstRowHeader": true,
    "format": "csv"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/csv-column-extractor",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"csv":"name,email,city\nAlice,alice@example.com,Amsterdam\nBob,bob@example.com,Utrecht","columns":["city","name"],"exclude":false,"delimiter":"auto","firstRowHeader":true,"format":"csv"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/csv-column-extractor · Page: /tools/csv-column-extractor

Developer

URL Encoder/Decoderpageurl-encoderurl_encode1 credit a call

Percent-encode a string for use in a URL, or decode one back to plain text.

What it takes

input
string
The text to encode, or the encoded text to decode.
e.g. hello world & more
action?
string
"encode" (default) or "decode".
e.g. encode

What comes back

{
  "ok": true,
  "data": {
    "output": "hello%20world%20%26%20more",
    "action": "encode"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool url_encode (URL Encoder/Decoder) with input: hello world & more, action: encode.

The assistant then makes this tool call:

{
  "name": "url_encode",
  "arguments": {
    "input": "hello world & more",
    "action": "encode"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/url-encoder \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":"hello world & more","action":"encode"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/url-encoder", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "input": "hello world & more",
    "action": "encode"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/url-encoder",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"input":"hello world & more","action":"encode"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/url-encoder · Page: /tools/url-encoder

Base64 Encode/Decodepagebase64base641 credit a call

Encode text to Base64 or decode Base64 back to text, byte for byte, with UTF-8 handled correctly.

What it takes

input
string
The text to encode, or the Base64 string to decode.
e.g. ToolForte
action?
string
"encode" (default) or "decode".
e.g. encode

What comes back

{
  "ok": true,
  "data": {
    "output": "VG9vbEZvcnRl",
    "action": "encode"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool base64 (Base64 Encode/Decode) with input: ToolForte, action: encode.

The assistant then makes this tool call:

{
  "name": "base64",
  "arguments": {
    "input": "ToolForte",
    "action": "encode"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/base64 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":"ToolForte","action":"encode"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/base64", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "input": "ToolForte",
    "action": "encode"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/base64",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"input":"ToolForte","action":"encode"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/base64 · Page: /tools/base64-encoder

Regex Testerpageregex-testertest_regex1 credit a call

Run a regular expression against a string in a real JavaScript engine and return every match with its captured groups.

What it takes

pattern
string
The regex source, without the surrounding slashes.
e.g. \b\w+@\w+\.\w+\b
test_string
string
The text to run the pattern against.
e.g. write to ada@example.com today
flags?
string
Regex flags such as "gi". Defaults to "g".
e.g. g

What comes back

{
  "ok": true,
  "data": {
    "matches": [
      {
        "match": "ada@example.com",
        "index": 9,
        "groups": []
      }
    ],
    "count": 1
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool test_regex (Regex Tester) with pattern: \b\w+@\w+\.\w+\b, test_string: write to ada@example.com today, flags: g.

The assistant then makes this tool call:

{
  "name": "test_regex",
  "arguments": {
    "pattern": "\\b\\w+@\\w+\\.\\w+\\b",
    "test_string": "write to ada@example.com today",
    "flags": "g"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/regex-tester \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pattern":"\\b\\w+@\\w+\\.\\w+\\b","test_string":"write to ada@example.com today","flags":"g"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/regex-tester", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "pattern": "\\b\\w+@\\w+\\.\\w+\\b",
    "test_string": "write to ada@example.com today",
    "flags": "g"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/regex-tester",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"pattern":"\\b\\w+@\\w+\\.\\w+\\b","test_string":"write to ada@example.com today","flags":"g"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/regex-tester · Page: /tools/regex-tester

Cron Parserpagecron-parserparse_cron1 credit a call

Explain a five-field cron expression in plain English and list the next times it fires.

What it takes

expression
string
A five-field cron expression: minute, hour, day of month, month, day of week.
e.g. 0 9 * * 1

What comes back

{
  "ok": true,
  "data": {
    "valid": true,
    "description": "at 09:00, on Monday",
    "nextRuns": [
      "2026-09-07T09:00:00.000Z"
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool parse_cron (Cron Parser) with expression: 0 9 * * 1.

The assistant then makes this tool call:

{
  "name": "parse_cron",
  "arguments": {
    "expression": "0 9 * * 1"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/cron-parser \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expression":"0 9 * * 1"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/cron-parser", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "expression": "0 9 * * 1"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/cron-parser",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"expression":"0 9 * * 1"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/cron-parser · Page: /tools/cron-parser

UUID Generatorpageuuid-generatorgenerate_uuids1 credit a call

Generate cryptographically random UUID v4 or sortable ULID identifiers in the display format you need.

What it takes

count?
number
How many to generate, 1 to 100. Defaults to 1.
e.g. 3
format?
string
"uuid" (default) for UUID v4, or "ulid".
e.g. uuid
display_format?
string
How to write them: "default", "no-dashes", "braces" or "urn".
e.g. default

What comes back

{
  "ok": true,
  "data": {
    "values": [
      "b7f9c1d2-3e4a-4b5c-8d6e-7f8091a2b3c4"
    ],
    "format": "uuid"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_uuids (UUID) with count: 3, format: uuid, display_format: default.

The assistant then makes this tool call:

{
  "name": "generate_uuids",
  "arguments": {
    "count": 3,
    "format": "uuid",
    "display_format": "default"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/uuid-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count":3,"format":"uuid","display_format":"default"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/uuid-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "count": 3,
    "format": "uuid",
    "display_format": "default"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/uuid-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"count":3,"format":"uuid","display_format":"default"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/uuid-generator · Page: /tools/uuid-generator

SQL Formatterpagesql-formatterformat_sql1 credit a call

Pretty-print a SQL statement: keywords in upper case, each major clause (SELECT, FROM, WHERE, JOIN, GROUP BY, ORDER BY and so on) on its own line, and indentation inside CASE and parentheses. String literals are left untouched. A formatter, not a parser: it does not check that the SQL is valid.

What it takes

sql
string
The SQL statement to format.
e.g. select id, name from users where active = 1 and role = 'admin' order by name

What comes back

{
  "ok": true,
  "data": {
    "sql": "SELECT id, name\nFROM users\nWHERE active = 1\nAND role = 'admin'\nORDER BY name"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool format_sql (SQL) with sql: select id, name from users where active = 1 and role = 'a....

The assistant then makes this tool call:

{
  "name": "format_sql",
  "arguments": {
    "sql": "select id, name from users where active = 1 and role = 'admin' order by name"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/sql-formatter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sql":"select id, name from users where active = 1 and role = 'admin' order by name"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/sql-formatter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "sql": "select id, name from users where active = 1 and role = 'admin' order by name"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/sql-formatter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"sql":"select id, name from users where active = 1 and role = 'admin' order by name"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/sql-formatter · Page: /tools/sql-formatter

HTML Entity Encoderpagehtml-entity-encoderhtml_entities1 credit a call

Encode text as HTML entities or decode entities back to text. Encoding always covers &, <, >, quotes and common typographic characters, and can cover every non-ASCII character too, named where HTML has a name (&eacute;) and numeric otherwise. Decoding reads numeric references and HTML 4 named entities; unknown names are left as they are.

What it takes

text
string
The text to encode, or the entities to decode.
e.g. <a href="x">Tom & Jerry</a>
mode?
string
"encode" (default) turns characters into entities, "decode" turns entities back into text.
e.g. encode
encodeNonAscii?
boolean
When encoding, also encode every character above ASCII, such as accented letters. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "output": "&lt;a href=&quot;x&quot;&gt;Tom &amp; Jerry&lt;/a&gt;",
    "mode": "encode"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool html_entities (HTML Entity) with text: <a href="x">Tom & Jerry</a>, mode: encode, encodeNonAscii: false.

The assistant then makes this tool call:

{
  "name": "html_entities",
  "arguments": {
    "text": "<a href=\"x\">Tom & Jerry</a>",
    "mode": "encode",
    "encodeNonAscii": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/html-entity-encoder \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"<a href=\"x\">Tom & Jerry</a>","mode":"encode","encodeNonAscii":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/html-entity-encoder", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "<a href=\"x\">Tom & Jerry</a>",
    "mode": "encode",
    "encodeNonAscii": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/html-entity-encoder",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"<a href=\"x\">Tom & Jerry</a>","mode":"encode","encodeNonAscii":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/html-entity-encoder · Page: /tools/html-entity-encoder

JSON to TypeScriptpagejson-to-typescriptjson_to_typescript1 credit a call

Derive TypeScript interfaces from a JSON sample. Nested objects become their own interfaces named after their key, arrays become typed arrays (a union when the items differ), null stays null, and properties can be made optional or readonly.

What it takes

json
string
A JSON sample to derive the types from, as a string.
e.g. {"id":1,"name":"Ada","address":{"city":"Utrecht"},"tags":["a","b"]}
rootName?
string
Name of the top-level interface or type. Defaults to "Root".
e.g. User
exportInterfaces?
boolean
Prefix every interface with "export". Defaults to true.
e.g. true
optionalProps?
boolean
Mark every property optional with "?". Defaults to false.
e.g. false
readonlyProps?
boolean
Mark every property "readonly". Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "typescript": "export interface Address {\n  city: string;\n}\n\nexport interface User {\n  id: number;\n  name: string;\n  address: Address;\n  tags: string[];\n}",
    "declarations": 2
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool json_to_typescript (JSON to TypeScript) with json: {"id":1,"name":"Ada","address":{"city":"Utrecht"},"tags":..., rootName: User, exportInterfaces: true, optionalProps: false, readonlyProps: false.

The assistant then makes this tool call:

{
  "name": "json_to_typescript",
  "arguments": {
    "json": "{\"id\":1,\"name\":\"Ada\",\"address\":{\"city\":\"Utrecht\"},\"tags\":[\"a\",\"b\"]}",
    "rootName": "User",
    "exportInterfaces": true,
    "optionalProps": false,
    "readonlyProps": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/json-to-typescript \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"json":"{\"id\":1,\"name\":\"Ada\",\"address\":{\"city\":\"Utrecht\"},\"tags\":[\"a\",\"b\"]}","rootName":"User","exportInterfaces":true,"optionalProps":false,"readonlyProps":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/json-to-typescript", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "json": "{\"id\":1,\"name\":\"Ada\",\"address\":{\"city\":\"Utrecht\"},\"tags\":[\"a\",\"b\"]}",
    "rootName": "User",
    "exportInterfaces": true,
    "optionalProps": false,
    "readonlyProps": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/json-to-typescript",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"json":"{\"id\":1,\"name\":\"Ada\",\"address\":{\"city\":\"Utrecht\"},\"tags\":[\"a\",\"b\"]}","rootName":"User","exportInterfaces":true,"optionalProps":false,"readonlyProps":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/json-to-typescript · Page: /tools/json-to-typescript

Hash Generatorpagehash-generatorhash_text1 credit a call

Hash a text with SHA-1, SHA-256, SHA-384 or SHA-512 and return the hex digest, or all four at once. Text is hashed as UTF-8. No MD5: it is broken and Web Crypto does not offer it.

What it takes

text
string
The text to hash. Hashed as UTF-8, so accents and emoji are fine.
e.g. hello world
algorithm?
string
One of "SHA-1", "SHA-256", "SHA-384", "SHA-512", or "all" (default) for every one of them.
e.g. SHA-256

What comes back

{
  "ok": true,
  "data": {
    "algorithms": [
      "SHA-256"
    ],
    "hashes": {
      "SHA-256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
    },
    "byteLength": 11
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool hash_text (Hash) with text: hello world, algorithm: SHA-256.

The assistant then makes this tool call:

{
  "name": "hash_text",
  "arguments": {
    "text": "hello world",
    "algorithm": "SHA-256"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/hash-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"hello world","algorithm":"SHA-256"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/hash-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "hello world",
    "algorithm": "SHA-256"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/hash-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"text":"hello world","algorithm":"SHA-256"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/hash-generator · Page: /tools/hash-generator

JWT Decoderpagejwt-decoderdecode_jwt1 credit a call

Decode a JSON Web Token into its header and payload, and explain the exp, iat and nbf claims as ISO dates with an expired flag. The signature is returned but never verified.

What it takes

token
string
The JWT to decode, exactly as you received it.
e.g. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpv...
now?
string
When to check expiry, as unix seconds or an ISO 8601 date. Leave out to use the current time.
e.g. 2026-09-07T12:00:00Z

What comes back

{
  "ok": true,
  "data": {
    "header": {
      "alg": "HS256",
      "typ": "JWT"
    },
    "payload": {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    },
    "signature": "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "expiresAt": null,
    "issuedAt": {
      "unix": 1516239022,
      "iso": "2018-01-18T01:30:22.000Z"
    },
    "notBefore": null,
    "expired": null,
    "checkedAt": "2026-09-07T12:00:00.000Z",
    "verified": false
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool decode_jwt (JWT) with token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3..., now: 2026-09-07T12:00:00Z.

The assistant then makes this tool call:

{
  "name": "decode_jwt",
  "arguments": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "now": "2026-09-07T12:00:00Z"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/jwt-decoder \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c","now":"2026-09-07T12:00:00Z"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/jwt-decoder", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "now": "2026-09-07T12:00:00Z"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/jwt-decoder",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c","now":"2026-09-07T12:00:00Z"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/jwt-decoder · Page: /tools/jwt-decoder

Number Base Converterpagenumber-base-converterconvert_number_base1 credit a call

Convert a whole number from one base to another, any base 2 to 36, and also return its binary, octal, decimal and hexadecimal forms. Exact for numbers of any size, no rounding.

What it takes

value
string
The number to convert, written in fromBase.
e.g. 255
fromBase?
number
Base of the input, 2 to 36. Defaults to 10.
e.g. 10
toBase?
number
Base of the output, 2 to 36. Defaults to 16.
e.g. 2

What comes back

{
  "ok": true,
  "data": {
    "input": "255",
    "fromBase": 10,
    "toBase": 2,
    "output": "11111111",
    "negative": false,
    "binary": "11111111",
    "octal": "377",
    "decimal": "255",
    "hexadecimal": "FF"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_number_base (Number Base) with value: 255, fromBase: 10, toBase: 2.

The assistant then makes this tool call:

{
  "name": "convert_number_base",
  "arguments": {
    "value": "255",
    "fromBase": 10,
    "toBase": 2
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/number-base-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":"255","fromBase":10,"toBase":2}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/number-base-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "value": "255",
    "fromBase": 10,
    "toBase": 2
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/number-base-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"value":"255","fromBase":10,"toBase":2},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/number-base-converter · Page: /tools/number-base-converter

Chmod Calculatorpagechmod-calculatorchmod1 credit a call

Convert Unix file permissions between octal (755) and symbolic (rwxr-xr-x) form. Returns both, a read/write/execute breakdown for owner, group and others, and the chmod command to apply them.

What it takes

permissions
string
The permissions in either form: 755 or rwxr-xr-x.
e.g. 755

What comes back

{
  "ok": true,
  "data": {
    "input": "755",
    "octal": "755",
    "symbolic": "rwxr-xr-x",
    "owner": {
      "read": true,
      "write": true,
      "execute": true,
      "octal": 7,
      "symbolic": "rwx"
    },
    "group": {
      "read": true,
      "write": false,
      "execute": true,
      "octal": 5,
      "symbolic": "r-x"
    },
    "others": {
      "read": true,
      "write": false,
      "execute": true,
      "octal": 5,
      "symbolic": "r-x"
    },
    "command": "chmod 755 <file>"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool chmod (Chmod) with permissions: 755.

The assistant then makes this tool call:

{
  "name": "chmod",
  "arguments": {
    "permissions": "755"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/chmod-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"permissions":"755"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/chmod-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "permissions": "755"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/chmod-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"permissions":"755"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/chmod-calculator · Page: /tools/chmod-calculator

HTTP Status Codespagehttp-status-codeshttp_status1 credit a call

Look up what an HTTP status code means. Give a code (404), a class (4xx) or a word (timeout) and get the name, class, one-line meaning, typical use case and RFC reference for every match.

What it takes

query
string
The code, class or word to look up: 404, 5xx or 'redirect'.
e.g. 404

What comes back

{
  "ok": true,
  "data": {
    "query": "404",
    "found": true,
    "count": 1,
    "matches": [
      {
        "code": 404,
        "name": "Not Found",
        "class": "4xx",
        "className": "Client Error",
        "description": "The server cannot find the requested resource. The URL is not recognized.",
        "useCase": "Deleted pages, typos in URLs, resources that never existed. Most common HTTP error.",
        "rfc": "RFC 9110"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool http_status (HTTP Status Codes) with query: 404.

The assistant then makes this tool call:

{
  "name": "http_status",
  "arguments": {
    "query": "404"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/http-status-codes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"404"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/http-status-codes", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "query": "404"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/http-status-codes",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"query":"404"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/http-status-codes · Page: /tools/http-status-codes

Text to Binarypagetext-to-binarytext_to_binary1 credit a call

Turn text into its UTF-8 bytes written as binary, hexadecimal, octal and decimal, or read those numbers back into text. The unit is the byte, not the character, so an accented letter is two groups and an emoji four. Both directions return all four bases at once, and decoding rejects a value that is not a byte or a byte sequence that is not valid UTF-8.

What it takes

input
string
The text to encode, or the numbers to decode separated by spaces, commas or line breaks.
e.g. Hi
action?
string
"encode" (default) reads text, "decode" reads numbers.
e.g. encode
format?
string
Which base the input is in when decoding: "binary" (default), "hex", "octal" or "decimal". Ignored when encoding.
e.g. binary
separator?
string
What goes between two bytes in the output: "space" (default), "none", "comma" or "newline".
e.g. space

What comes back

{
  "ok": true,
  "data": {
    "text": "Hi",
    "binary": "01001000 01101001",
    "hex": "48 69",
    "octal": "110 151",
    "decimal": "72 105",
    "characters": 2,
    "bytes": 2,
    "bits": 16
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool text_to_binary (Text to Binary) with input: Hi, action: encode, format: binary, separator: space.

The assistant then makes this tool call:

{
  "name": "text_to_binary",
  "arguments": {
    "input": "Hi",
    "action": "encode",
    "format": "binary",
    "separator": "space"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/text-to-binary \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":"Hi","action":"encode","format":"binary","separator":"space"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/text-to-binary", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "input": "Hi",
    "action": "encode",
    "format": "binary",
    "separator": "space"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/text-to-binary",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"input":"Hi","action":"encode","format":"binary","separator":"space"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/text-to-binary · Page: /tools/text-to-binary

Design

Color Converterpagecolor-converterconvert_color1 credit a call

Convert one colour between HEX, RGB and HSL, accepting any of those three as input.

What it takes

color
string
The colour to convert: hex (#ff0000), rgb(255,0,0) or hsl(0,100%,50%).
e.g. #c5f04a

What comes back

{
  "ok": true,
  "data": {
    "hex": "#c5f04a",
    "rgb": {
      "r": 197,
      "g": 240,
      "b": 74
    },
    "hsl": {
      "h": 75,
      "s": 85,
      "l": 62
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_color (Color) with color: #c5f04a.

The assistant then makes this tool call:

{
  "name": "convert_color",
  "arguments": {
    "color": "#c5f04a"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/color-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"color":"#c5f04a"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/color-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "color": "#c5f04a"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/color-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"color":"#c5f04a"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/color-converter · Page: /tools/color-converter

Color Contrast Checkerpagecolor-contrast-checkercolor_contrast1 credit a call

Compute the WCAG 2 contrast ratio between a text colour and a background colour and say whether it passes AA and AAA for normal and large text. Accepts hex, rgb() or hsl(), and suggests a nearby colour when it fails.

What it takes

foreground
string
The text colour, e.g. #1e293b.
e.g. #1e293b
background
string
The colour behind the text, e.g. #ffffff.
e.g. #ffffff

What comes back

{
  "ok": true,
  "data": {
    "foreground": "#1e293b",
    "background": "#ffffff",
    "ratio": 14.63,
    "ratioText": "14.63:1",
    "aa": {
      "normalText": true,
      "largeText": true
    },
    "aaa": {
      "normalText": true,
      "largeText": true
    },
    "suggestions": []
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool color_contrast (Color Contrast) with foreground: #1e293b, background: #ffffff.

The assistant then makes this tool call:

{
  "name": "color_contrast",
  "arguments": {
    "foreground": "#1e293b",
    "background": "#ffffff"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/color-contrast-checker \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"foreground":"#1e293b","background":"#ffffff"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/color-contrast-checker", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "foreground": "#1e293b",
    "background": "#ffffff"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/color-contrast-checker",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"foreground":"#1e293b","background":"#ffffff"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/color-contrast-checker · Page: /tools/color-contrast-checker

Security

Password Strengthpagepassword-strengthpassword_strength1 credit a call

Score a password on entropy and character variety, and estimate how long it would take to crack.

What it takes

password
string
The password to analyse, at most 1000 characters. It is never stored.
e.g. correct-horse-battery-staple

What comes back

{
  "ok": true,
  "data": {
    "score": 4,
    "strength": "very-strong",
    "entropy": 132.6,
    "crackTime": "centuries"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool password_strength (Password Strength) with password: correct-horse-battery-staple.

The assistant then makes this tool call:

{
  "name": "password_strength",
  "arguments": {
    "password": "correct-horse-battery-staple"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/password-strength \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"password":"correct-horse-battery-staple"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/password-strength", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "password": "correct-horse-battery-staple"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/password-strength",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"password":"correct-horse-battery-staple"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/password-strength · Page: /tools/password-strength-tester

Password Generatorpagepassword-generatorgenerate_password1 credit a call

Generate one or more random passwords of a chosen length from lower case, upper case, digits and symbols, optionally without look-alike characters. Returns the passwords with their entropy in bits and a rough crack time.

What it takes

length?
number
How many characters each password has, 4 to 128. Defaults to 16.
e.g. 16
uppercase?
boolean
Use capital letters. Defaults to true.
e.g. true
lowercase?
boolean
Use small letters. Defaults to true.
e.g. true
numbers?
boolean
Use digits. Defaults to true.
e.g. true
symbols?
boolean
Use punctuation symbols. Defaults to true.
e.g. true
excludeAmbiguous?
boolean
Skip look-alike characters such as l, 1, I, O and 0. Defaults to false.
e.g. false
count?
number
How many passwords to return, 1 to 50. Defaults to 1.
e.g. 1

What comes back

{
  "ok": true,
  "data": {
    "passwords": [
      "k7#Qm2$vLp9!Xw4Z"
    ],
    "length": 16,
    "charsetSize": 88,
    "entropyBits": 103,
    "strength": "Very strong",
    "crackTime": "32B+ years"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_password (Password) with length: 16, uppercase: true, lowercase: true, numbers: true, symbols: true, excludeAmbiguous: false, count: 1.

The assistant then makes this tool call:

{
  "name": "generate_password",
  "arguments": {
    "length": 16,
    "uppercase": true,
    "lowercase": true,
    "numbers": true,
    "symbols": true,
    "excludeAmbiguous": false,
    "count": 1
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/password-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"length":16,"uppercase":true,"lowercase":true,"numbers":true,"symbols":true,"excludeAmbiguous":false,"count":1}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/password-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "length": 16,
    "uppercase": true,
    "lowercase": true,
    "numbers": true,
    "symbols": true,
    "excludeAmbiguous": false,
    "count": 1
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/password-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"length":16,"uppercase":true,"lowercase":true,"numbers":true,"symbols":true,"excludeAmbiguous":false,"count":1},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/password-generator · Page: /tools/password-generator

Checks and validation

Email Validatoremail-validatorvalidate_email1 credit a call

Check that an email address is syntactically valid and warn about likely typos in the domain.

What it takes

email
string
The address to check.
e.g. user@gmial.com

What comes back

{
  "ok": true,
  "data": {
    "valid": true,
    "email": "user@gmial.com",
    "local": "user",
    "domain": "gmial.com",
    "warnings": [
      "Did you mean gmail.com?"
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool validate_email (Email) with email: user@gmial.com.

The assistant then makes this tool call:

{
  "name": "validate_email",
  "arguments": {
    "email": "user@gmial.com"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/email-validator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@gmial.com"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/email-validator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "email": "user@gmial.com"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/email-validator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"email":"user@gmial.com"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/email-validator

Card Number Validatorpagecredit-card-validatorvalidate_card_number1 credit a call

Check a payment card number the way a checkout form does: the Luhn checksum that every major network uses to catch a mistyped digit, and the scheme behind the prefix (Visa, Mastercard, Amex, Discover, JCB, Diners). It is a format check and nothing more: it says nothing about whether a card exists, is active or has funds. The number is never logged, stored or returned, and the result shows at most the last four digits.

What it takes

cardNumber
string
The card number to check, 13 to 19 digits. Grouping characters are ignored.
e.g. 4242 4242 4242 4242

What comes back

{
  "ok": true,
  "data": {
    "valid": true,
    "luhnValid": true,
    "scheme": "Visa",
    "length": 16,
    "masked": "**** **** **** 4242",
    "note": "Format check only. Nothing is logged or stored."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool validate_card_number (Card Number) with cardNumber: 4242 4242 4242 4242.

The assistant then makes this tool call:

{
  "name": "validate_card_number",
  "arguments": {
    "cardNumber": "4242 4242 4242 4242"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/credit-card-validator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"cardNumber":"4242 4242 4242 4242"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/credit-card-validator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "cardNumber": "4242 4242 4242 4242"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/credit-card-validator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"cardNumber":"4242 4242 4242 4242"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/credit-card-validator · Page: /tools/credit-card-validator

Money and finance

IBAN Validatorpageiban-validatorvalidate_iban1 credit a call

Check whether an IBAN is well formed: the mod-97 checksum, the country's own length, and the character layout each position must have. Splits the number into its parts, verifies the national check digit for twelve countries, and names the bank for Dutch IBANs. A format check, not a bank check.

What it takes

iban
string
The IBAN to check. Spaces and lower case are fine.
e.g. NL91 ABNA 0417 1643 00

What comes back

{
  "ok": true,
  "data": {
    "valid": true,
    "iban": "NL91ABNA0417164300",
    "country": "NL",
    "countryName": "Netherlands",
    "checkDigits": "91",
    "bankCode": "ABNA",
    "accountNumber": "0417164300",
    "institution": {
      "name": "ABN AMRO",
      "kind": "bank"
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool validate_iban (IBAN) with iban: NL91 ABNA 0417 1643 00.

The assistant then makes this tool call:

{
  "name": "validate_iban",
  "arguments": {
    "iban": "NL91 ABNA 0417 1643 00"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/iban-validator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"iban":"NL91 ABNA 0417 1643 00"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/iban-validator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "iban": "NL91 ABNA 0417 1643 00"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/iban-validator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"iban":"NL91 ABNA 0417 1643 00"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/iban-validator · Page: /tools/iban-validator

VAT Calculatorpagevat-calculatorcalculate_vat1 credit a call

Add VAT to a net amount or extract the VAT already inside a gross amount, at any rate, rounded to cents.

What it takes

amount
number
The amount to work from: net when adding, gross when extracting.
e.g. 100
rate
number
VAT percentage, 0 to 100. The Dutch high rate is 21.
e.g. 21
mode?
string
"add" (default) to add VAT on top, "extract" to split a gross amount.
e.g. add

What comes back

{
  "ok": true,
  "data": {
    "net": 100,
    "vat": 21,
    "gross": 121,
    "rate": 21
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool calculate_vat (VAT) with amount: 100, rate: 21, mode: add.

The assistant then makes this tool call:

{
  "name": "calculate_vat",
  "arguments": {
    "amount": 100,
    "rate": 21,
    "mode": "add"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/vat-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":100,"rate":21,"mode":"add"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/vat-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 100,
    "rate": 21,
    "mode": "add"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/vat-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":100,"rate":21,"mode":"add"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/vat-calculator · Page: /tools/vat-calculator

VAT Number Format Checkpagevat-number-checkcheck_vat_number_format1 credit a call

Check whether a VAT number matches the official format for its EU, GB or CH country. Syntax only, not registration.

What it takes

vatNumber
string
The VAT number including its country prefix. Spaces and dots are ignored.
e.g. NL123456789B01

What comes back

{
  "ok": true,
  "data": {
    "input": "NL123456789B01",
    "normalized": "NL123456789B01",
    "country": "NL",
    "validFormat": true,
    "note": "Format matches the Dutch pattern."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool check_vat_number_format (VAT Number Format Check) with vatNumber: NL123456789B01.

The assistant then makes this tool call:

{
  "name": "check_vat_number_format",
  "arguments": {
    "vatNumber": "NL123456789B01"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/vat-number-check \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"vatNumber":"NL123456789B01"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/vat-number-check", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "vatNumber": "NL123456789B01"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/vat-number-check",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"vatNumber":"NL123456789B01"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/vat-number-check · Page: /tools/vat-number-checker

Percentage Calculatorpagepercentage-calculatorpercentage1 credit a call

Answer one percentage question from two numbers: what x% of y is, what percent x is of y, the percentage change from x to y, or x increased or decreased by y%. Returns the number and a sentence stating it.

What it takes

mode
string
One of percentOf, whatPercent, change, increase or decrease.
e.g. percentOf
x
number
First number. For percentOf this is the percentage, for the other modes the starting amount.
e.g. 15
y
number
Second number. The base amount, the new value for change, or the percentage for increase and decrease.
e.g. 200

What comes back

{
  "ok": true,
  "data": {
    "mode": "percentOf",
    "x": 15,
    "y": 200,
    "result": 30,
    "resultIsPercent": false,
    "sentence": "15% of 200 is 30."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool percentage (Percentage) with mode: percentOf, x: 15, y: 200.

The assistant then makes this tool call:

{
  "name": "percentage",
  "arguments": {
    "mode": "percentOf",
    "x": 15,
    "y": 200
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/percentage-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"percentOf","x":15,"y":200}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/percentage-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "percentOf",
    "x": 15,
    "y": 200
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/percentage-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"percentOf","x":15,"y":200},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/percentage-calculator · Page: /tools/percentage-calculator

Compound Interest Calculatorpagecompound-interest-calculatorcompound_interest1 credit a call

Grow a starting amount at an annual rate for a number of years, compounding monthly, quarterly or annually, with an optional monthly contribution. Returns the future value, total contributed, total interest and a year-by-year table.

What it takes

principal
number
The amount you start with.
e.g. 10000
annualRatePercent
number
Yearly interest rate in percent.
e.g. 7
years
number
Number of years to let it grow, a whole number.
e.g. 10
compoundsPerYear?
number
Compounding periods per year: 12 for monthly (default), 4 for quarterly, 1 for annually.
e.g. 12
monthlyContribution?
number
Amount added every month on top of the principal. Defaults to 0.
e.g. 100

What comes back

{
  "ok": true,
  "data": {
    "principal": 10000,
    "annualRatePercent": 7,
    "years": 10,
    "compoundsPerYear": 12,
    "monthlyContribution": 100,
    "futureValue": 37506.06,
    "totalContributed": 22000,
    "totalInterest": 15506.06,
    "interestPercent": 41.34,
    "yearly": [
      {
        "year": 1,
        "contributions": 11200,
        "interest": 769.39,
        "balance": 11969.39
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool compound_interest (Compound Interest) with principal: 10000, annualRatePercent: 7, years: 10, compoundsPerYear: 12, monthlyContribution: 100.

The assistant then makes this tool call:

{
  "name": "compound_interest",
  "arguments": {
    "principal": 10000,
    "annualRatePercent": 7,
    "years": 10,
    "compoundsPerYear": 12,
    "monthlyContribution": 100
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/compound-interest-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"principal":10000,"annualRatePercent":7,"years":10,"compoundsPerYear":12,"monthlyContribution":100}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/compound-interest-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "principal": 10000,
    "annualRatePercent": 7,
    "years": 10,
    "compoundsPerYear": 12,
    "monthlyContribution": 100
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/compound-interest-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"principal":10000,"annualRatePercent":7,"years":10,"compoundsPerYear":12,"monthlyContribution":100},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/compound-interest-calculator · Page: /tools/compound-interest-calculator

Loan Calculatorpageloan-calculatorloan_payment1 credit a call

Work out an annuity loan from the amount, annual interest rate and term: the fixed monthly payment, total paid, total interest and an amortisation schedule of up to 360 months showing principal, interest and remaining balance.

What it takes

amount
number
How much is borrowed.
e.g. 250000
annualRatePercent
number
Yearly interest rate in percent.
e.g. 4.5
term
number
How long the loan runs, in years by default.
e.g. 30
termUnit?
string
years (default) or months.
e.g. years

What comes back

{
  "ok": true,
  "data": {
    "amount": 250000,
    "annualRatePercent": 4.5,
    "termMonths": 360,
    "monthlyPayment": 1266.71,
    "totalPaid": 456016.78,
    "totalInterest": 206016.78,
    "interestToPrincipalRatio": 0.82,
    "schedule": [
      {
        "month": 1,
        "payment": 1266.71,
        "principal": 329.21,
        "interest": 937.5,
        "balance": 249670.79
      }
    ],
    "scheduleTruncated": false
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool loan_payment (Loan) with amount: 250000, annualRatePercent: 4.5, term: 30, termUnit: years.

The assistant then makes this tool call:

{
  "name": "loan_payment",
  "arguments": {
    "amount": 250000,
    "annualRatePercent": 4.5,
    "term": 30,
    "termUnit": "years"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/loan-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":250000,"annualRatePercent":4.5,"term":30,"termUnit":"years"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/loan-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 250000,
    "annualRatePercent": 4.5,
    "term": 30,
    "termUnit": "years"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/loan-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":250000,"annualRatePercent":4.5,"term":30,"termUnit":"years"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/loan-calculator · Page: /tools/loan-calculator

Discount Calculatorpagediscount-calculatordiscount1 credit a call

Final price and saving after a discount given as a percentage or a fixed amount, with optional extra stacked discounts applied one after another and optional VAT added on the discounted price. Money is rounded to cents.

What it takes

price
number
The full price before the discount.
e.g. 80
discountPercent?
number
Percentage off. Give this or discountAmount, not both.
e.g. 25
discountAmount?
number
Fixed amount off. Give this or discountPercent, not both.
additionalDiscountPercents?
array
Extra percentages applied one after the other on the reduced price.
e.g. [10]
vatPercent?
number
Tax percentage to add on the discounted price.
e.g. 21

What comes back

{
  "ok": true,
  "data": {
    "originalPrice": 80,
    "discountPercent": 32.5,
    "saving": 26,
    "finalPrice": 54,
    "vatPercent": 21,
    "vatAmount": 11.34,
    "finalPriceWithVat": 65.34,
    "steps": [
      {
        "step": 1,
        "percent": 25,
        "priceAfter": 60
      },
      {
        "step": 2,
        "percent": 10,
        "priceAfter": 54
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool discount (Discount) with price: 80, discountPercent: 25, additionalDiscountPercents: [10], vatPercent: 21.

The assistant then makes this tool call:

{
  "name": "discount",
  "arguments": {
    "price": 80,
    "discountPercent": 25,
    "additionalDiscountPercents": [
      10
    ],
    "vatPercent": 21
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/discount-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"price":80,"discountPercent":25,"additionalDiscountPercents":[10],"vatPercent":21}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/discount-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "price": 80,
    "discountPercent": 25,
    "additionalDiscountPercents": [
      10
    ],
    "vatPercent": 21
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/discount-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"price":80,"discountPercent":25,"additionalDiscountPercents":[10],"vatPercent":21},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/discount-calculator · Page: /tools/discount-calculator

Tip Calculatorpagetip-calculatorsplit_tip1 credit a call

Tip on a restaurant bill at a percentage, the total, and the even split per person. Can round the total up to the next whole unit, in which case the tip absorbs the difference.

What it takes

bill
number
The amount on the bill.
e.g. 86.4
tipPercent?
number
Tip percentage, 15 by default.
e.g. 15
people?
number
Number of people splitting the bill, 1 by default.
e.g. 4
roundUp?
boolean
Round the total up to a whole amount. Off by default.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "bill": 86.4,
    "tipPercent": 15,
    "people": 4,
    "roundUp": false,
    "tip": 12.96,
    "total": 99.36,
    "perPerson": {
      "total": 24.84,
      "tip": 3.24
    },
    "effectiveTipPercent": 15
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool split_tip (Tip) with bill: 86.4, tipPercent: 15, people: 4, roundUp: false.

The assistant then makes this tool call:

{
  "name": "split_tip",
  "arguments": {
    "bill": 86.4,
    "tipPercent": 15,
    "people": 4,
    "roundUp": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/tip-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"bill":86.4,"tipPercent":15,"people":4,"roundUp":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/tip-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "bill": 86.4,
    "tipPercent": 15,
    "people": 4,
    "roundUp": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/tip-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"bill":86.4,"tipPercent":15,"people":4,"roundUp":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/tip-calculator · Page: /tools/tip-calculator

ROI Calculatorpageroi-calculatorroi1 credit a call

Return on investment from the amount invested and the total amount that came back: the gain, the ROI in percent and, when a holding period in years is given, the annualised return. An estimate, not financial advice.

What it takes

invested
number
The amount invested.
e.g. 10000
returned
number
Everything received back, capital included.
e.g. 14000
years?
number
How many years the money was invested, to annualise the return.
e.g. 3

What comes back

{
  "ok": true,
  "data": {
    "invested": 10000,
    "returned": 14000,
    "gain": 4000,
    "roiPercent": 40,
    "years": 3,
    "annualisedPercent": 11.87,
    "note": "Estimates for information only, not financial advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool roi (ROI) with invested: 10000, returned: 14000, years: 3.

The assistant then makes this tool call:

{
  "name": "roi",
  "arguments": {
    "invested": 10000,
    "returned": 14000,
    "years": 3
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/roi-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"invested":10000,"returned":14000,"years":3}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/roi-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "invested": 10000,
    "returned": 14000,
    "years": 3
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/roi-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"invested":10000,"returned":14000,"years":3},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/roi-calculator · Page: /tools/roi-calculator

Break-even Calculatorpagebreak-even-calculatorbreak_even1 credit a call

Break-even point from fixed costs per period, the price per unit and the variable cost per unit: the units and revenue needed to cover costs, the contribution margin, profit at an optional sales volume, and scenarios at half to twice the break-even volume.

What it takes

fixedCosts
number
Fixed costs for the period, such as rent and salaries.
e.g. 5000
variableCostPerUnit
number
What one extra unit costs to make or deliver.
e.g. 10
pricePerUnit
number
What one unit sells for.
e.g. 25
volume?
number
A sales volume in units to calculate the profit for.
e.g. 500

What comes back

{
  "ok": true,
  "data": {
    "fixedCosts": 5000,
    "pricePerUnit": 25,
    "variableCostPerUnit": 10,
    "contributionMargin": 15,
    "contributionMarginPercent": 60,
    "breakEvenUnits": 333.33,
    "breakEvenUnitsRoundedUp": 334,
    "breakEvenRevenue": 8333.33,
    "volume": 500,
    "profitAtVolume": 2500,
    "scenarios": [
      {
        "multiplier": 0.5,
        "units": 167,
        "revenue": 4175,
        "profit": -2495
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool break_even (Break-even) with fixedCosts: 5000, variableCostPerUnit: 10, pricePerUnit: 25, volume: 500.

The assistant then makes this tool call:

{
  "name": "break_even",
  "arguments": {
    "fixedCosts": 5000,
    "variableCostPerUnit": 10,
    "pricePerUnit": 25,
    "volume": 500
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/break-even-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fixedCosts":5000,"variableCostPerUnit":10,"pricePerUnit":25,"volume":500}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/break-even-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "fixedCosts": 5000,
    "variableCostPerUnit": 10,
    "pricePerUnit": 25,
    "volume": 500
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/break-even-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"fixedCosts":5000,"variableCostPerUnit":10,"pricePerUnit":25,"volume":500},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/break-even-calculator · Page: /tools/break-even-calculator

Dutch Inheritance Tax Calculatorpageerfbelasting-calculatordutch_inheritance_tax1 credit a call

Estimate Dutch inheritance tax (erfbelasting) for one heir with the 2026 exemptions and two-bracket rates: give the inherited amount and the relationship to the deceased, get the exemption, taxable amount, tax per bracket, total tax and what the heir keeps.

What it takes

amount
number
What this heir inherits, in euros.
e.g. 100000
heir
string
Who inherits: "partner", "child", "grandchild", "greatGrandchild", "disabledChild", "parent" or "other".
e.g. child

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "exemption": 26230,
    "exemptionApplied": 26230,
    "taxableAmount": 73770,
    "lowBracketTax": 7377,
    "highBracketTax": 0,
    "totalTax": 7377,
    "netReceived": 92623,
    "effectiveRate": 0.07377,
    "notes": [
      "Partners usually count as one person for inheritance tax."
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_inheritance_tax (Dutch Inheritance Tax) with amount: 100000, heir: child.

The assistant then makes this tool call:

{
  "name": "dutch_inheritance_tax",
  "arguments": {
    "amount": 100000,
    "heir": "child"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/erfbelasting-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":100000,"heir":"child"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/erfbelasting-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 100000,
    "heir": "child"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/erfbelasting-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":100000,"heir":"child"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/erfbelasting-calculator · Page: /tools/erfbelasting-calculator

Dutch Gift Tax Calculatorpageschenkbelasting-calculatordutch_gift_tax1 credit a call

Estimate Dutch gift tax (schenkbelasting) with the 2026 exemptions and two-bracket rates: give the gift amount, the relationship to the donor and which exemption applies, get the exemption used, taxable amount, tax per bracket, total tax and what the recipient keeps.

What it takes

amount
number
The gift, in euros.
e.g. 25000
relationship
string
Who receives it: "child" (also used for a partner), "grandchild" or "other".
e.g. child
exemption?
string
The exemption to apply: "annual" (default), "oneOffFree" or "oneOffStudy" (parents to a child aged 18 to 40, once), or "none".
e.g. annual

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "exemptionApplied": 6908,
    "taxableAmount": 18092,
    "lowBracketTax": 1809.2,
    "highBracketTax": 0,
    "totalTax": 1809.2,
    "netReceived": 23190.8,
    "effectiveRate": 0.072368,
    "notes": [
      "Partners count as one donor."
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_gift_tax (Dutch Gift Tax) with amount: 25000, relationship: child, exemption: annual.

The assistant then makes this tool call:

{
  "name": "dutch_gift_tax",
  "arguments": {
    "amount": 25000,
    "relationship": "child",
    "exemption": "annual"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/schenkbelasting-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":25000,"relationship":"child","exemption":"annual"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/schenkbelasting-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 25000,
    "relationship": "child",
    "exemption": "annual"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/schenkbelasting-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":25000,"relationship":"child","exemption":"annual"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/schenkbelasting-calculator · Page: /tools/schenkbelasting-calculator

Dutch WW Duration Calculatorpageww-duration-calculatordutch_ww_duration1 credit a call

Estimate how many months of Dutch unemployment benefit (WW) an employment history gives: one month per year for the first ten years, half a month per year after that, between three and twenty-four months, with the notional years for people born in 1979 or earlier counted automatically.

What it takes

birthYear
number
The year the person was born, 1930 to 2011.
e.g. 1975
workedYearsSince1998
number
Calendar years since 1998 in which the person worked enough days, 0 to 29.
e.g. 20

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "notionalYears": 5,
    "actualYears": 20,
    "totalYears": 25,
    "months": 17.5,
    "uncappedMonths": 17.5,
    "cappedAtMaximum": false,
    "raisedToMinimum": false,
    "note": "This is an estimate."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_ww_duration (Dutch WW Duration) with birthYear: 1975, workedYearsSince1998: 20.

The assistant then makes this tool call:

{
  "name": "dutch_ww_duration",
  "arguments": {
    "birthYear": 1975,
    "workedYearsSince1998": 20
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/ww-duration-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthYear":1975,"workedYearsSince1998":20}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/ww-duration-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "birthYear": 1975,
    "workedYearsSince1998": 20
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/ww-duration-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"birthYear":1975,"workedYearsSince1998":20},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/ww-duration-calculator · Page: /tools/ww-duration-calculator

30% Ruling Calculatorpage30-percent-ruling-calculatordutch_30_percent_ruling1 credit a call

Work out the tax-free allowance under the Dutch 30% ruling for a gross annual salary with the 2026 salary norm and WNT cap, plus a simplified estimate of net pay with and without the ruling and the yearly advantage.

What it takes

grossAnnualSalary
number
Gross salary per year in euros, before the ruling.
e.g. 70000
youngMaster?
boolean
Set true for someone under 30 with a qualifying master's degree. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "grossAnnualSalary": 70000,
    "salaryNorm": 48013,
    "eligible": true,
    "allowancePerYear": 21000,
    "allowancePerMonth": 1750,
    "taxableSalaryWithRuling": 49000,
    "netPerYearWithoutRuling": 49000,
    "netPerYearWithRuling": 58000,
    "netAdvantagePerYear": 9000,
    "cappedByWnt": false,
    "limitedByNorm": false,
    "notes": [
      "Based on 2026 figures."
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_30_percent_ruling (30% Ruling) with grossAnnualSalary: 70000, youngMaster: false.

The assistant then makes this tool call:

{
  "name": "dutch_30_percent_ruling",
  "arguments": {
    "grossAnnualSalary": 70000,
    "youngMaster": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/30-percent-ruling-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"grossAnnualSalary":70000,"youngMaster":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/30-percent-ruling-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "grossAnnualSalary": 70000,
    "youngMaster": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/30-percent-ruling-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"grossAnnualSalary":70000,"youngMaster":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/30-percent-ruling-calculator · Page: /tools/30-percent-ruling-calculator

Dutch Holiday Allowance Calculatorpagedutch-holiday-allowance-calculatordutch_holiday_allowance1 credit a call

Calculate Dutch holiday allowance (vakantiegeld) from a gross monthly salary and the months worked: the gross amount at the given percentage (statutory minimum 8%) and an estimate of the net payout after the special payroll tax rate (bijzonder tarief).

What it takes

monthlySalary
number
Gross salary per month in euros.
e.g. 3500
monthsWorked?
number
How many months of the accrual period were worked, 0 to 12. Defaults to 12.
e.g. 12
allowancePercent?
number
Holiday allowance percentage. Defaults to the statutory 8; some collective agreements pay more.
e.g. 8
specialRatePercent?
number
The special payroll tax rate (bijzonder tarief) printed on the payslip, as a percentage. Defaults to 42.01.
e.g. 42.01

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "grossAllowance": 3360,
    "taxWithheld": 1411.54,
    "netAllowance": 1948.46,
    "allowancePercent": 8,
    "specialRatePercent": 42.01,
    "note": "Based on 2026 figures."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_holiday_allowance (Dutch Holiday Allowance) with monthlySalary: 3500, monthsWorked: 12, allowancePercent: 8, specialRatePercent: 42.01.

The assistant then makes this tool call:

{
  "name": "dutch_holiday_allowance",
  "arguments": {
    "monthlySalary": 3500,
    "monthsWorked": 12,
    "allowancePercent": 8,
    "specialRatePercent": 42.01
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-holiday-allowance-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"monthlySalary":3500,"monthsWorked":12,"allowancePercent":8,"specialRatePercent":42.01}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-holiday-allowance-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "monthlySalary": 3500,
    "monthsWorked": 12,
    "allowancePercent": 8,
    "specialRatePercent": 42.01
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-holiday-allowance-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"monthlySalary":3500,"monthsWorked":12,"allowancePercent":8,"specialRatePercent":42.01},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-holiday-allowance-calculator · Page: /tools/dutch-holiday-allowance-calculator

Dutch Severance Calculatorpagedutch-severance-calculatordutch_severance1 credit a call

Calculate the Dutch statutory transition payment (transitievergoeding) with the 2026 rules: one third of the monthly salary base per year of service, pro rata by day, capped at EUR 102,000 or one annual salary if higher. The base can include 8% holiday allowance and fixed yearly bonuses.

What it takes

monthlySalary
number
Gross salary per month in euros.
e.g. 3500
fixedAnnualBonuses?
number
Fixed yearly components such as a thirteenth month or structural bonus, in euros. Defaults to 0.
e.g. 0
includeHolidayAllowance?
boolean
Whether to add the 8% holiday allowance to the monthly salary. Defaults to true; set false if the salary already includes it.
e.g. true
startDate
string
First day of employment, yyyy-mm-dd.
e.g. 2018-01-01
endDate
string
Last day of employment, yyyy-mm-dd.
e.g. 2026-12-31

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "serviceDays": 3287,
    "serviceYears": 9,
    "monthlyBase": 3780,
    "formulaAmount": 11339.14,
    "statutoryMaximum": 102000,
    "payment": 11339.14,
    "capped": false,
    "note": "Based on 2026 figures."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_severance (Dutch Severance) with monthlySalary: 3500, fixedAnnualBonuses: 0, includeHolidayAllowance: true, startDate: 2018-01-01, endDate: 2026-12-31.

The assistant then makes this tool call:

{
  "name": "dutch_severance",
  "arguments": {
    "monthlySalary": 3500,
    "fixedAnnualBonuses": 0,
    "includeHolidayAllowance": true,
    "startDate": "2018-01-01",
    "endDate": "2026-12-31"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-severance-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"monthlySalary":3500,"fixedAnnualBonuses":0,"includeHolidayAllowance":true,"startDate":"2018-01-01","endDate":"2026-12-31"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-severance-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "monthlySalary": 3500,
    "fixedAnnualBonuses": 0,
    "includeHolidayAllowance": true,
    "startDate": "2018-01-01",
    "endDate": "2026-12-31"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-severance-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"monthlySalary":3500,"fixedAnnualBonuses":0,"includeHolidayAllowance":true,"startDate":"2018-01-01","endDate":"2026-12-31"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-severance-calculator · Page: /tools/dutch-severance-calculator

Dutch Mileage Allowance Calculatorpagedutch-mileage-calculatordutch_mileage_allowance1 credit a call

Calculate a Dutch kilometre reimbursement per week, month and year from a distance per trip and trips per week (or a weekly total), working weeks and a rate, and show how much of it exceeds the 2026 tax-free maximum of EUR 0.25 per km.

What it takes

kmPerTrip?
number
Kilometres for one journey, one way.
e.g. 25
tripsPerWeek?
number
Single journeys per week. Four office days there and back is 8.
e.g. 8
kmPerWeek?
number
Total kilometres per week, as an alternative to kmPerTrip and tripsPerWeek. When given it wins.
e.g. 200
weeksPerYear?
number
Working weeks per year, 1 to 53. Defaults to 46, typical after vacation and public holidays.
e.g. 46
ratePerKm?
number
Reimbursement rate in euros per kilometre. Defaults to the 2026 tax-free maximum of 0.25.
e.g. 0.25

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "weeklyKm": 200,
    "yearlyKm": 9200,
    "perWeek": 50,
    "perMonth": 191.67,
    "perYear": 2300,
    "ratePerKm": 0.25,
    "taxFreeRate": 0.25,
    "aboveTaxFree": false,
    "taxablePartPerYear": 0,
    "note": "Based on 2026 figures."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_mileage_allowance (Dutch Mileage Allowance) with kmPerTrip: 25, tripsPerWeek: 8, kmPerWeek: 200, weeksPerYear: 46, ratePerKm: 0.25.

The assistant then makes this tool call:

{
  "name": "dutch_mileage_allowance",
  "arguments": {
    "kmPerTrip": 25,
    "tripsPerWeek": 8,
    "kmPerWeek": 200,
    "weeksPerYear": 46,
    "ratePerKm": 0.25
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-mileage-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kmPerTrip":25,"tripsPerWeek":8,"kmPerWeek":200,"weeksPerYear":46,"ratePerKm":0.25}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-mileage-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "kmPerTrip": 25,
    "tripsPerWeek": 8,
    "kmPerWeek": 200,
    "weeksPerYear": 46,
    "ratePerKm": 0.25
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-mileage-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"kmPerTrip":25,"tripsPerWeek":8,"kmPerWeek":200,"weeksPerYear":46,"ratePerKm":0.25},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-mileage-calculator · Page: /tools/dutch-mileage-calculator

Mortgage Calculatorpagemortgage-calculatormortgage_payment1 credit a call

Work out the payment on a home loan from the price, the deposit, the rate and the term, paid monthly, bi-weekly or weekly. Returns the payment per period, the total paid, the total interest, the loan-to-value ratio and an amortisation schedule of up to 360 periods showing how each payment splits between principal and interest.

What it takes

homePrice
number
What the property costs.
e.g. 350000
downPayment?
number
The deposit. Defaults to 0, and must stay below the price.
e.g. 70000
annualRatePercent
number
Yearly interest rate in percent.
e.g. 4.5
termYears
number
How many years the mortgage runs.
e.g. 30
paymentFrequency?
string
monthly, biweekly or weekly. Defaults to monthly.
e.g. monthly

What comes back

{
  "ok": true,
  "data": {
    "homePrice": 350000,
    "downPayment": 70000,
    "loanAmount": 280000,
    "annualRatePercent": 4.5,
    "termYears": 30,
    "frequency": "monthly",
    "periodsPerYear": 12,
    "totalPeriods": 360,
    "periodicPayment": 1418.72,
    "totalPayment": 510738.79,
    "totalInterest": 230738.79,
    "loanToValuePercent": 80,
    "schedule": [
      {
        "period": 1,
        "payment": 1418.72,
        "principal": 368.72,
        "interest": 1050,
        "balance": 279631.28
      }
    ],
    "scheduleTruncated": false
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool mortgage_payment (Mortgage) with homePrice: 350000, downPayment: 70000, annualRatePercent: 4.5, termYears: 30, paymentFrequency: monthly.

The assistant then makes this tool call:

{
  "name": "mortgage_payment",
  "arguments": {
    "homePrice": 350000,
    "downPayment": 70000,
    "annualRatePercent": 4.5,
    "termYears": 30,
    "paymentFrequency": "monthly"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/mortgage-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"homePrice":350000,"downPayment":70000,"annualRatePercent":4.5,"termYears":30,"paymentFrequency":"monthly"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/mortgage-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "homePrice": 350000,
    "downPayment": 70000,
    "annualRatePercent": 4.5,
    "termYears": 30,
    "paymentFrequency": "monthly"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/mortgage-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"homePrice":350000,"downPayment":70000,"annualRatePercent":4.5,"termYears":30,"paymentFrequency":"monthly"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/mortgage-calculator · Page: /tools/mortgage-calculator

Simple Interest Calculatorpagesimple-interest-calculatorsimple_interest1 credit a call

Interest at a flat rate on the original principal only, I = P x r x t, over a period given in years or months. Returns the interest, the final amount, and what the same money would have made with annual compounding, so the two methods can be compared before signing anything.

What it takes

principal
number
The starting amount.
e.g. 10000
annualRatePercent
number
Yearly rate in percent.
e.g. 5
time
number
The term, counted in the unit below.
e.g. 3
timeUnit?
string
years or months. Defaults to years.
e.g. years

What comes back

{
  "ok": true,
  "data": {
    "principal": 10000,
    "annualRatePercent": 5,
    "time": 3,
    "timeUnit": "years",
    "timeYears": 3,
    "interest": 1500,
    "totalAmount": 11500,
    "compoundTotalAmount": 11576.25,
    "compoundInterest": 1576.25,
    "compoundAdvantage": 76.25
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool simple_interest (Simple Interest) with principal: 10000, annualRatePercent: 5, time: 3, timeUnit: years.

The assistant then makes this tool call:

{
  "name": "simple_interest",
  "arguments": {
    "principal": 10000,
    "annualRatePercent": 5,
    "time": 3,
    "timeUnit": "years"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/simple-interest-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"principal":10000,"annualRatePercent":5,"time":3,"timeUnit":"years"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/simple-interest-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "principal": 10000,
    "annualRatePercent": 5,
    "time": 3,
    "timeUnit": "years"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/simple-interest-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"principal":10000,"annualRatePercent":5,"time":3,"timeUnit":"years"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/simple-interest-calculator · Page: /tools/simple-interest-calculator

Investment Calculatorpageinvestment-calculatorinvestment_growth1 credit a call

Project a lump sum plus a monthly contribution at a yearly return, compounded monthly with the contribution going in at the start of each month. Returns the final value, everything paid in, the growth, and a year-by-year table of balance and growth.

What it takes

initialInvestment?
number
The starting lump sum. Defaults to 0.
e.g. 10000
monthlyContribution?
number
Amount added every month. Defaults to 0.
e.g. 500
annualReturnPercent
number
Expected yearly return in percent.
e.g. 7
years
number
Years to project, a whole number.
e.g. 20

What comes back

{
  "ok": true,
  "data": {
    "initialInvestment": 10000,
    "monthlyContribution": 500,
    "annualReturnPercent": 7,
    "years": 20,
    "finalValue": 302370.09,
    "totalContributed": 130000,
    "totalGrowth": 172370.09,
    "growthPercent": 57,
    "yearlyBreakdown": [
      {
        "year": 1,
        "contributed": 16000,
        "growth": 955.34,
        "balance": 16955.34
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool investment_growth (Investment) with initialInvestment: 10000, monthlyContribution: 500, annualReturnPercent: 7, years: 20.

The assistant then makes this tool call:

{
  "name": "investment_growth",
  "arguments": {
    "initialInvestment": 10000,
    "monthlyContribution": 500,
    "annualReturnPercent": 7,
    "years": 20
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/investment-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"initialInvestment":10000,"monthlyContribution":500,"annualReturnPercent":7,"years":20}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/investment-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "initialInvestment": 10000,
    "monthlyContribution": 500,
    "annualReturnPercent": 7,
    "years": 20
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/investment-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"initialInvestment":10000,"monthlyContribution":500,"annualReturnPercent":7,"years":20},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/investment-calculator · Page: /tools/investment-calculator

SIP Calculatorpagesip-calculatorsip_returns1 credit a call

Returns on a systematic investment plan: the same amount invested every month for a number of years at an expected annual return, using the annuity due formula Indian SIP calculators publish. Returns the total value, the amount invested, the returns earned and a year-by-year table.

What it takes

monthlyInvestment
number
What goes in every month.
e.g. 5000
expectedAnnualReturnPercent
number
Expected yearly return in percent.
e.g. 12
years
number
How long the plan runs, in whole years.
e.g. 10

What comes back

{
  "ok": true,
  "data": {
    "monthlyInvestment": 5000,
    "expectedAnnualReturnPercent": 12,
    "years": 10,
    "totalValue": 1161695.38,
    "investedAmount": 600000,
    "estimatedReturns": 561695.38,
    "returnsPercent": 48.4,
    "yearlyBreakdown": [
      {
        "year": 1,
        "invested": 60000,
        "returns": 4046.64,
        "value": 64046.64
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool sip_returns (SIP) with monthlyInvestment: 5000, expectedAnnualReturnPercent: 12, years: 10.

The assistant then makes this tool call:

{
  "name": "sip_returns",
  "arguments": {
    "monthlyInvestment": 5000,
    "expectedAnnualReturnPercent": 12,
    "years": 10
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/sip-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"monthlyInvestment":5000,"expectedAnnualReturnPercent":12,"years":10}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/sip-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "monthlyInvestment": 5000,
    "expectedAnnualReturnPercent": 12,
    "years": 10
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/sip-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"monthlyInvestment":5000,"expectedAnnualReturnPercent":12,"years":10},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/sip-calculator · Page: /tools/sip-calculator

EMI Calculatorpageemi-calculatoremi1 credit a call

The equated monthly instalment on a loan from the amount, the annual rate and a tenure in years or months. Returns the instalment, the total paid, the total interest, interest as a share of the total, and an amortisation schedule grouped by year.

What it takes

loanAmount
number
How much is borrowed.
e.g. 1000000
annualRatePercent
number
Yearly interest rate in percent.
e.g. 8.5
tenure
number
The term, counted in the unit below.
e.g. 20
tenureUnit?
string
years or months. Defaults to years.
e.g. years

What comes back

{
  "ok": true,
  "data": {
    "loanAmount": 1000000,
    "annualRatePercent": 8.5,
    "tenure": 20,
    "tenureUnit": "years",
    "months": 240,
    "emi": 8678.23,
    "totalPayment": 2082775.76,
    "totalInterest": 1082775.76,
    "interestPercent": 52,
    "yearlyBreakdown": [
      {
        "year": 1,
        "principalPaid": 19902.29,
        "interestPaid": 84236.5,
        "balance": 980097.71
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool emi (EMI) with loanAmount: 1000000, annualRatePercent: 8.5, tenure: 20, tenureUnit: years.

The assistant then makes this tool call:

{
  "name": "emi",
  "arguments": {
    "loanAmount": 1000000,
    "annualRatePercent": 8.5,
    "tenure": 20,
    "tenureUnit": "years"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/emi-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"loanAmount":1000000,"annualRatePercent":8.5,"tenure":20,"tenureUnit":"years"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/emi-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "loanAmount": 1000000,
    "annualRatePercent": 8.5,
    "tenure": 20,
    "tenureUnit": "years"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/emi-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"loanAmount":1000000,"annualRatePercent":8.5,"tenure":20,"tenureUnit":"years"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/emi-calculator · Page: /tools/emi-calculator

Profit Margin Calculatorpageprofit-margin-calculatorprofit_margin1 credit a call

Gross margin, markup and profit on one sale. In margin mode give the cost and the selling price; in price mode give the cost and the margin you want and it returns the price to charge. Margin is profit over the price, markup is profit over the cost, and both come back either way.

What it takes

mode?
string
margin (default) or price.
e.g. margin
cost
number
What the item cost.
e.g. 60
revenue?
number
The selling price. Needed in margin mode.
e.g. 100
targetMarginPercent?
number
The margin you want, in percent. Needed in price mode.
e.g. 40

What comes back

{
  "ok": true,
  "data": {
    "mode": "margin",
    "cost": 60,
    "revenue": 100,
    "profit": 40,
    "grossMarginPercent": 40,
    "markupPercent": 66.67
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool profit_margin (Profit Margin) with mode: margin, cost: 60, revenue: 100, targetMarginPercent: 40.

The assistant then makes this tool call:

{
  "name": "profit_margin",
  "arguments": {
    "mode": "margin",
    "cost": 60,
    "revenue": 100,
    "targetMarginPercent": 40
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/profit-margin-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"margin","cost":60,"revenue":100,"targetMarginPercent":40}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/profit-margin-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "margin",
    "cost": 60,
    "revenue": 100,
    "targetMarginPercent": 40
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/profit-margin-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"margin","cost":60,"revenue":100,"targetMarginPercent":40},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/profit-margin-calculator · Page: /tools/profit-margin-calculator

Margin and Markup Calculatorpagemargin-calculatormargin_markup1 credit a call

Give any two of cost, revenue and gross margin and this solves for the rest, including the markup. Use costRevenue when you know both amounts, costMargin to price up from a cost, and revenueMargin to work out what a product may cost to hit a margin at a fixed price.

What it takes

mode?
string
costRevenue (default), costMargin or revenueMargin.
e.g. costRevenue
cost?
number
What the item cost.
e.g. 60
revenue?
number
What the item sells for.
e.g. 100
marginPercent?
number
Gross margin in percent.
e.g. 40

What comes back

{
  "ok": true,
  "data": {
    "mode": "costRevenue",
    "cost": 60,
    "revenue": 100,
    "profit": 40,
    "grossMarginPercent": 40,
    "markupPercent": 66.67
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool margin_markup (Margin and Markup) with mode: costRevenue, cost: 60, revenue: 100, marginPercent: 40.

The assistant then makes this tool call:

{
  "name": "margin_markup",
  "arguments": {
    "mode": "costRevenue",
    "cost": 60,
    "revenue": 100,
    "marginPercent": 40
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/margin-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"costRevenue","cost":60,"revenue":100,"marginPercent":40}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/margin-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "costRevenue",
    "cost": 60,
    "revenue": 100,
    "marginPercent": 40
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/margin-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"costRevenue","cost":60,"revenue":100,"marginPercent":40},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/margin-calculator · Page: /tools/margin-calculator

Commission Calculatorpagecommission-calculatorcommission1 credit a call

Commission on a sale and what is left after it. Flat mode pays one rate on the whole amount; tiered mode works like tax brackets, each rate paid only on the slice of the sale inside its band, which is why the effective rate lands between the lowest and highest tier.

What it takes

saleAmount
number
What the sale was worth.
e.g. 50000
mode?
string
flat (default) or tiered.
e.g. tiered
ratePercent?
number
The single rate, in percent. Needed in flat mode.
e.g. 5
tiers?
array
Bands lowest first; the last one has no upTo. Needed in tiered mode.
e.g. [{"upTo":10000,"ratePercent":3},{"upTo":30000,"ratePercent":5},{"ratePercent":8}]

What comes back

{
  "ok": true,
  "data": {
    "mode": "tiered",
    "saleAmount": 50000,
    "commission": 2900,
    "net": 47100,
    "effectiveRatePercent": 5.8,
    "breakdown": [
      {
        "label": "Up to 10,000",
        "amount": 10000,
        "ratePercent": 3,
        "commission": 300
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool commission (Commission) with saleAmount: 50000, mode: tiered, ratePercent: 5, tiers: [{"upTo":10000,"ratePercent":3},{"upTo":30000,"ratePercent":5},{"ratePercent":8}].

The assistant then makes this tool call:

{
  "name": "commission",
  "arguments": {
    "saleAmount": 50000,
    "mode": "tiered",
    "ratePercent": 5,
    "tiers": [
      {
        "upTo": 10000,
        "ratePercent": 3
      },
      {
        "upTo": 30000,
        "ratePercent": 5
      },
      {
        "ratePercent": 8
      }
    ]
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/commission-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"saleAmount":50000,"mode":"tiered","ratePercent":5,"tiers":[{"upTo":10000,"ratePercent":3},{"upTo":30000,"ratePercent":5},{"ratePercent":8}]}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/commission-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "saleAmount": 50000,
    "mode": "tiered",
    "ratePercent": 5,
    "tiers": [
      {
        "upTo": 10000,
        "ratePercent": 3
      },
      {
        "upTo": 30000,
        "ratePercent": 5
      },
      {
        "ratePercent": 8
      }
    ]
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/commission-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"saleAmount":50000,"mode":"tiered","ratePercent":5,"tiers":[{"upTo":10000,"ratePercent":3},{"upTo":30000,"ratePercent":5},{"ratePercent":8}]},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/commission-calculator · Page: /tools/commission-calculator

Sales Tax Calculatorpagesales-tax-calculatorsales_tax1 credit a call

Add sales tax to a net price, or pull it back out of a price that already includes it. Works for US sales tax and for VAT alike. Returns the net, the tax and the gross, rounded so that net plus tax is exactly the gross.

What it takes

amount
number
The price to work from.
e.g. 100
ratePercent
number
Tax rate in percent.
e.g. 8.875
mode?
string
add (default) or extract.
e.g. add

What comes back

{
  "ok": true,
  "data": {
    "mode": "add",
    "ratePercent": 8.875,
    "net": 100,
    "tax": 8.88,
    "gross": 108.88
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool sales_tax (Sales Tax) with amount: 100, ratePercent: 8.875, mode: add.

The assistant then makes this tool call:

{
  "name": "sales_tax",
  "arguments": {
    "amount": 100,
    "ratePercent": 8.875,
    "mode": "add"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/sales-tax-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":100,"ratePercent":8.875,"mode":"add"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/sales-tax-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 100,
    "ratePercent": 8.875,
    "mode": "add"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/sales-tax-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":100,"ratePercent":8.875,"mode":"add"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/sales-tax-calculator · Page: /tools/sales-tax-calculator

GST Calculatorpagegst-calculatorgst1 credit a call

Add GST to a base price or remove it from an inclusive one, at any rate including the Indian slabs of 5, 12, 18 and 28 percent. Returns the net, the GST and the gross, plus the CGST and SGST halves for an intra-state supply, split so the two halves add up to the tax exactly.

What it takes

amount
number
The price to work from.
e.g. 10000
ratePercent
number
GST rate in percent. The slabs are 5, 12, 18 and 28.
e.g. 18
mode?
string
add (default) or remove.
e.g. add

What comes back

{
  "ok": true,
  "data": {
    "mode": "add",
    "ratePercent": 18,
    "net": 10000,
    "gst": 1800,
    "gross": 11800,
    "cgst": 900,
    "sgst": 900
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool gst (GST) with amount: 10000, ratePercent: 18, mode: add.

The assistant then makes this tool call:

{
  "name": "gst",
  "arguments": {
    "amount": 10000,
    "ratePercent": 18,
    "mode": "add"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/gst-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":10000,"ratePercent":18,"mode":"add"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/gst-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 10000,
    "ratePercent": 18,
    "mode": "add"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/gst-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":10000,"ratePercent":18,"mode":"add"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/gst-calculator · Page: /tools/gst-calculator

Inflation Calculatorpageinflation-calculatorinflation_adjust1 credit a call

What an amount is worth after inflation, or what it was worth before. Fixed mode applies a rate you choose over a number of years. CPI mode uses the published US CPI-U annual averages from 1913 to 2025, so two years can be compared with the figures the BLS actually reported.

What it takes

mode?
string
fixed (default) or cpi.
e.g. cpi
amount
number
The amount of money.
e.g. 100
annualRatePercent?
number
Yearly inflation rate in percent. Needed in fixed mode.
e.g. 3
years?
number
Number of years. Needed in fixed mode.
e.g. 10
fromYear?
number
Starting year, 1913 to 2025. Needed in cpi mode.
e.g. 1990
toYear?
number
Target year, 1913 to 2025. Needed in cpi mode.
e.g. 2025

What comes back

{
  "ok": true,
  "data": {
    "mode": "cpi",
    "amount": 100,
    "years": 35,
    "annualRatePercent": 2.61,
    "futureCost": 246.37,
    "purchasingPower": 40.59,
    "cumulativeInflationPercent": 146.37,
    "fromYear": 1990,
    "toYear": 2025,
    "fromIndex": 130.7,
    "toIndex": 322
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool inflation_adjust (Inflation) with mode: cpi, amount: 100, annualRatePercent: 3, years: 10, fromYear: 1990, toYear: 2025.

The assistant then makes this tool call:

{
  "name": "inflation_adjust",
  "arguments": {
    "mode": "cpi",
    "amount": 100,
    "annualRatePercent": 3,
    "years": 10,
    "fromYear": 1990,
    "toYear": 2025
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/inflation-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"cpi","amount":100,"annualRatePercent":3,"years":10,"fromYear":1990,"toYear":2025}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/inflation-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "cpi",
    "amount": 100,
    "annualRatePercent": 3,
    "years": 10,
    "fromYear": 1990,
    "toYear": 2025
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/inflation-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"cpi","amount":100,"annualRatePercent":3,"years":10,"fromYear":1990,"toYear":2025},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/inflation-calculator · Page: /tools/inflation-calculator

Retirement Calculatorpageretirement-calculatorretirement_savings1 credit a call

Project a pension pot from what is saved now, what goes in every month, the return and the years left until retirement. Returns the pot at the retirement age, the same pot restated in today's money at an inflation rate, what the 4% rule would pay per month, and a year-by-year table.

What it takes

currentAge
number
Age today, in whole years.
e.g. 30
retirementAge
number
Age at retirement, above the current age.
e.g. 67
currentSavings?
number
What is saved already. Defaults to 0.
e.g. 25000
monthlyContribution?
number
Monthly deposit. Defaults to 0.
e.g. 500
annualReturnPercent
number
Expected yearly return in percent.
e.g. 7
annualInflationPercent?
number
Yearly inflation in percent. Defaults to 0.
e.g. 2.5

What comes back

{
  "ok": true,
  "data": {
    "currentAge": 30,
    "retirementAge": 67,
    "yearsToRetire": 37,
    "currentSavings": 25000,
    "monthlyContribution": 500,
    "annualReturnPercent": 7,
    "annualInflationPercent": 2.5,
    "nestEgg": 1385133.21,
    "nestEggInTodaysMoney": 555531.29,
    "totalContributed": 247000,
    "totalGrowth": 1138133.21,
    "monthlyIncome": 4617.11,
    "monthlyIncomeInTodaysMoney": 1851.77,
    "yearlyBreakdown": [
      {
        "age": 31,
        "contributed": 31000,
        "balance": 33039.69,
        "todaysValue": 32233.84
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool retirement_savings (Retirement) with currentAge: 30, retirementAge: 67, currentSavings: 25000, monthlyContribution: 500, annualReturnPercent: 7, annualInflationPercent: 2.5.

The assistant then makes this tool call:

{
  "name": "retirement_savings",
  "arguments": {
    "currentAge": 30,
    "retirementAge": 67,
    "currentSavings": 25000,
    "monthlyContribution": 500,
    "annualReturnPercent": 7,
    "annualInflationPercent": 2.5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/retirement-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"currentAge":30,"retirementAge":67,"currentSavings":25000,"monthlyContribution":500,"annualReturnPercent":7,"annualInflationPercent":2.5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/retirement-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "currentAge": 30,
    "retirementAge": 67,
    "currentSavings": 25000,
    "monthlyContribution": 500,
    "annualReturnPercent": 7,
    "annualInflationPercent": 2.5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/retirement-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"currentAge":30,"retirementAge":67,"currentSavings":25000,"monthlyContribution":500,"annualReturnPercent":7,"annualInflationPercent":2.5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/retirement-calculator · Page: /tools/retirement-calculator

Debt Payoff Calculatorpagedebt-payoff-calculatordebt_payoff1 credit a call

Take a list of debts with balance, APR and minimum payment, add whatever extra you can pay each month, and simulate both payoff strategies: snowball, which clears the smallest balance first, and avalanche, which clears the dearest first. Returns months to debt free, total interest and the payoff order for each, plus what avalanche saves.

What it takes

debts
array
Each debt with balance, aprPercent, minPayment and an optional name.
e.g. [{"name":"Credit card","balance":3500,"aprPercent":21,"minPayment":90},{"name":"Car loan","balance":9000,"aprPercent":7.5,"minPayment":260}]
extraMonthlyPayment?
number
Extra paid each month on top of the minimums.
e.g. 200

What comes back

{
  "ok": true,
  "data": {
    "totalBalance": 12500,
    "totalMinimumPayment": 350,
    "extraMonthlyPayment": 200,
    "snowball": {
      "strategy": "snowball",
      "months": 28,
      "totalInterest": 1407.79,
      "payoffOrder": [
        {
          "name": "Credit card",
          "month": 14
        }
      ],
      "paidOff": true
    },
    "avalanche": {
      "strategy": "avalanche",
      "months": 28,
      "totalInterest": 1407.79,
      "payoffOrder": [
        {
          "name": "Credit card",
          "month": 14
        }
      ],
      "paidOff": true
    },
    "interestSavedByAvalanche": 0,
    "monthsSavedByAvalanche": 0,
    "underwater": []
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool debt_payoff (Debt Payoff) with debts: [{"name":"Credit card","balance":3500,"aprPercent":21,"minPayment":90},{"name":"Car loan","balance":9000,"aprPercent":7.5,"minPayment":260}], extraMonthlyPayment: 200.

The assistant then makes this tool call:

{
  "name": "debt_payoff",
  "arguments": {
    "debts": [
      {
        "name": "Credit card",
        "balance": 3500,
        "aprPercent": 21,
        "minPayment": 90
      },
      {
        "name": "Car loan",
        "balance": 9000,
        "aprPercent": 7.5,
        "minPayment": 260
      }
    ],
    "extraMonthlyPayment": 200
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/debt-payoff-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"debts":[{"name":"Credit card","balance":3500,"aprPercent":21,"minPayment":90},{"name":"Car loan","balance":9000,"aprPercent":7.5,"minPayment":260}],"extraMonthlyPayment":200}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/debt-payoff-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "debts": [
      {
        "name": "Credit card",
        "balance": 3500,
        "aprPercent": 21,
        "minPayment": 90
      },
      {
        "name": "Car loan",
        "balance": 9000,
        "aprPercent": 7.5,
        "minPayment": 260
      }
    ],
    "extraMonthlyPayment": 200
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/debt-payoff-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"debts":[{"name":"Credit card","balance":3500,"aprPercent":21,"minPayment":90},{"name":"Car loan","balance":9000,"aprPercent":7.5,"minPayment":260}],"extraMonthlyPayment":200},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/debt-payoff-calculator · Page: /tools/debt-payoff-calculator

Savings Goal Calculatorpagesavings-goal-calculatorsavings_goal1 credit a call

A savings goal from either end. monthsToGoal walks the months at a given deposit until the balance clears the goal and reports the quarter marks along the way; requiredDeposit solves the other way round for the monthly amount a deadline needs. Both include interest compounded monthly.

What it takes

mode?
string
monthsToGoal (default) or requiredDeposit.
e.g. monthsToGoal
goal
number
The target amount.
e.g. 10000
currentSavings?
number
What is saved already. Defaults to 0.
e.g. 1500
monthlyDeposit?
number
Monthly deposit. Needed in monthsToGoal mode.
e.g. 300
months?
number
The deadline in months. Needed in requiredDeposit mode.
e.g. 24
annualRatePercent?
number
Yearly interest rate in percent. Defaults to 0.
e.g. 2.5

What comes back

{
  "ok": true,
  "data": {
    "mode": "monthsToGoal",
    "goal": 10000,
    "currentSavings": 1500,
    "annualRatePercent": 2.5,
    "alreadyThere": false,
    "months": 28,
    "monthlyDeposit": 300,
    "totalDeposited": 8400,
    "interestEarned": 330.58,
    "finalBalance": 10230.58,
    "schedule": [
      {
        "month": 1,
        "balance": 1803.13,
        "note": ""
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool savings_goal (Savings Goal) with mode: monthsToGoal, goal: 10000, currentSavings: 1500, monthlyDeposit: 300, months: 24, annualRatePercent: 2.5.

The assistant then makes this tool call:

{
  "name": "savings_goal",
  "arguments": {
    "mode": "monthsToGoal",
    "goal": 10000,
    "currentSavings": 1500,
    "monthlyDeposit": 300,
    "months": 24,
    "annualRatePercent": 2.5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/savings-goal-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"monthsToGoal","goal":10000,"currentSavings":1500,"monthlyDeposit":300,"months":24,"annualRatePercent":2.5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/savings-goal-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "monthsToGoal",
    "goal": 10000,
    "currentSavings": 1500,
    "monthlyDeposit": 300,
    "months": 24,
    "annualRatePercent": 2.5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/savings-goal-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"monthsToGoal","goal":10000,"currentSavings":1500,"monthlyDeposit":300,"months":24,"annualRatePercent":2.5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/savings-goal-calculator · Page: /tools/savings-goal-calculator

Split Bill Calculatorpagesplit-bill-calculatorsplit_bill1 credit a call

Settle up a group who have been paying for each other. Each expense is paid by one person and shared evenly by everyone or by the people named on it, with an optional tip added first. Returns what each person paid, owes and is owed, plus the shortest set of transfers that clears the group, optionally rounded to whole notes.

What it takes

people
array
The names in the group, each one different.
e.g. ["Alex","Sam","Kim"]
expenses
array
Each expense with payer, amount, an optional description and an optional sharedWith.
e.g. [{"payer":"Alex","description":"Dinner","amount":84},{"payer":"Sam","description":"Taxi","amount":21}]
tipPercent?
number
Tip added to every expense. Defaults to 0.
e.g. 10
roundTransfersTo?
number
Round transfers to this multiple. Defaults to 0.
e.g. 5

What comes back

{
  "ok": true,
  "data": {
    "people": [
      "Alex",
      "Sam",
      "Kim"
    ],
    "total": 105,
    "tipPercent": 0,
    "balances": [
      {
        "person": "Alex",
        "paid": 84,
        "owed": 35,
        "balance": 49
      }
    ],
    "transfers": [
      {
        "from": "Kim",
        "to": "Alex",
        "amount": 35
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool split_bill (Split Bill) with people: ["Alex","Sam","Kim"], expenses: [{"payer":"Alex","description":"Dinner","amount":84},{"payer":"Sam","description":"Taxi","amount":21}], tipPercent: 10, roundTransfersTo: 5.

The assistant then makes this tool call:

{
  "name": "split_bill",
  "arguments": {
    "people": [
      "Alex",
      "Sam",
      "Kim"
    ],
    "expenses": [
      {
        "payer": "Alex",
        "description": "Dinner",
        "amount": 84
      },
      {
        "payer": "Sam",
        "description": "Taxi",
        "amount": 21
      }
    ],
    "tipPercent": 10,
    "roundTransfersTo": 5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/split-bill-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"people":["Alex","Sam","Kim"],"expenses":[{"payer":"Alex","description":"Dinner","amount":84},{"payer":"Sam","description":"Taxi","amount":21}],"tipPercent":10,"roundTransfersTo":5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/split-bill-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "people": [
      "Alex",
      "Sam",
      "Kim"
    ],
    "expenses": [
      {
        "payer": "Alex",
        "description": "Dinner",
        "amount": 84
      },
      {
        "payer": "Sam",
        "description": "Taxi",
        "amount": 21
      }
    ],
    "tipPercent": 10,
    "roundTransfersTo": 5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/split-bill-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"people":["Alex","Sam","Kim"],"expenses":[{"payer":"Alex","description":"Dinner","amount":84},{"payer":"Sam","description":"Taxi","amount":21}],"tipPercent":10,"roundTransfersTo":5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/split-bill-calculator · Page: /tools/split-bill-calculator

Freelance Rate Calculatorpagefreelance-rate-calculatorfreelance_rate1 credit a call

The hourly and day rate a Dutch freelancer has to charge to take home a target net income. Works backwards from the net through the 2026 box 1 brackets, the zelfstandigenaftrek, the mkb-winstvrijstelling, the tax credits and the Zvw contribution, adds business costs and a buffer, and divides by the hours left after holidays and non-billable time. Dutch ZZP rules only.

What it takes

targetNetIncome
number
Net income you want for the year, in euros.
e.g. 45000
businessCosts?
number
Yearly business costs. Defaults to 0.
e.g. 5000
nonBillablePercent?
number
Percent of working time you cannot bill. Defaults to 0.
e.g. 30
vacationWeeks?
number
Weeks off a year. Defaults to 0.
e.g. 5
hoursPerWeek?
number
Hours in a working week. Defaults to 40.
e.g. 40
bufferPercent?
number
Buffer on top of the revenue. Defaults to 0.
e.g. 10
monthlyDisabilityInsurance?
number
Monthly AOV premium. Defaults to 0.
e.g. 150
monthlyPensionDeposit?
number
Monthly pension deposit. Defaults to 0.
e.g. 250
hoursPerDay?
number
Hours in a working day, for the day rate. Defaults to 8.
e.g. 8

What comes back

{
  "ok": true,
  "data": {
    "targetNetIncome": 45000,
    "billableHours": 1316,
    "hourlyRate": 52.75,
    "dayRate": 422,
    "hoursPerDay": 8,
    "revenue": 63108.06,
    "revenueWithBuffer": 69418.86,
    "buffer": 6310.81,
    "costs": 5000,
    "profit": 58108.06,
    "incomeTax": 10698.54,
    "healthcareContribution": 2409.52,
    "disabilityInsurance": 0,
    "pensionDeposit": 0,
    "equivalentEmployeeSalary": 61830.07
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool freelance_rate (Freelance Rate) with targetNetIncome: 45000, businessCosts: 5000, nonBillablePercent: 30, vacationWeeks: 5, hoursPerWeek: 40, bufferPercent: 10, monthlyDisabilityInsurance: 150, monthlyPensionDeposit: 250, hoursPerDay: 8.

The assistant then makes this tool call:

{
  "name": "freelance_rate",
  "arguments": {
    "targetNetIncome": 45000,
    "businessCosts": 5000,
    "nonBillablePercent": 30,
    "vacationWeeks": 5,
    "hoursPerWeek": 40,
    "bufferPercent": 10,
    "monthlyDisabilityInsurance": 150,
    "monthlyPensionDeposit": 250,
    "hoursPerDay": 8
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/freelance-rate-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"targetNetIncome":45000,"businessCosts":5000,"nonBillablePercent":30,"vacationWeeks":5,"hoursPerWeek":40,"bufferPercent":10,"monthlyDisabilityInsurance":150,"monthlyPensionDeposit":250,"hoursPerDay":8}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/freelance-rate-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "targetNetIncome": 45000,
    "businessCosts": 5000,
    "nonBillablePercent": 30,
    "vacationWeeks": 5,
    "hoursPerWeek": 40,
    "bufferPercent": 10,
    "monthlyDisabilityInsurance": 150,
    "monthlyPensionDeposit": 250,
    "hoursPerDay": 8
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/freelance-rate-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"targetNetIncome":45000,"businessCosts":5000,"nonBillablePercent":30,"vacationWeeks":5,"hoursPerWeek":40,"bufferPercent":10,"monthlyDisabilityInsurance":150,"monthlyPensionDeposit":250,"hoursPerDay":8},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/freelance-rate-calculator · Page: /tools/freelance-rate-calculator

Meeting Cost Calculatorpagemeeting-cost-calculatormeeting_cost1 credit a call

Price a meeting in salary from the number of attendees, one blended hourly rate and how long it runs. Returns the total, the cost per minute and the cost per person, so a recurring meeting can be weighed against what it produces.

What it takes

attendees
number
The number of people attending.
e.g. 5
hourlyRate
number
The hourly cost of one attendee.
e.g. 75
durationMinutes
number
The length of the meeting in minutes.
e.g. 60
currency?
string
USD, EUR or GBP. Only affects the formatted total.
e.g. USD

What comes back

{
  "ok": true,
  "data": {
    "attendees": 5,
    "hourlyRate": 75,
    "durationMinutes": 60,
    "currency": "USD",
    "symbol": "$",
    "totalCost": 375,
    "costPerMinute": 6.25,
    "costPerHour": 375,
    "costPerPerson": 75,
    "formattedTotal": "$375.00"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool meeting_cost (Meeting Cost) with attendees: 5, hourlyRate: 75, durationMinutes: 60, currency: USD.

The assistant then makes this tool call:

{
  "name": "meeting_cost",
  "arguments": {
    "attendees": 5,
    "hourlyRate": 75,
    "durationMinutes": 60,
    "currency": "USD"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/meeting-cost-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"attendees":5,"hourlyRate":75,"durationMinutes":60,"currency":"USD"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/meeting-cost-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "attendees": 5,
    "hourlyRate": 75,
    "durationMinutes": 60,
    "currency": "USD"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/meeting-cost-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"attendees":5,"hourlyRate":75,"durationMinutes":60,"currency":"USD"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/meeting-cost-calculator · Page: /tools/meeting-cost-calculator

Fuel Cost Calculatorpagefuel-cost-calculatorfuel_cost1 credit a call

Work out the fuel a journey burns and what it costs, from a distance in kilometres or miles, a consumption figure in any of the four common units, and a pump price per litre or gallon. Handles return trips, a repeat count for a monthly commute, and splitting the bill between passengers.

What it takes

distance
number
The length of one journey.
e.g. 100
distanceUnit?
string
km (default) or mi.
e.g. km
consumption
number
The car's fuel consumption figure.
e.g. 6.5
consumptionUnit?
string
l100km (default), kml, mpgUs or mpgUk, matching how the consumption is quoted.
e.g. l100km
price
number
The pump price of the fuel.
e.g. 1.95
priceUnit?
string
liter (default), usGallon or ukGallon.
e.g. liter
passengers?
number
How many people split the bill. Defaults to 1.
e.g. 1
roundTrip?
boolean
True doubles the distance for the return leg. Defaults to false.
e.g. false
trips?
number
How many times the journey is made. Defaults to 1.
e.g. 1

What comes back

{
  "ok": true,
  "data": {
    "totalKm": 100,
    "liters": 6.5,
    "cost": 12.68,
    "costPerPerson": 12.68,
    "passengers": 1,
    "trips": 1,
    "roundTrip": false,
    "litersPer100Km": 6.5,
    "pricePerLiter": 1.95,
    "costPerTrip": 12.68
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool fuel_cost (Fuel Cost) with distance: 100, distanceUnit: km, consumption: 6.5, consumptionUnit: l100km, price: 1.95, priceUnit: liter, passengers: 1, roundTrip: false, trips: 1.

The assistant then makes this tool call:

{
  "name": "fuel_cost",
  "arguments": {
    "distance": 100,
    "distanceUnit": "km",
    "consumption": 6.5,
    "consumptionUnit": "l100km",
    "price": 1.95,
    "priceUnit": "liter",
    "passengers": 1,
    "roundTrip": false,
    "trips": 1
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/fuel-cost-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"distance":100,"distanceUnit":"km","consumption":6.5,"consumptionUnit":"l100km","price":1.95,"priceUnit":"liter","passengers":1,"roundTrip":false,"trips":1}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/fuel-cost-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "distance": 100,
    "distanceUnit": "km",
    "consumption": 6.5,
    "consumptionUnit": "l100km",
    "price": 1.95,
    "priceUnit": "liter",
    "passengers": 1,
    "roundTrip": false,
    "trips": 1
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/fuel-cost-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"distance":100,"distanceUnit":"km","consumption":6.5,"consumptionUnit":"l100km","price":1.95,"priceUnit":"liter","passengers":1,"roundTrip":false,"trips":1},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/fuel-cost-calculator · Page: /tools/fuel-cost-calculator

Appliance Energy Cost Calculatorpageappliance-energy-cost-calculatorappliance_energy_cost1 credit a call

Price what an appliance costs to run, from its wattage, how it is used and the price of a kilowatt hour. Takes either a daily pattern (hours a day) or a weekly one (runs per week times minutes a run), and returns kilowatt hours and money per day, per month and per year.

What it takes

watts
number
The appliance's power draw in watts.
e.g. 90
pricePerKwh
number
The price of one kilowatt hour.
e.g. 0.3
mode?
string
daily (default) or weekly, matching how the appliance is used.
e.g. daily
hoursPerDay?
number
Hours a day the appliance runs, for daily mode.
e.g. 4
usesPerWeek?
number
Runs per week, for weekly mode.
e.g. 4
minutesPerUse?
number
Minutes per run, for weekly mode.
e.g. 60

What comes back

{
  "ok": true,
  "data": {
    "watts": 90,
    "mode": "daily",
    "pricePerKwh": 0.3,
    "kwhDay": 0.36,
    "kwhMonth": 10.96,
    "kwhYear": 131.49,
    "costDay": 0.11,
    "costMonth": 3.29,
    "costYear": 39.45,
    "hoursPerDay": 4
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool appliance_energy_cost (Appliance Energy Cost) with watts: 90, pricePerKwh: 0.3, mode: daily, hoursPerDay: 4, usesPerWeek: 4, minutesPerUse: 60.

The assistant then makes this tool call:

{
  "name": "appliance_energy_cost",
  "arguments": {
    "watts": 90,
    "pricePerKwh": 0.3,
    "mode": "daily",
    "hoursPerDay": 4,
    "usesPerWeek": 4,
    "minutesPerUse": 60
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/appliance-energy-cost-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"watts":90,"pricePerKwh":0.3,"mode":"daily","hoursPerDay":4,"usesPerWeek":4,"minutesPerUse":60}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/appliance-energy-cost-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "watts": 90,
    "pricePerKwh": 0.3,
    "mode": "daily",
    "hoursPerDay": 4,
    "usesPerWeek": 4,
    "minutesPerUse": 60
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/appliance-energy-cost-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"watts":90,"pricePerKwh":0.3,"mode":"daily","hoursPerDay":4,"usesPerWeek":4,"minutesPerUse":60},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/appliance-energy-cost-calculator · Page: /tools/appliance-energy-cost-calculator

Timesheet Calculatorpagetimesheet-calculatortimesheet_hours1 credit a call

Turn clock-in and clock-out times into hours worked: the net hours per day after the break, the weekly total in decimal hours and in hours and minutes, the split between regular and overtime hours at a threshold you choose, and gross pay at a flat hourly rate. Overnight shifts are handled, a day nobody worked is reported rather than guessed, and the result carries the page's caveat that this is an indication, not payroll or legal advice.

What it takes

days
array
One entry per day, each with start and end as HH:MM and optional breakMinutes and label. Leave both times empty for a day that was not worked.
e.g. [{"label":"Monday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Tuesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Wednesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Thursday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Friday","start":"09:00","end":"17:00","breakMinutes":30}]
overtimeThresholdHours?
number
Weekly hours before overtime starts. 40 in the United States, often 36 to 38 under a European collective agreement.
e.g. 40
hourlyRate?
number
Base pay per hour, used for the gross pay line. Every hour is counted at this rate, premiums are the job of overtime-calculator.
e.g. 25

What comes back

{
  "ok": true,
  "data": {
    "days": [
      {
        "label": "Monday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30,
        "hours": 8,
        "overnight": false
      }
    ],
    "totalHours": 39.5,
    "totalHoursHm": "39h 30m",
    "regularHours": 39.5,
    "overtimeHours": 0,
    "overtimeThresholdHours": 40,
    "daysWorked": 5,
    "hourlyRate": 25,
    "grossPay": 987.5,
    "note": "Indication only, not payroll or legal advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool timesheet_hours (Timesheet) with days: [{"label":"Monday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Tuesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Wednesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Thursday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Friday","start":"09:00","end":"17:00","breakMinutes":30}], overtimeThresholdHours: 40, hourlyRate: 25.

The assistant then makes this tool call:

{
  "name": "timesheet_hours",
  "arguments": {
    "days": [
      {
        "label": "Monday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Tuesday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Wednesday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Thursday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Friday",
        "start": "09:00",
        "end": "17:00",
        "breakMinutes": 30
      }
    ],
    "overtimeThresholdHours": 40,
    "hourlyRate": 25
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/timesheet-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"days":[{"label":"Monday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Tuesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Wednesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Thursday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Friday","start":"09:00","end":"17:00","breakMinutes":30}],"overtimeThresholdHours":40,"hourlyRate":25}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/timesheet-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "days": [
      {
        "label": "Monday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Tuesday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Wednesday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Thursday",
        "start": "09:00",
        "end": "17:30",
        "breakMinutes": 30
      },
      {
        "label": "Friday",
        "start": "09:00",
        "end": "17:00",
        "breakMinutes": 30
      }
    ],
    "overtimeThresholdHours": 40,
    "hourlyRate": 25
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/timesheet-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"days":[{"label":"Monday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Tuesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Wednesday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Thursday","start":"09:00","end":"17:30","breakMinutes":30},{"label":"Friday","start":"09:00","end":"17:00","breakMinutes":30}],"overtimeThresholdHours":40,"hourlyRate":25},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/timesheet-calculator · Page: /tools/timesheet-calculator

Overtime Calculatorpageovertime-calculatorovertime_pay1 credit a call

Work out a pay packet that mixes rates: regular hours at the base rate, overtime hours at a multiplier such as the 1.5x the United States FLSA sets as a minimum, and double-time hours at twice the base rate. Returns each line, the total, the total hours and the effective rate across all of them, which is the number to compare a salaried offer against. An indication, not payroll or legal advice.

What it takes

hourlyRate
number
What one regular hour pays.
e.g. 25
regularHours
number
Hours worked at the base rate.
e.g. 40
overtimeHours
number
Hours worked beyond the normal schedule.
e.g. 5
doubleTimeHours?
number
Hours paid at 2x, common for holidays or a seventh consecutive workday.
e.g. 0
overtimeMultiplier?
number
Premium for the overtime hours. Defaults to 1.5, the FLSA minimum.
e.g. 1.5

What comes back

{
  "ok": true,
  "data": {
    "hourlyRate": 25,
    "overtimeMultiplier": 1.5,
    "overtimeRate": 37.5,
    "doubleTimeRate": 50,
    "regularPay": 1000,
    "overtimePay": 187.5,
    "doubleTimePay": 0,
    "totalPay": 1187.5,
    "totalHours": 45,
    "effectiveRate": 26.39,
    "note": "Indication only, not payroll or legal advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool overtime_pay (Overtime) with hourlyRate: 25, regularHours: 40, overtimeHours: 5, doubleTimeHours: 0, overtimeMultiplier: 1.5.

The assistant then makes this tool call:

{
  "name": "overtime_pay",
  "arguments": {
    "hourlyRate": 25,
    "regularHours": 40,
    "overtimeHours": 5,
    "doubleTimeHours": 0,
    "overtimeMultiplier": 1.5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/overtime-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"hourlyRate":25,"regularHours":40,"overtimeHours":5,"doubleTimeHours":0,"overtimeMultiplier":1.5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/overtime-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "hourlyRate": 25,
    "regularHours": 40,
    "overtimeHours": 5,
    "doubleTimeHours": 0,
    "overtimeMultiplier": 1.5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/overtime-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"hourlyRate":25,"regularHours":40,"overtimeHours":5,"doubleTimeHours":0,"overtimeMultiplier":1.5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/overtime-calculator · Page: /tools/overtime-calculator

PTO Calculatorpagepto-calculatorpto_accrual1 credit a call

Project a paid time off balance: give an accrual rate either as hours per pay period or as days per year, plus the hours in the bank and the hours already booked, and get the accrual per year and per month, the balance after what is planned, twelve months of projected balance, and the balance on a target date. Accrual caps, carry-over deadlines and waiting periods are deliberately not modelled, which the note repeats.

What it takes

mode?
string
Either "perPeriod" (hours per paycheck) or "perYear" (days granted per year).
e.g. perPeriod
accrualPerPeriod?
number
Hours added each pay period, straight off the payslip. 15 days a year on a fortnightly schedule is about 4.62.
e.g. 4.62
payFrequency?
string
weekly, biweekly, semimonthly or monthly. Only read in mode perPeriod.
e.g. biweekly
daysPerYear?
number
Paid days off per year. Only read in mode perYear.
e.g. 15
hoursPerDay?
number
Hours in a workday, used to convert hours into days.
e.g. 8
currentBalanceHours?
number
The balance the last payslip shows, in hours.
e.g. 40
plannedHours?
number
Hours already booked. Subtracted first, so a negative balance means borrowing against future accrual.
e.g. 0
targetDate?
string
The date to project to, yyyy-mm-dd. Left out, or in the past, returns no projection.
e.g. 2026-07-01
today?
string
The date to count from, yyyy-mm-dd. Leave out to use the current date.
e.g. 2026-01-01

What comes back

{
  "ok": true,
  "data": {
    "hoursPerYear": 120.12,
    "daysPerYear": 15.02,
    "hoursPerMonth": 10.01,
    "hoursPerDay": 8,
    "balanceAfterPlanned": 40,
    "daysAfterPlanned": 5,
    "projected": {
      "date": "2026-07-01",
      "hours": 99.5,
      "days": 12.4,
      "months": 5.9
    },
    "schedule": [
      {
        "month": "Feb 2026",
        "hours": 50,
        "days": 6.3
      }
    ],
    "note": "Indication only. Accrual caps, carry-over limits, and waiting periods in your company policy are not modeled."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool pto_accrual (PTO) with mode: perPeriod, accrualPerPeriod: 4.62, payFrequency: biweekly, daysPerYear: 15, hoursPerDay: 8, currentBalanceHours: 40, plannedHours: 0, targetDate: 2026-07-01, today: 2026-01-01.

The assistant then makes this tool call:

{
  "name": "pto_accrual",
  "arguments": {
    "mode": "perPeriod",
    "accrualPerPeriod": 4.62,
    "payFrequency": "biweekly",
    "daysPerYear": 15,
    "hoursPerDay": 8,
    "currentBalanceHours": 40,
    "plannedHours": 0,
    "targetDate": "2026-07-01",
    "today": "2026-01-01"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/pto-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"perPeriod","accrualPerPeriod":4.62,"payFrequency":"biweekly","daysPerYear":15,"hoursPerDay":8,"currentBalanceHours":40,"plannedHours":0,"targetDate":"2026-07-01","today":"2026-01-01"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/pto-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "perPeriod",
    "accrualPerPeriod": 4.62,
    "payFrequency": "biweekly",
    "daysPerYear": 15,
    "hoursPerDay": 8,
    "currentBalanceHours": 40,
    "plannedHours": 0,
    "targetDate": "2026-07-01",
    "today": "2026-01-01"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/pto-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"perPeriod","accrualPerPeriod":4.62,"payFrequency":"biweekly","daysPerYear":15,"hoursPerDay":8,"currentBalanceHours":40,"plannedHours":0,"targetDate":"2026-07-01","today":"2026-01-01"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/pto-calculator · Page: /tools/pto-calculator

Salary Converterpagesalary-calculator-convertersalary_convert1 credit a call

Express one gross salary in every pay period at once: per hour, per day, per week, per fortnight, per month and per year. Give the amount and the period it is quoted in, and adjust the hours per week and weeks per year for part-time, term-time or shift work. A day is a fifth of the working week rather than a fixed eight hours, so a 36 hour week converts honestly. Gross only: tax, contributions and benefits are not modelled.

What it takes

amount
number
The gross salary figure you already have.
e.g. 85000
period
string
The period that amount belongs to: annual, monthly, biweekly, weekly, daily or hourly.
e.g. annual
hoursPerWeek?
number
Hours worked in a normal week. 40 is the standard assumption.
e.g. 40
weeksPerYear?
number
Paid weeks in a year. 52 for a normal contract, fewer for term-time work.
e.g. 52

What comes back

{
  "ok": true,
  "data": {
    "period": "annual",
    "amount": 85000,
    "hoursPerWeek": 40,
    "weeksPerYear": 52,
    "hoursPerYear": 2080,
    "annual": 85000,
    "monthly": 7083.33,
    "biweekly": 3269.23,
    "weekly": 1634.62,
    "daily": 326.92,
    "hourly": 40.87
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool salary_convert (Salary) with amount: 85000, period: annual, hoursPerWeek: 40, weeksPerYear: 52.

The assistant then makes this tool call:

{
  "name": "salary_convert",
  "arguments": {
    "amount": 85000,
    "period": "annual",
    "hoursPerWeek": 40,
    "weeksPerYear": 52
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/salary-calculator-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":85000,"period":"annual","hoursPerWeek":40,"weeksPerYear":52}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/salary-calculator-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 85000,
    "period": "annual",
    "hoursPerWeek": 40,
    "weeksPerYear": 52
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/salary-calculator-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":85000,"period":"annual","hoursPerWeek":40,"weeksPerYear":52},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/salary-calculator-converter · Page: /tools/salary-calculator-converter

Dutch Mortgage Calculatorpagehypotheek-calculatordutch_mortgage1 credit a call

Work out what a Dutch mortgage costs per month: an annuiteitenhypotheek, where the payment stays the same and the split between interest and repayment shifts, or a lineaire hypotheek, where the payment falls every month. Returns the first and last monthly payment, the interest in the first month, the total interest and the total cost, plus a net payment after hypotheekrenteaftrek when you give the deduction rate. An indication, not mortgage or tax advice: NHG, income tests and lender conditions are not modelled.

What it takes

amount
number
The mortgage amount in euros.
e.g. 300000
years
number
Term in years. 30 is the usual Dutch maximum.
e.g. 30
annualRatePercent
number
The interest rate as a percentage per year.
e.g. 4.5
type?
string
"annuiteit" (the common Dutch mortgage) or "lineair" (higher at the start, cheaper in total).
e.g. annuiteit
deductionRatePercent?
number
Your hypotheekrenteaftrek rate, to get a net indication of the first month. Leave it out and only gross figures come back.
e.g. 36.97

What comes back

{
  "ok": true,
  "data": {
    "amount": 300000,
    "years": 30,
    "months": 360,
    "annualRatePercent": 4.5,
    "type": "annuiteit",
    "firstMonthlyPayment": 1520.06,
    "lastMonthlyPayment": 1520.06,
    "firstMonthInterest": 1125,
    "totalInterest": 247220.13,
    "totalCost": 547220.13,
    "deductionRatePercent": 36.97,
    "netFirstMonthlyPayment": 1104.15,
    "note": "This is an indication, not mortgage or tax advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_mortgage (Dutch Mortgage) with amount: 300000, years: 30, annualRatePercent: 4.5, type: annuiteit, deductionRatePercent: 36.97.

The assistant then makes this tool call:

{
  "name": "dutch_mortgage",
  "arguments": {
    "amount": 300000,
    "years": 30,
    "annualRatePercent": 4.5,
    "type": "annuiteit",
    "deductionRatePercent": 36.97
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/hypotheek-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":300000,"years":30,"annualRatePercent":4.5,"type":"annuiteit","deductionRatePercent":36.97}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/hypotheek-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 300000,
    "years": 30,
    "annualRatePercent": 4.5,
    "type": "annuiteit",
    "deductionRatePercent": 36.97
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/hypotheek-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":300000,"years":30,"annualRatePercent":4.5,"type":"annuiteit","deductionRatePercent":36.97},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/hypotheek-calculator · Page: /tools/hypotheek-calculator

Dutch Salary Calculatorpagesalaris-calculatordutch_net_salary1 credit a call

Estimate a Dutch net salary from a gross one, or the gross salary needed for a net one, with the 2026 box 1 brackets (36.97% up to EUR 75,518, 49.50% above) and the two credits that follow income: the algemene heffingskorting and the arbeidskorting. Returns gross and net per year and per month, the tax before and after credits, each credit, and the effective rate. An estimate based on 2026 Dutch tax rates: it does not account for social security premiums, pension contributions, or individual circumstances, so it is not tax advice.

What it takes

amount
number
The salary in euros: gross in mode grossToNet, the net you want in mode netToGross.
e.g. 45000
period?
string
Whether that amount is per "year" or per "month".
e.g. year
mode?
string
Direction of the calculation: "grossToNet" (default) or "netToGross".
e.g. grossToNet

What comes back

{
  "ok": true,
  "data": {
    "mode": "grossToNet",
    "grossAnnual": 45000,
    "grossMonthly": 3750,
    "taxBeforeCredits": 16636.5,
    "generalTaxCredit": 2023.5,
    "employmentTaxCredit": 5203.77,
    "taxAfterCredits": 9409.24,
    "netAnnual": 35590.76,
    "netMonthly": 2965.9,
    "effectiveTaxRatePercent": 20.91,
    "note": "This calculation is an estimate based on 2026 Dutch tax rates."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_net_salary (Dutch Salary) with amount: 45000, period: year, mode: grossToNet.

The assistant then makes this tool call:

{
  "name": "dutch_net_salary",
  "arguments": {
    "amount": 45000,
    "period": "year",
    "mode": "grossToNet"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/salaris-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":45000,"period":"year","mode":"grossToNet"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/salaris-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 45000,
    "period": "year",
    "mode": "grossToNet"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/salaris-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":45000,"period":"year","mode":"grossToNet"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/salaris-calculator · Page: /tools/salaris-calculator

Dutch Student Finance Calculatorpagedutch-student-finance-calculatordutch_student_finance1 credit a call

Estimate what DUO pays a Dutch student each month: the basisbeurs for mbo or hbo/wo, living at home or away, plus the aanvullende beurs that follows the parents' income, and the student travel product. The middle income band returns a range rather than a number, because DUO phases the aanvullende beurs out between roughly EUR 41,500 and EUR 70,000 of combined 2024 parental income. An indication, not advice: the official 2026 DUO amounts are indexed during the year.

What it takes

study?
string
"mbo" for a bol course, "hbowo" for hbo or university.
e.g. hbowo
living?
string
"away" for a student living away from home (uitwonend), "home" for thuiswonend.
e.g. away
parentalIncome?
string
Which band the parents' combined 2024 income falls in: "low", "middle" or "high".
e.g. low

What comes back

{
  "ok": true,
  "data": {
    "study": "hbowo",
    "living": "away",
    "parentalIncome": "low",
    "basicGrant": 324.52,
    "supplementaryGrantLow": 491.08,
    "supplementaryGrantHigh": 491.08,
    "totalLow": 815.6,
    "totalHigh": 815.6,
    "travelProduct": "Free public transport on weekdays or weekends, by choice.",
    "supplementaryNote": "With a combined parental income below roughly EUR 41,500 you typically get the full aanvullende beurs.",
    "note": "This is an indication, not advice. Check duo.nl for your personal calculation."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_student_finance (Dutch Student Finance) with study: hbowo, living: away, parentalIncome: low.

The assistant then makes this tool call:

{
  "name": "dutch_student_finance",
  "arguments": {
    "study": "hbowo",
    "living": "away",
    "parentalIncome": "low"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-student-finance-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"study":"hbowo","living":"away","parentalIncome":"low"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-student-finance-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "study": "hbowo",
    "living": "away",
    "parentalIncome": "low"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-student-finance-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"study":"hbowo","living":"away","parentalIncome":"low"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-student-finance-calculator · Page: /tools/dutch-student-finance-calculator

Dates and time

Dutch Public Holidayspagedutch-holidaysdutch_public_holidays1 credit a call

List every Dutch public holiday in a year, including the movable feasts computed from Easter.

What it takes

year
number
The calendar year, between 1900 and 2200.
e.g. 2026

What comes back

{
  "ok": true,
  "data": {
    "year": 2026,
    "holidays": [
      {
        "date": "2026-01-01",
        "name": "Nieuwjaarsdag",
        "nameEn": "New Year's Day",
        "dayOff": true
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_public_holidays (Dutch Public Holidays) with year: 2026.

The assistant then makes this tool call:

{
  "name": "dutch_public_holidays",
  "arguments": {
    "year": 2026
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-holidays \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"year":2026}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-holidays", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "year": 2026
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-holidays",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"year":2026},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-holidays · Page: /tools/public-holidays

Working Days Calculatorpageworking-daysworking_days_between1 credit a call

Count the working days between two dates inclusive, skipping weekends and, by default, Dutch public holidays.

What it takes

start
string
First day of the range, as YYYY-MM-DD. Counted itself.
e.g. 2026-01-01
end
string
Last day of the range, as YYYY-MM-DD. Counted itself.
e.g. 2026-01-31
excludeDutchHolidays?
boolean
Leave Dutch public holidays out of the count. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "start": "2026-01-01",
    "end": "2026-01-31",
    "totalDays": 31,
    "workingDays": 21,
    "weekendDays": 9,
    "holidaysExcluded": [
      {
        "date": "2026-01-01",
        "name": "Nieuwjaarsdag"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool working_days_between (Working Days) with start: 2026-01-01, end: 2026-01-31, excludeDutchHolidays: true.

The assistant then makes this tool call:

{
  "name": "working_days_between",
  "arguments": {
    "start": "2026-01-01",
    "end": "2026-01-31",
    "excludeDutchHolidays": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/working-days \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"start":"2026-01-01","end":"2026-01-31","excludeDutchHolidays":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/working-days", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "start": "2026-01-01",
    "end": "2026-01-31",
    "excludeDutchHolidays": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/working-days",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"start":"2026-01-01","end":"2026-01-31","excludeDutchHolidays":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/working-days · Page: /tools/dutch-working-days-calculator

Timestamp Converterpagetimestamp-converterconvert_timestamp1 credit a call

Convert a Unix timestamp (seconds or milliseconds) to an ISO 8601 UTC date, or an ISO date to a Unix timestamp. Returns both timestamps, the ISO and RFC 7231 forms, and the weekday.

What it takes

value
number
A Unix timestamp such as 1725710400, or an ISO 8601 date such as 2026-09-07T12:00:00Z.
e.g. 1725710400
unit?
string
Force "seconds" or "milliseconds" for a numeric value. Default "auto" decides by size.
e.g. auto

What comes back

{
  "ok": true,
  "data": {
    "input": 1725710400,
    "interpretedAs": "seconds",
    "unixSeconds": 1725710400,
    "unixMilliseconds": 1725710400000,
    "iso": "2024-09-07T12:00:00.000Z",
    "utc": "Sat, 07 Sep 2024 12:00:00 GMT",
    "date": "2024-09-07",
    "time": "12:00:00",
    "weekday": "Saturday"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_timestamp (Timestamp) with value: 1725710400, unit: auto.

The assistant then makes this tool call:

{
  "name": "convert_timestamp",
  "arguments": {
    "value": 1725710400,
    "unit": "auto"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/timestamp-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":1725710400,"unit":"auto"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/timestamp-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "value": 1725710400,
    "unit": "auto"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/timestamp-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"value":1725710400,"unit":"auto"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/timestamp-converter · Page: /tools/timestamp-converter

Date Difference Calculatorpagedate-difference-calculatordate_difference1 credit a call

The time between two calendar dates: total days, weeks plus days, a years/months/days breakdown, hours, and the number of business days (Monday to Friday, no holidays). Order does not matter; the end date is excluded unless includeEndDate is true.

What it takes

startDate
string
The first date as YYYY-MM-DD.
e.g. 2026-01-01
endDate
string
The second date as YYYY-MM-DD.
e.g. 2026-12-31
includeEndDate?
boolean
Whether the end date counts as a full day. Defaults to false.
e.g. false

What comes back

{
  "ok": true,
  "data": {
    "start": "2026-01-01",
    "end": "2026-12-31",
    "startWeekday": "Thursday",
    "endWeekday": "Thursday",
    "swapped": false,
    "includeEndDate": false,
    "years": 0,
    "months": 11,
    "days": 30,
    "totalDays": 364,
    "totalWeeks": 52,
    "weeksAndDays": {
      "weeks": 52,
      "days": 0
    },
    "totalHours": 8736,
    "businessDays": 260
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool date_difference (Date Difference) with startDate: 2026-01-01, endDate: 2026-12-31, includeEndDate: false.

The assistant then makes this tool call:

{
  "name": "date_difference",
  "arguments": {
    "startDate": "2026-01-01",
    "endDate": "2026-12-31",
    "includeEndDate": false
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/date-difference-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"startDate":"2026-01-01","endDate":"2026-12-31","includeEndDate":false}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/date-difference-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "startDate": "2026-01-01",
    "endDate": "2026-12-31",
    "includeEndDate": false
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/date-difference-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"startDate":"2026-01-01","endDate":"2026-12-31","includeEndDate":false},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/date-difference-calculator · Page: /tools/date-difference-calculator

Age Calculatorpageage-calculatorage1 credit a call

Exact age on a date from a birth date: years, months and days, total days, weeks and months lived, and the date of the next birthday with the days until it. Defaults to today when asOf is left out.

What it takes

birthDate
string
The date of birth as YYYY-MM-DD.
e.g. 1990-05-15
asOf?
string
The reference date as YYYY-MM-DD. Leave out for today.
e.g. 2026-09-07

What comes back

{
  "ok": true,
  "data": {
    "birthDate": "1990-05-15",
    "asOf": "2026-09-07",
    "years": 36,
    "months": 3,
    "days": 23,
    "totalDays": 13264,
    "totalWeeks": 1894,
    "totalMonths": 435,
    "nextBirthday": {
      "date": "2027-05-15",
      "daysUntil": 250,
      "turning": 37
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool age (Age) with birthDate: 1990-05-15, asOf: 2026-09-07.

The assistant then makes this tool call:

{
  "name": "age",
  "arguments": {
    "birthDate": "1990-05-15",
    "asOf": "2026-09-07"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/age-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthDate":"1990-05-15","asOf":"2026-09-07"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/age-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "birthDate": "1990-05-15",
    "asOf": "2026-09-07"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/age-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"birthDate":"1990-05-15","asOf":"2026-09-07"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/age-calculator · Page: /tools/age-calculator

Week Numberpageweek-numberweek_number1 credit a call

The ISO 8601 week number and ISO year for a date, with the Monday and Sunday of that week, plus the US (Sunday-based) and UK/EU week numbers. Defaults to today when no date is given.

What it takes

date?
string
The date as YYYY-MM-DD. Leave out for today.
e.g. 2026-09-07

What comes back

{
  "ok": true,
  "data": {
    "date": "2026-09-07",
    "weekday": "Monday",
    "isoWeek": 37,
    "isoYear": 2026,
    "weekStart": "2026-09-07",
    "weekEnd": "2026-09-13",
    "usWeek": 37,
    "ukWeek": 37
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool week_number (Week Number) with date: 2026-09-07.

The assistant then makes this tool call:

{
  "name": "week_number",
  "arguments": {
    "date": "2026-09-07"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/week-number \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"date":"2026-09-07"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/week-number", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "date": "2026-09-07"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/week-number",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"date":"2026-09-07"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/week-number · Page: /tools/week-number

Timezone Converterpagetimezone-converterconvert_timezone1 credit a call

Take a local date and time in one IANA time zone (such as Europe/Amsterdam) and express it in another, using the built-in Intl zone rules including daylight saving. Returns both wall-clock times with their UTC offsets, the UTC instant and the hour difference.

What it takes

dateTime
string
The local date and time in the source zone, no offset.
e.g. 2026-03-15T14:30
from
string
Source IANA time zone name.
e.g. Europe/Amsterdam
to
string
Target IANA time zone name.
e.g. America/New_York

What comes back

{
  "ok": true,
  "data": {
    "input": "2026-03-15T14:30",
    "from": {
      "zone": "Europe/Amsterdam",
      "dateTime": "2026-03-15T14:30:00",
      "offset": "+01:00",
      "offsetMinutes": 60,
      "weekday": "Sunday"
    },
    "to": {
      "zone": "America/New_York",
      "dateTime": "2026-03-15T09:30:00",
      "offset": "-04:00",
      "offsetMinutes": -240,
      "weekday": "Sunday"
    },
    "utc": "2026-03-15T13:30:00Z",
    "differenceHours": -5
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_timezone (Timezone) with dateTime: 2026-03-15T14:30, from: Europe/Amsterdam, to: America/New_York.

The assistant then makes this tool call:

{
  "name": "convert_timezone",
  "arguments": {
    "dateTime": "2026-03-15T14:30",
    "from": "Europe/Amsterdam",
    "to": "America/New_York"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/timezone-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dateTime":"2026-03-15T14:30","from":"Europe/Amsterdam","to":"America/New_York"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/timezone-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "dateTime": "2026-03-15T14:30",
    "from": "Europe/Amsterdam",
    "to": "America/New_York"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/timezone-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"dateTime":"2026-03-15T14:30","from":"Europe/Amsterdam","to":"America/New_York"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/timezone-converter · Page: /tools/timezone-converter

AOW Age Calculatorpageaow-age-calculatoraow_age1 credit a call

Look up the Dutch state pension (AOW) age for a birth date from the official SVB table: the age in years and months, the date it starts, how long until then, and whether that age is legally fixed or still an expectation.

What it takes

birthDate
string
The person's birth date as yyyy-mm-dd.
e.g. 1975-05-12
today?
string
The date to count the remaining time from, yyyy-mm-dd. Leave out to use today.
e.g. 2026-08-28

What comes back

{
  "ok": true,
  "data": {
    "status": "expected",
    "years": 68,
    "months": 0,
    "aowDate": "2043-05-12",
    "timeLeft": {
      "years": 16,
      "months": 8,
      "days": 15
    },
    "note": "This is an expectation, not a guarantee."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool aow_age (AOW Age) with birthDate: 1975-05-12, today: 2026-08-28.

The assistant then makes this tool call:

{
  "name": "aow_age",
  "arguments": {
    "birthDate": "1975-05-12",
    "today": "2026-08-28"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/aow-age-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthDate":"1975-05-12","today":"2026-08-28"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/aow-age-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "birthDate": "1975-05-12",
    "today": "2026-08-28"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/aow-age-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"birthDate":"1975-05-12","today":"2026-08-28"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/aow-age-calculator · Page: /tools/aow-age-calculator

Dutch Notice Period Calculatorpagedutch-notice-period-calculatordutch_notice_period1 credit a call

Find the statutory Dutch notice period (Article 7:672 Civil Code) for an employee or employer from the employment start date and the date notice is given, and the date the contract ends, since notice runs from the first of the next month. A contractual period can override the statutory one.

What it takes

givenBy
string
"employee" when the employee resigns, "employer" when the employer dismisses.
e.g. employee
startDate
string
First day of employment, yyyy-mm-dd.
e.g. 2019-03-01
noticeDate
string
The day notice is given, yyyy-mm-dd.
e.g. 2026-09-12
contractMonths?
number
A notice period in months agreed in the contract or CAO, 0 to 12. Leave out to use the statutory period.
e.g. 1

What comes back

{
  "ok": true,
  "data": {
    "ok": true,
    "serviceYears": 7.53,
    "statutoryMonths": 1,
    "appliedMonths": 1,
    "fromContract": true,
    "noticePeriodStarts": "2026-10-01",
    "employmentEnds": "2026-10-31",
    "note": "Based on Article 7:672 of the Dutch Civil Code."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_notice_period (Dutch Notice Period) with givenBy: employee, startDate: 2019-03-01, noticeDate: 2026-09-12, contractMonths: 1.

The assistant then makes this tool call:

{
  "name": "dutch_notice_period",
  "arguments": {
    "givenBy": "employee",
    "startDate": "2019-03-01",
    "noticeDate": "2026-09-12",
    "contractMonths": 1
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-notice-period-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"givenBy":"employee","startDate":"2019-03-01","noticeDate":"2026-09-12","contractMonths":1}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-notice-period-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "givenBy": "employee",
    "startDate": "2019-03-01",
    "noticeDate": "2026-09-12",
    "contractMonths": 1
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-notice-period-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"givenBy":"employee","startDate":"2019-03-01","noticeDate":"2026-09-12","contractMonths":1},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-notice-period-calculator · Page: /tools/dutch-notice-period-calculator

Dutch School Holidayspagedutch-school-holidaysdutch_school_holidays1 credit a call

List the official Dutch school holidays (schoolvakanties) for a school year and region (noord, midden or zuid) with start and end dates, whether each is advisory, days until each one, and which break comes next. Covers 2026-2027 and 2027-2028 from Rijksoverheid.nl.

What it takes

schoolYear?
string
Which school year: "2026-2027" (default) or "2027-2028".
e.g. 2026-2027
region?
string
The region: "noord" (e.g. Amsterdam, Groningen), "midden" (default, e.g. Utrecht, Rotterdam) or "zuid" (e.g. Brabant, Limburg).
e.g. midden
today?
string
The date to count days from, yyyy-mm-dd. Leave out to use today.
e.g. 2026-09-07

What comes back

{
  "ok": true,
  "data": {
    "schoolYear": "2026-2027",
    "region": "midden",
    "holidays": [
      {
        "name": "Autumn break",
        "dutch": "Herfstvakantie",
        "start": "2026-10-17",
        "end": "2026-10-25",
        "advisory": true,
        "daysUntilStart": 40,
        "status": "upcoming"
      }
    ],
    "next": {
      "name": "Autumn break",
      "dutch": "Herfstvakantie",
      "start": "2026-10-17",
      "end": "2026-10-25",
      "advisory": true,
      "daysUntilStart": 40,
      "ongoing": false
    },
    "note": "Kerstvakantie and zomervakantie are set by the Ministry of Education."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_school_holidays (Dutch School Holidays) with schoolYear: 2026-2027, region: midden, today: 2026-09-07.

The assistant then makes this tool call:

{
  "name": "dutch_school_holidays",
  "arguments": {
    "schoolYear": "2026-2027",
    "region": "midden",
    "today": "2026-09-07"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-school-holidays \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"schoolYear":"2026-2027","region":"midden","today":"2026-09-07"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-school-holidays", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "schoolYear": "2026-2027",
    "region": "midden",
    "today": "2026-09-07"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-school-holidays",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"schoolYear":"2026-2027","region":"midden","today":"2026-09-07"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-school-holidays · Page: /tools/dutch-school-holidays

Date Calculatorpagedate-calculatordate_add_subtract1 credit a call

Add or subtract days, weeks, months or years from a date and get the date you land on, written out with its weekday. The arithmetic is calendar aware and runs in UTC, so leap years and month lengths are handled and the answer never shifts with a time zone.

What it takes

amount
number
How many days, weeks, months or years to move.
e.g. 90
unit
string
One of days, weeks, months or years.
e.g. days
operation?
string
add to move forward, subtract to move back. Defaults to add.
e.g. add
startDate?
string
The date to count from as YYYY-MM-DD. Defaults to today in UTC.
e.g. 2026-03-15

What comes back

{
  "ok": true,
  "data": {
    "startDate": "2026-03-15",
    "startWeekday": "Sunday",
    "operation": "add",
    "amount": 90,
    "unit": "days",
    "resultDate": "2026-06-13",
    "weekday": "Saturday",
    "formatted": "Saturday, June 13, 2026",
    "daysDifference": 90
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool date_add_subtract (Date) with amount: 90, unit: days, operation: add, startDate: 2026-03-15.

The assistant then makes this tool call:

{
  "name": "date_add_subtract",
  "arguments": {
    "amount": 90,
    "unit": "days",
    "operation": "add",
    "startDate": "2026-03-15"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/date-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":90,"unit":"days","operation":"add","startDate":"2026-03-15"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/date-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 90,
    "unit": "days",
    "operation": "add",
    "startDate": "2026-03-15"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/date-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"amount":90,"unit":"days","operation":"add","startDate":"2026-03-15"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/date-calculator · Page: /tools/date-calculator

Military Time Converterpagemilitary-time-convertermilitary_time1 credit a call

Convert a time between the 24-hour military clock and the 12-hour AM/PM clock, in either direction, and get both spellings plus the spoken military phrase. Accepts 1:30 PM, 130pm, 1330 and 13:00.

What it takes

time
string
The time to convert, in either clock: 1:30 PM, 7am, 1330 or 13:00.
e.g. 1:30 PM
from?
string
auto (default) decides from the AM/PM marker; standard or military force one reading.
e.g. auto

What comes back

{
  "ok": true,
  "data": {
    "input": "1:30 PM",
    "readAs": "standard",
    "hours": 13,
    "minutes": 30,
    "military": "1330",
    "military24": "13:30",
    "standard": "1:30 PM",
    "spoken": "13 30 (1330 hours)"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool military_time (Military Time) with time: 1:30 PM, from: auto.

The assistant then makes this tool call:

{
  "name": "military_time",
  "arguments": {
    "time": "1:30 PM",
    "from": "auto"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/military-time-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"time":"1:30 PM","from":"auto"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/military-time-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "time": "1:30 PM",
    "from": "auto"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/military-time-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"time":"1:30 PM","from":"auto"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/military-time-converter · Page: /tools/military-time-converter

Health

BMI Calculatorpagebmi-calculatorbmi1 credit a call

Body mass index from height and weight, in centimetres and kilograms or in inches and pounds. Returns the BMI, its category (underweight, normal weight, overweight, obese) and the weight range that would count as normal at that height.

What it takes

height
number
Height in cm, or inches with imperial units.
e.g. 175
weight
number
Weight in kg, or pounds with imperial units.
e.g. 70
units?
string
metric (default) or imperial.
e.g. metric

What comes back

{
  "ok": true,
  "data": {
    "units": "metric",
    "heightCm": 175,
    "weightKg": 70,
    "bmi": 22.9,
    "category": "Normal weight",
    "healthyWeightRange": {
      "min": 56.7,
      "max": 76.3,
      "unit": "kg"
    },
    "categories": [
      {
        "label": "Underweight",
        "range": "< 18.5"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool bmi (BMI) with height: 175, weight: 70, units: metric.

The assistant then makes this tool call:

{
  "name": "bmi",
  "arguments": {
    "height": 175,
    "weight": 70,
    "units": "metric"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/bmi-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"height":175,"weight":70,"units":"metric"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/bmi-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "height": 175,
    "weight": 70,
    "units": "metric"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/bmi-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"height":175,"weight":70,"units":"metric"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/bmi-calculator · Page: /tools/bmi-calculator

Macro Calculatorpagemacro-calculatormacros1 credit a call

Daily protein, carbohydrate and fat grams for a calorie target and a goal. Calories come from the Mifflin-St Jeor basal rate times an activity factor, shifted by 500 kcal down to lose or 300 kcal up to gain and never below 1200, and are then split three ways: balanced 30/40/30, low carb 40/20/40 and high protein 40/30/30. This is an indication, not medical advice.

What it takes

age
number
Age in whole years. The formulas are fitted for 15 to 100.
e.g. 30
sex
string
Either male or female: the formulas use a different constant.
e.g. male
heightCm
number
Height in centimetres, 100 to 250. Convert feet and inches first.
e.g. 178
weightKg
number
Body weight in kilograms, 30 to 300. Convert pounds first.
e.g. 75
activity?
string
One of sedentary, light, moderate, active or extra. Defaults to moderate.
e.g. moderate
goal?
string
One of lose, maintain or gain. Defaults to maintain.
e.g. maintain

What comes back

{
  "ok": true,
  "data": {
    "bmr": 1718,
    "tdee": 2662,
    "calories": 2662,
    "goal": "maintain",
    "activity": "moderate",
    "activityFactor": 1.55,
    "formula": "Mifflin-St Jeor (1990)",
    "splits": [
      {
        "id": "balanced",
        "label": "Balanced",
        "protein": 30,
        "carbs": 40,
        "fat": 30,
        "proteinG": 200,
        "carbsG": 266,
        "fatG": 89
      }
    ],
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool macros (Macro) with age: 30, sex: male, heightCm: 178, weightKg: 75, activity: moderate, goal: maintain.

The assistant then makes this tool call:

{
  "name": "macros",
  "arguments": {
    "age": 30,
    "sex": "male",
    "heightCm": 178,
    "weightKg": 75,
    "activity": "moderate",
    "goal": "maintain"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/macro-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"age":30,"sex":"male","heightCm":178,"weightKg":75,"activity":"moderate","goal":"maintain"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/macro-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "age": 30,
    "sex": "male",
    "heightCm": 178,
    "weightKg": 75,
    "activity": "moderate",
    "goal": "maintain"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/macro-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"age":30,"sex":"male","heightCm":178,"weightKg":75,"activity":"moderate","goal":"maintain"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/macro-calculator · Page: /tools/macro-calculator

Sleep Calculatorpagesleep-calculatorsleep_times1 credit a call

Bedtimes or wake-up times that complete whole sleep cycles. From one clock time it counts six, five, four and three blocks of 90 minutes, plus the 15 minutes an average adult needs to fall asleep, so the alarm lands between cycles instead of in deep sleep. This is an indication, not medical advice.

What it takes

time
string
The time you must be up, or the time you are going to bed, as HH:MM on a 24-hour clock.
e.g. 07:00
mode?
string
wake to get bedtimes for that alarm, bed to get alarm times for that bedtime. Defaults to wake.
e.g. wake

What comes back

{
  "ok": true,
  "data": {
    "mode": "wake",
    "time": "07:00",
    "cycleMinutes": 90,
    "fallAsleepMinutes": 15,
    "options": [
      {
        "cycles": 6,
        "time": "9:45 PM",
        "hours": 9,
        "quality": "Optimal (9 h sleep)",
        "tone": "optimal"
      }
    ],
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool sleep_times (Sleep) with time: 07:00, mode: wake.

The assistant then makes this tool call:

{
  "name": "sleep_times",
  "arguments": {
    "time": "07:00",
    "mode": "wake"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/sleep-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"time":"07:00","mode":"wake"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/sleep-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "time": "07:00",
    "mode": "wake"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/sleep-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"time":"07:00","mode":"wake"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/sleep-calculator · Page: /tools/sleep-calculator

Water Intake Calculatorpagewater-intake-calculatorwater_intake1 credit a call

Daily water intake from weight, activity and climate. The base is 35 ml per kilogram of body weight, the midpoint of the usual 30 to 40 ml guideline, plus 350 ml for every 30 minutes of exercise and a flat 500 ml in a hot or humid climate, reported in litres and in 250 ml glasses. This is an indication, not medical advice.

What it takes

weightKg
number
Body weight in kilograms, 20 to 300. Convert pounds first.
e.g. 75
exerciseMinutes?
number
Minutes of exercise on a typical day. Every 30 minutes adds 350 ml. Defaults to 0.
e.g. 30
climate?
string
normal or hot. Hot or humid weather adds 500 ml. Defaults to normal.
e.g. normal

What comes back

{
  "ok": true,
  "data": {
    "weightKg": 75,
    "exerciseMinutes": 30,
    "climate": "normal",
    "baseL": 2.625,
    "exerciseL": 0.35,
    "climateL": 0,
    "totalL": 2.975,
    "glasses": 12,
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool water_intake (Water Intake) with weightKg: 75, exerciseMinutes: 30, climate: normal.

The assistant then makes this tool call:

{
  "name": "water_intake",
  "arguments": {
    "weightKg": 75,
    "exerciseMinutes": 30,
    "climate": "normal"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/water-intake-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"weightKg":75,"exerciseMinutes":30,"climate":"normal"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/water-intake-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "weightKg": 75,
    "exerciseMinutes": 30,
    "climate": "normal"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/water-intake-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"weightKg":75,"exerciseMinutes":30,"climate":"normal"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/water-intake-calculator · Page: /tools/water-intake-calculator

Body Fat Calculatorpagebody-fat-calculatorbody_fat1 credit a call

Body fat percentage from tape measurements using the US Navy method. The Hodgdon and Beckett (1984) circumference formula takes height, neck and waist for men and adds the hip for women, returns the American Council on Exercise category band, and splits a body weight into fat and lean mass when one is given. This is an indication, not medical advice.

What it takes

sex
string
Either male or female: the formulas use a different constant.
e.g. male
heightCm
number
Height in centimetres.
e.g. 178
neckCm
number
Neck circumference in centimetres, just below the larynx.
e.g. 38
waistCm
number
Waist circumference in centimetres: navel for men, narrowest point for women.
e.g. 85
hipCm?
number
Hip circumference in centimetres at the widest point. Required for women.
e.g. 95
weightKg?
number
Body weight in kilograms, only needed for the fat and lean mass split.
e.g. 80

What comes back

{
  "ok": true,
  "data": {
    "sex": "male",
    "bodyFatPercent": 16.44,
    "category": "Fitness",
    "fatMassKg": 13.15,
    "leanMassKg": 66.85,
    "formula": "US Navy circumference method (Hodgdon and Beckett, 1984)",
    "categories": [
      {
        "id": "fit",
        "label": "Fitness",
        "male": [
          14,
          17
        ],
        "female": [
          21,
          24
        ]
      }
    ],
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool body_fat (Body Fat) with sex: male, heightCm: 178, neckCm: 38, waistCm: 85, hipCm: 95, weightKg: 80.

The assistant then makes this tool call:

{
  "name": "body_fat",
  "arguments": {
    "sex": "male",
    "heightCm": 178,
    "neckCm": 38,
    "waistCm": 85,
    "hipCm": 95,
    "weightKg": 80
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/body-fat-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sex":"male","heightCm":178,"neckCm":38,"waistCm":85,"hipCm":95,"weightKg":80}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/body-fat-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "sex": "male",
    "heightCm": 178,
    "neckCm": 38,
    "waistCm": 85,
    "hipCm": 95,
    "weightKg": 80
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/body-fat-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"sex":"male","heightCm":178,"neckCm":38,"waistCm":85,"hipCm":95,"weightKg":80},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/body-fat-calculator · Page: /tools/body-fat-calculator

BMR Calculatorpagebmr-calculatorbmr1 credit a call

Basal metabolic rate from sex, age, height and weight, by both Mifflin-St Jeor (1990) and the revised Harris-Benedict (Roza and Shizgal, 1984), so the spread between them shows the uncertainty. Also returns total daily energy expenditure at all five activity factors, from 1.2 sedentary to 1.9 extra active. This is an indication, not medical advice.

What it takes

sex
string
Either male or female: the formulas use a different constant.
e.g. male
age
number
Age in whole years. The formulas are fitted for 15 to 100.
e.g. 30
heightCm
number
Height in centimetres, 100 to 250. Convert feet and inches first.
e.g. 178
weightKg
number
Body weight in kilograms, 30 to 300. Convert pounds first.
e.g. 75

What comes back

{
  "ok": true,
  "data": {
    "sex": "male",
    "age": 30,
    "mifflin": 1718,
    "harris": 1777,
    "formulas": [
      "Mifflin-St Jeor (1990)",
      "Harris-Benedict revised (1984)"
    ],
    "tdee": [
      {
        "id": "moderate",
        "label": "Moderately active (3-5 days/week)",
        "factor": 1.55,
        "mifflin": 2662,
        "harris": 2754
      }
    ],
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool bmr (BMR) with sex: male, age: 30, heightCm: 178, weightKg: 75.

The assistant then makes this tool call:

{
  "name": "bmr",
  "arguments": {
    "sex": "male",
    "age": 30,
    "heightCm": 178,
    "weightKg": 75
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/bmr-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sex":"male","age":30,"heightCm":178,"weightKg":75}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/bmr-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "sex": "male",
    "age": 30,
    "heightCm": 178,
    "weightKg": 75
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/bmr-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"sex":"male","age":30,"heightCm":178,"weightKg":75},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/bmr-calculator · Page: /tools/bmr-calculator

Ideal Weight Calculatorpageideal-weight-calculatorideal_weight1 credit a call

Ideal body weight from height and sex by the common formulas: Robinson (1983), Miller (1983), Devine (1974) and Hamwi (1964), with their average and the WHO healthy BMI band of 18.5 to 24.9 for the same height, all in kilograms and pounds. This is an indication, not medical advice.

What it takes

heightCm
number
Height in centimetres, 130 to 250. Convert feet and inches first.
e.g. 178
sex
string
Either male or female: the formulas use a different constant.
e.g. male

What comes back

{
  "ok": true,
  "data": {
    "sex": "male",
    "heightCm": 178,
    "formulas": [
      {
        "name": "Robinson (1983)",
        "kg": 71.15,
        "lb": 156.86
      }
    ],
    "averageKg": 72.49,
    "averageLb": 159.81,
    "healthyBmiRange": {
      "minKg": 58.61,
      "maxKg": 78.89,
      "minLb": 129.21,
      "maxLb": 173.92
    },
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool ideal_weight (Ideal Weight) with heightCm: 178, sex: male.

The assistant then makes this tool call:

{
  "name": "ideal_weight",
  "arguments": {
    "heightCm": 178,
    "sex": "male"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/ideal-weight-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"heightCm":178,"sex":"male"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/ideal-weight-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "heightCm": 178,
    "sex": "male"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/ideal-weight-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"heightCm":178,"sex":"male"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/ideal-weight-calculator · Page: /tools/ideal-weight-calculator

Calorie Calculatorpagecalorie-calculatordaily_calories1 credit a call

Daily calories to maintain, lose or gain weight from your details and activity. Mifflin-St Jeor (1990) sets the basal rate and drives the targets, revised Harris-Benedict (1984) is returned beside it for comparison, and the maintenance figure is also split into the balanced 30/40/30 macros. Consult a registered dietitian for personalized nutrition advice.

What it takes

sex
string
Either male or female: the formulas use a different constant.
e.g. male
age
number
Age in whole years. The formulas are fitted for 15 to 100.
e.g. 30
heightCm
number
Height in centimetres, 100 to 250. Convert feet and inches first.
e.g. 178
weightKg
number
Body weight in kilograms, 30 to 300. Convert pounds first.
e.g. 75
activity?
string
One of sedentary, light, moderate, active or veryActive. Defaults to moderate.
e.g. moderate

What comes back

{
  "ok": true,
  "data": {
    "sex": "male",
    "activity": "moderate",
    "activityFactor": 1.55,
    "bmrMifflin": 1718,
    "bmrHarris": 1777,
    "tdeeMifflin": 2662,
    "tdeeHarris": 2754,
    "maintenance": 2662,
    "weightLoss": 2162,
    "weightGain": 3162,
    "macros": {
      "protein": 200,
      "carbs": 266,
      "fat": 89
    },
    "formulas": [
      "Mifflin-St Jeor (1990)",
      "Harris-Benedict revised (1984)"
    ],
    "note": "Consult a registered dietitian for personalized nutrition advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool daily_calories (Calorie) with sex: male, age: 30, heightCm: 178, weightKg: 75, activity: moderate.

The assistant then makes this tool call:

{
  "name": "daily_calories",
  "arguments": {
    "sex": "male",
    "age": 30,
    "heightCm": 178,
    "weightKg": 75,
    "activity": "moderate"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/calorie-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sex":"male","age":30,"heightCm":178,"weightKg":75,"activity":"moderate"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/calorie-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "sex": "male",
    "age": 30,
    "heightCm": 178,
    "weightKg": 75,
    "activity": "moderate"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/calorie-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"sex":"male","age":30,"heightCm":178,"weightKg":75,"activity":"moderate"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/calorie-calculator · Page: /tools/calorie-calculator

Running Pace Calculatorpagerunning-pace-calculatorrunning_pace1 credit a call

Pace, time or distance from the other two, with splits. Give any two of the three and it returns the missing one, the pace in both minutes per kilometre and per mile, the speed in km/h, a cumulative split for every whole unit, and the finish time at that same pace for seven race distances from 1 km to the marathon.

What it takes

solve?
string
pace, time or distance: which one is missing. Defaults to pace.
e.g. pace
unit?
string
km or mi, the unit for distance and pace. Defaults to km.
e.g. km
distance?
number
Distance in the chosen unit, needed unless you are solving for distance.
e.g. 10
time?
string
Finish time as h:mm:ss or mm:ss, needed unless you are solving for time.
e.g. 55:00
pace?
string
Pace per unit as mm:ss, needed unless you are solving for pace.
e.g. 5:30

What comes back

{
  "ok": true,
  "data": {
    "solve": "pace",
    "unit": "km",
    "distance": 10,
    "timeSeconds": 3300,
    "time": "55:00",
    "paceSeconds": 330,
    "pace": "5:30",
    "pacePerKm": "5:30",
    "pacePerMile": "8:51",
    "speedKmh": 10.909,
    "resultLabel": "Pace per km",
    "resultValue": "5:30 /km",
    "splits": [
      {
        "at": 1,
        "time": "5:30"
      }
    ],
    "predictions": [
      {
        "label": "Marathon",
        "km": 42.195,
        "time": "3:52:04"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool running_pace (Running Pace) with solve: pace, unit: km, distance: 10, time: 55:00, pace: 5:30.

The assistant then makes this tool call:

{
  "name": "running_pace",
  "arguments": {
    "solve": "pace",
    "unit": "km",
    "distance": 10,
    "time": "55:00",
    "pace": "5:30"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/running-pace-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"solve":"pace","unit":"km","distance":10,"time":"55:00","pace":"5:30"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/running-pace-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "solve": "pace",
    "unit": "km",
    "distance": 10,
    "time": "55:00",
    "pace": "5:30"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/running-pace-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"solve":"pace","unit":"km","distance":10,"time":"55:00","pace":"5:30"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/running-pace-calculator · Page: /tools/running-pace-calculator

TDEE Calculatorpagetdee-calculatortdee1 credit a call

Total daily energy expenditure from BMR and activity level. The basal rate is Mifflin-St Jeor (1990) and comes from the same function the BMR tool uses, multiplied by an activity factor from 1.2 to 1.9, with five ready-made calorie targets from a 500 kcal cut to a 500 kcal bulk. This is an indication, not medical advice.

What it takes

sex
string
Either male or female: the formulas use a different constant.
e.g. male
age
number
Age in whole years. The formulas are fitted for 15 to 100.
e.g. 30
heightCm
number
Height in centimetres, 100 to 250. Convert feet and inches first.
e.g. 178
weightKg
number
Body weight in kilograms, 30 to 300. Convert pounds first.
e.g. 75
activityFactor?
number
Activity multiplier between 1.2 and 1.9. Defaults to 1.55, moderately active.
e.g. 1.55

What comes back

{
  "ok": true,
  "data": {
    "sex": "male",
    "activityFactor": 1.55,
    "bmr": 1718,
    "tdee": 2662,
    "formula": "Mifflin-St Jeor (1990)",
    "targets": [
      {
        "label": "Maintenance",
        "kcal": 2662,
        "note": "Hold current weight"
      }
    ],
    "note": "This is an indication, not medical advice."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool tdee (TDEE) with sex: male, age: 30, heightCm: 178, weightKg: 75, activityFactor: 1.55.

The assistant then makes this tool call:

{
  "name": "tdee",
  "arguments": {
    "sex": "male",
    "age": 30,
    "heightCm": 178,
    "weightKg": 75,
    "activityFactor": 1.55
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/tdee-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sex":"male","age":30,"heightCm":178,"weightKg":75,"activityFactor":1.55}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/tdee-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "sex": "male",
    "age": 30,
    "heightCm": 178,
    "weightKg": 75,
    "activityFactor": 1.55
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/tdee-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"sex":"male","age":30,"heightCm":178,"weightKg":75,"activityFactor":1.55},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/tdee-calculator · Page: /tools/tdee-calculator

Due Date Calculatorpagedue-date-calculatorpregnancy_due_date1 credit a call

Estimated due date and current week from the last period or conception date. Naegele's rule adds 280 days to the first day of the last menstrual period, or 266 days when counting from conception, and the result also carries gestational age, trimester and the 12, 20, 28 and 37 week milestone dates. Estimate only, consult your midwife or doctor.

What it takes

date
string
The first day of the last menstrual period, or the conception date, as YYYY-MM-DD.
e.g. 2026-01-01
method?
string
lmp when the date is the last period, conception when it is the conception date. Defaults to lmp.
e.g. lmp
today?
string
The day to measure gestational age on, YYYY-MM-DD. Leave out for today.
e.g. 2026-03-01

What comes back

{
  "ok": true,
  "data": {
    "method": "lmp",
    "from": "2026-01-01",
    "lmpDate": "2026-01-01",
    "dueDate": "2026-10-08",
    "gestationalAge": {
      "weeks": 8,
      "days": 3,
      "totalDays": 59
    },
    "trimester": "First trimester",
    "milestones": [
      {
        "label": "Full term (37 weeks)",
        "date": "2026-09-17"
      }
    ],
    "formula": "LMP + 280 days (Naegele's rule)",
    "note": "Estimate only, consult your midwife or doctor."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool pregnancy_due_date (Due Date) with date: 2026-01-01, method: lmp, today: 2026-03-01.

The assistant then makes this tool call:

{
  "name": "pregnancy_due_date",
  "arguments": {
    "date": "2026-01-01",
    "method": "lmp",
    "today": "2026-03-01"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/due-date-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"date":"2026-01-01","method":"lmp","today":"2026-03-01"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/due-date-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "date": "2026-01-01",
    "method": "lmp",
    "today": "2026-03-01"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/due-date-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"date":"2026-01-01","method":"lmp","today":"2026-03-01"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/due-date-calculator · Page: /tools/due-date-calculator

Ovulation Calculatorpageovulation-calculatorovulation_window1 credit a call

Fertile window and ovulation day from the last period and cycle length. The calendar method places ovulation 14 days before the next period rather than 14 days after the last one, opens the fertile window five days before it and closes it one day after, and projects the same pattern across three cycles. Estimate only, consult your midwife or doctor.

What it takes

lastPeriod
string
The first day of the last period, as YYYY-MM-DD.
e.g. 2026-03-01
cycleLength?
number
Average cycle length in whole days, 21 to 40. Defaults to 28.
e.g. 28
today?
string
The day to count the days until ovulation from, YYYY-MM-DD. Optional.
e.g. 2026-03-10

What comes back

{
  "ok": true,
  "data": {
    "cycleLength": 28,
    "cycles": [
      {
        "periodStart": "2026-03-01",
        "ovulation": "2026-03-15",
        "fertileStart": "2026-03-10",
        "fertileEnd": "2026-03-16",
        "nextPeriod": "2026-03-29"
      }
    ],
    "ovulation": "2026-03-15",
    "fertileWindow": {
      "start": "2026-03-10",
      "end": "2026-03-16"
    },
    "nextPeriod": "2026-03-29",
    "daysUntilOvulation": 5,
    "daysUntilNextPeriod": 19,
    "note": "Estimate only, consult your midwife or doctor."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool ovulation_window (Ovulation) with lastPeriod: 2026-03-01, cycleLength: 28, today: 2026-03-10.

The assistant then makes this tool call:

{
  "name": "ovulation_window",
  "arguments": {
    "lastPeriod": "2026-03-01",
    "cycleLength": 28,
    "today": "2026-03-10"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/ovulation-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lastPeriod":"2026-03-01","cycleLength":28,"today":"2026-03-10"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/ovulation-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "lastPeriod": "2026-03-01",
    "cycleLength": 28,
    "today": "2026-03-10"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/ovulation-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"lastPeriod":"2026-03-01","cycleLength":28,"today":"2026-03-10"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/ovulation-calculator · Page: /tools/ovulation-calculator

One Rep Max Calculatorpageone-rep-max-calculatorone_rep_max1 credit a call

Estimated one repetition maximum from a weight and reps, with percentages. Four formulas run side by side, Epley, Brzycki, Lombardi and O'Conner, and their average drives a training table from 95% down to 50% with the usual rep range for each load. This is an indication for training purposes, not medical advice.

What it takes

weight
number
The load lifted, in kilograms or pounds. The output uses the same unit.
e.g. 100
reps
number
Repetitions completed, 1 to 15. A single is a tested max, not an estimate.
e.g. 5

What comes back

{
  "ok": true,
  "data": {
    "weight": 100,
    "reps": 5,
    "epley": 116.67,
    "brzycki": 112.5,
    "lombardi": 117.46,
    "oconner": 112.5,
    "average": 114.78,
    "tested": false,
    "formulas": [
      "Epley",
      "Brzycki",
      "Lombardi",
      "O'Conner"
    ],
    "percentages": [
      {
        "percent": 85,
        "weight": 97.56,
        "reps": "5-6",
        "focus": "Strength"
      }
    ],
    "note": "This is an indication for training purposes, not medical advice. Never attempt a true max without proper warm-up and a spotter."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool one_rep_max (One Rep Max) with weight: 100, reps: 5.

The assistant then makes this tool call:

{
  "name": "one_rep_max",
  "arguments": {
    "weight": 100,
    "reps": 5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/one-rep-max-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"weight":100,"reps":5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/one-rep-max-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "weight": 100,
    "reps": 5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/one-rep-max-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"weight":100,"reps":5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/one-rep-max-calculator · Page: /tools/one-rep-max-calculator

Dog Age Calculatorpagedog-age-calculatordog_age1 credit a call

Convert a dog's age into human years with the epigenetic research formula, 16 x ln(age) + 31, and return the size-adjusted chart estimate and the old multiply-by-seven answer next to it. Cats are handled by the standard veterinary chart.

What it takes

age
number
How old the pet is, in years.
e.g. 5
species?
string
dog (default) or cat.
e.g. dog
size?
string
small, medium (default) or large, which changes the chart estimate for a dog.
e.g. medium

What comes back

{
  "ok": true,
  "data": {
    "species": "dog",
    "size": "medium",
    "age": 5,
    "humanYears": 56.75,
    "method": "Modern research formula",
    "chartYears": 36,
    "sevenTimesRule": 35
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dog_age (Dog Age) with age: 5, species: dog, size: medium.

The assistant then makes this tool call:

{
  "name": "dog_age",
  "arguments": {
    "age": 5,
    "species": "dog",
    "size": "medium"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dog-age-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"age":5,"species":"dog","size":"medium"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dog-age-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "age": 5,
    "species": "dog",
    "size": "medium"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dog-age-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"age":5,"species":"dog","size":"medium"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dog-age-calculator · Page: /tools/dog-age-calculator

Units

PX to REM Converterpagepx-rem-converterpx_to_rem1 credit a call

Convert a pixel value to rem or a rem value to pixels for a given root font size, 16px unless told otherwise. Returns both numbers and CSS-ready strings.

What it takes

value
number
The size to convert.
e.g. 24
direction?
string
Which way to convert: "px-to-rem" (default) or "rem-to-px".
e.g. px-to-rem
rootFontSize?
number
Root font size in pixels that 1rem equals. Defaults to 16.
e.g. 16

What comes back

{
  "ok": true,
  "data": {
    "input": 24,
    "direction": "px-to-rem",
    "rootFontSize": 16,
    "px": 24,
    "rem": 1.5,
    "pxText": "24px",
    "remText": "1.5rem"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool px_to_rem (PX to REM) with value: 24, direction: px-to-rem, rootFontSize: 16.

The assistant then makes this tool call:

{
  "name": "px_to_rem",
  "arguments": {
    "value": 24,
    "direction": "px-to-rem",
    "rootFontSize": 16
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/px-rem-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":24,"direction":"px-to-rem","rootFontSize":16}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/px-rem-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "value": 24,
    "direction": "px-to-rem",
    "rootFontSize": 16
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/px-rem-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"value":24,"direction":"px-to-rem","rootFontSize":16},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/px-rem-converter · Page: /tools/px-rem-converter

Unit Converterpageunit-converterconvert_units1 credit a call

Convert a value between units of length (m, km, cm, mm, mi, yd, ft, in, nmi, um), weight (kg, g, mg, lb, oz, st, t, us_ton, imperial_ton, ug), temperature (c, f, k), speed (kmh, ms, mph, kn) or data (b, kb, mb, gb, tb, in 1024 steps). Units are matched by key, full name or common alias.

What it takes

value
number
The number to convert.
e.g. 10
from
string
Unit of the input value, by key or name.
e.g. km
to
string
Unit to convert into, same category as from.
e.g. mi
category?
string
Optional category to disambiguate: length, weight, temperature, speed or data.
e.g. length

What comes back

{
  "ok": true,
  "data": {
    "value": 10,
    "from": {
      "key": "km",
      "name": "Kilometers (km)"
    },
    "to": {
      "key": "mi",
      "name": "Miles"
    },
    "category": "length",
    "result": 6.213711922373339,
    "formatted": "6.213712"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool convert_units (Unit) with value: 10, from: km, to: mi, category: length.

The assistant then makes this tool call:

{
  "name": "convert_units",
  "arguments": {
    "value": 10,
    "from": "km",
    "to": "mi",
    "category": "length"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/unit-converter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":10,"from":"km","to":"mi","category":"length"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/unit-converter", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "value": 10,
    "from": "km",
    "to": "mi",
    "category": "length"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/unit-converter",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"value":10,"from":"km","to":"mi","category":"length"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/unit-converter · Page: /tools/unit-converter

Fraction Calculatorpagefraction-calculatorfractions1 credit a call

Add, subtract, multiply or divide two fractions, mixed numbers included, and get the answer reduced to lowest terms. The arithmetic is exact whole-number arithmetic, so nothing is rounded through a decimal on the way, and the result comes back as a fraction, a mixed number and a decimal.

What it takes

a
object
The first fraction as {numerator, denominator}, with an optional whole for a mixed number.
e.g. {"numerator":1,"denominator":2}
b
object
The second fraction as {numerator, denominator}, with an optional whole for a mixed number.
e.g. {"numerator":1,"denominator":3}
operation
string
One of "+", "-", "*" or "/".
e.g. +

What comes back

{
  "ok": true,
  "data": {
    "numerator": 5,
    "denominator": 6,
    "fraction": "5/6",
    "mixed": "5/6",
    "decimal": 0.8333333333333334,
    "expression": "1/2 + 1/3 = 5/6"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool fractions (Fraction) with a: {"numerator":1,"denominator":2}, b: {"numerator":1,"denominator":3}, operation: +.

The assistant then makes this tool call:

{
  "name": "fractions",
  "arguments": {
    "a": {
      "numerator": 1,
      "denominator": 2
    },
    "b": {
      "numerator": 1,
      "denominator": 3
    },
    "operation": "+"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/fraction-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"a":{"numerator":1,"denominator":2},"b":{"numerator":1,"denominator":3},"operation":"+"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/fraction-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "a": {
      "numerator": 1,
      "denominator": 2
    },
    "b": {
      "numerator": 1,
      "denominator": 3
    },
    "operation": "+"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/fraction-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"a":{"numerator":1,"denominator":2},"b":{"numerator":1,"denominator":3},"operation":"+"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/fraction-calculator · Page: /tools/fraction-calculator

Ratio Calculatorpageratio-calculatorratio1 credit a call

Reduce a ratio to lowest whole-number terms, solve a proportion A:B = C:D for the one value left out, or scale a ratio by a factor for a recipe or a mix. Reducing is exact whole-number arithmetic, so a ratio written with decimals is scaled to integers first rather than rounded.

What it takes

mode
string
One of simplify, solve or scale.
e.g. simplify
a?
number
First part of the ratio. Required for simplify and scale; in solve mode leave exactly one of a, b, c, d out.
e.g. 1920
b?
number
Second part of the ratio.
e.g. 1080
c?
number
Third value of the proportion, used by solve mode only.
e.g. 9
d?
number
Fourth value of the proportion, used by solve mode only.
e.g. 12
factor?
number
The multiplier used by scale mode only.
e.g. 1.5

What comes back

{
  "ok": true,
  "data": {
    "mode": "simplify",
    "a": 16,
    "b": 9,
    "ratio": "16:9",
    "decimal": 1.7777777777777777,
    "solvedFor": null,
    "solved": null
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool ratio (Ratio) with mode: simplify, a: 1920, b: 1080, c: 9, d: 12, factor: 1.5.

The assistant then makes this tool call:

{
  "name": "ratio",
  "arguments": {
    "mode": "simplify",
    "a": 1920,
    "b": 1080,
    "c": 9,
    "d": 12,
    "factor": 1.5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/ratio-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"simplify","a":1920,"b":1080,"c":9,"d":12,"factor":1.5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/ratio-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mode": "simplify",
    "a": 1920,
    "b": 1080,
    "c": 9,
    "d": 12,
    "factor": 1.5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/ratio-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"mode":"simplify","a":1920,"b":1080,"c":9,"d":12,"factor":1.5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/ratio-calculator · Page: /tools/ratio-calculator

Aspect Ratio Calculatorpageaspect-ratio-calculatoraspect_ratio1 credit a call

Reduce a width and a height to their aspect ratio, or work out the side that is missing at a given ratio so an image or a canvas keeps its proportions. Also returns the decimal ratio, the megapixels and whether the result is landscape, portrait or square.

What it takes

width?
number
The width. Give it with a height to read off the ratio, or with ratioWidth and ratioHeight to solve for the height.
e.g. 1920
height?
number
The height. Give it with a width to read off the ratio, or with the ratio pair to solve for the width.
e.g. 1080
ratioWidth?
number
Width side of the ratio to hold, e.g. 16. Used when a side is missing.
e.g. 16
ratioHeight?
number
Height side of the ratio to hold, e.g. 9. Used when a side is missing.
e.g. 9

What comes back

{
  "ok": true,
  "data": {
    "width": 1920,
    "height": 1080,
    "ratio": "16:9",
    "ratioWidth": 16,
    "ratioHeight": 9,
    "decimal": 1.7777777777777777,
    "megapixels": 2.0736,
    "orientation": "landscape",
    "solvedFor": "ratio"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool aspect_ratio (Aspect Ratio) with width: 1920, height: 1080, ratioWidth: 16, ratioHeight: 9.

The assistant then makes this tool call:

{
  "name": "aspect_ratio",
  "arguments": {
    "width": 1920,
    "height": 1080,
    "ratioWidth": 16,
    "ratioHeight": 9
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/aspect-ratio-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"width":1920,"height":1080,"ratioWidth":16,"ratioHeight":9}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/aspect-ratio-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "width": 1920,
    "height": 1080,
    "ratioWidth": 16,
    "ratioHeight": 9
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/aspect-ratio-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"width":1920,"height":1080,"ratioWidth":16,"ratioHeight":9},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/aspect-ratio-calculator · Page: /tools/aspect-ratio-calculator

School and study

GPA Calculatorpagegpa-calculatorgpa1 credit a call

Work out a grade point average from courses that each have a grade and a credit weight, on the 4.0 letter scale, the 10-point European scale or percentages. Returns the GPA on the 4.0 scale with its letter, its honours classification and the credits counted.

What it takes

courses
array
The courses to average, each an object with a grade and a credits number, plus an optional name.
e.g. [{"name":"Calculus I","grade":"A","credits":4},{"name":"English Composition","grade":"A-","credits":3},{"name":"Introduction to CS","grade":"B+","credits":3}]
scale?
string
The grading scale: "4.0" letters (default), "10-point" numbers, or "percentage".
e.g. 4.0

What comes back

{
  "ok": true,
  "data": {
    "scale": "4.0",
    "gpa": 3.7,
    "letter": "A-",
    "classification": "Magna Cum Laude",
    "totalCredits": 10,
    "countedCourses": 3,
    "courses": [
      {
        "name": "Calculus I",
        "grade": "A",
        "credits": 4,
        "points": 4
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool gpa (GPA) with courses: [{"name":"Calculus I","grade":"A","credits":4},{"name":"English Composition","grade":"A-","credits":3},{"name":"Introduction to CS","grade":"B+","credits":3}], scale: 4.0.

The assistant then makes this tool call:

{
  "name": "gpa",
  "arguments": {
    "courses": [
      {
        "name": "Calculus I",
        "grade": "A",
        "credits": 4
      },
      {
        "name": "English Composition",
        "grade": "A-",
        "credits": 3
      },
      {
        "name": "Introduction to CS",
        "grade": "B+",
        "credits": 3
      }
    ],
    "scale": "4.0"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/gpa-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"courses":[{"name":"Calculus I","grade":"A","credits":4},{"name":"English Composition","grade":"A-","credits":3},{"name":"Introduction to CS","grade":"B+","credits":3}],"scale":"4.0"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/gpa-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "courses": [
      {
        "name": "Calculus I",
        "grade": "A",
        "credits": 4
      },
      {
        "name": "English Composition",
        "grade": "A-",
        "credits": 3
      },
      {
        "name": "Introduction to CS",
        "grade": "B+",
        "credits": 3
      }
    ],
    "scale": "4.0"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/gpa-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"courses":[{"name":"Calculus I","grade":"A","credits":4},{"name":"English Composition","grade":"A-","credits":3},{"name":"Introduction to CS","grade":"B+","credits":3}],"scale":"4.0"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/gpa-calculator · Page: /tools/gpa-calculator

Grade Calculatorpagegrade-calculatorweighted_grade1 credit a call

Average the assessments of one course into the weighted grade it stands at, from each item's score and what it is worth. Divides by the weight actually entered, so a half-graded course reports the average so far rather than a score dragged down by work not handed in yet.

What it takes

items
array
The graded assessments, each an object with a score in percent and a weight in percent, plus an optional name.
e.g. [{"name":"Homework","score":85,"weight":20},{"name":"Midterm","score":78,"weight":30},{"name":"Project","score":92,"weight":20}]

What comes back

{
  "ok": true,
  "data": {
    "weightedAverage": 84,
    "totalWeight": 70,
    "remainingWeight": 30,
    "countedItems": 3,
    "items": [
      {
        "name": "Homework",
        "score": 85,
        "weight": 20,
        "points": 1700
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool weighted_grade (Grade) with items: [{"name":"Homework","score":85,"weight":20},{"name":"Midterm","score":78,"weight":30},{"name":"Project","score":92,"weight":20}].

The assistant then makes this tool call:

{
  "name": "weighted_grade",
  "arguments": {
    "items": [
      {
        "name": "Homework",
        "score": 85,
        "weight": 20
      },
      {
        "name": "Midterm",
        "score": 78,
        "weight": 30
      },
      {
        "name": "Project",
        "score": 92,
        "weight": 20
      }
    ]
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/grade-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"name":"Homework","score":85,"weight":20},{"name":"Midterm","score":78,"weight":30},{"name":"Project","score":92,"weight":20}]}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/grade-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "items": [
      {
        "name": "Homework",
        "score": 85,
        "weight": 20
      },
      {
        "name": "Midterm",
        "score": 78,
        "weight": 30
      },
      {
        "name": "Project",
        "score": 92,
        "weight": 20
      }
    ]
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/grade-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"items":[{"name":"Homework","score":85,"weight":20},{"name":"Midterm","score":78,"weight":30},{"name":"Project","score":92,"weight":20}]},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/grade-calculator · Page: /tools/grade-calculator

Final Grade Calculatorpagefinal-grade-calculatorfinal_grade_needed1 credit a call

Work out the score needed on a final exam to finish a course at a target grade, from the grade so far and what the final is worth. Says plainly whether the target is reachable, already secured, or out of reach, and prices the usual A to D targets at the same weight.

What it takes

currentGrade
number
Where the course grade stands now, in percent.
e.g. 85
targetGrade
number
The grade you want to end up with, in percent.
e.g. 90
finalWeightPercent
number
How much of the course grade the final exam decides, in percent.
e.g. 30

What comes back

{
  "ok": true,
  "data": {
    "currentGrade": 85,
    "targetGrade": 90,
    "finalWeightPercent": 30,
    "requiredScore": 101.67,
    "achievable": false,
    "alreadySecured": false,
    "verdict": {
      "text": "Not possible without extra credit",
      "kind": "impossible"
    },
    "commonTargets": [
      {
        "label": "A (90%)",
        "target": 90,
        "required": 101.67,
        "verdict": {
          "text": "Not possible without extra credit",
          "kind": "impossible"
        }
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool final_grade_needed (Final Grade) with currentGrade: 85, targetGrade: 90, finalWeightPercent: 30.

The assistant then makes this tool call:

{
  "name": "final_grade_needed",
  "arguments": {
    "currentGrade": 85,
    "targetGrade": 90,
    "finalWeightPercent": 30
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/final-grade-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"currentGrade":85,"targetGrade":90,"finalWeightPercent":30}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/final-grade-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "currentGrade": 85,
    "targetGrade": 90,
    "finalWeightPercent": 30
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/final-grade-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"currentGrade":85,"targetGrade":90,"finalWeightPercent":30},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/final-grade-calculator · Page: /tools/final-grade-calculator

Test Grade Calculatorpagetest-grade-calculatortest_grade1 credit a call

Turn a number of questions and a number of wrong answers into a percentage and a letter grade, with a chart pricing every possible number of wrong answers on that test. The letter cutoffs default to the US ten point scale and can be replaced.

What it takes

questions
number
The number of questions on the test, 1 to 1000.
e.g. 25
wrong
number
How many of them were answered wrong.
e.g. 3
scale?
object
Letter cutoffs as {a, b, c, d} percentages. Defaults to 90, 80, 70, 60.
e.g. {"a":90,"b":80,"c":70,"d":60}

What comes back

{
  "ok": true,
  "data": {
    "questions": 25,
    "wrong": 3,
    "correct": 22,
    "score": 88,
    "letter": "B",
    "scale": {
      "a": 90,
      "b": 80,
      "c": 70,
      "d": 60
    },
    "chart": [
      {
        "wrong": 0,
        "score": 100,
        "letter": "A"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool test_grade (Test Grade) with questions: 25, wrong: 3, scale: {"a":90,"b":80,"c":70,"d":60}.

The assistant then makes this tool call:

{
  "name": "test_grade",
  "arguments": {
    "questions": 25,
    "wrong": 3,
    "scale": {
      "a": 90,
      "b": 80,
      "c": 70,
      "d": 60
    }
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/test-grade-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"questions":25,"wrong":3,"scale":{"a":90,"b":80,"c":70,"d":60}}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/test-grade-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "questions": 25,
    "wrong": 3,
    "scale": {
      "a": 90,
      "b": 80,
      "c": 70,
      "d": 60
    }
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/test-grade-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"questions":25,"wrong":3,"scale":{"a":90,"b":80,"c":70,"d":60}},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/test-grade-calculator · Page: /tools/test-grade-calculator

Grade Curve Calculatorpagegrade-curve-calculatorgrade_curve1 credit a call

Curve a set of test scores by one of the three methods teachers use: add the same points to everyone, take the square root and multiply by ten, or scale the highest score in the room up to 100. Returns every adjusted score plus the class mean, median, minimum and maximum before and after.

What it takes

scores
array
The raw scores to curve, as numbers between 0 and 150.
e.g. [72,85,64,91,58,77,69,88]
method?
string
flat, sqrt (default) or scale. flat needs flatPoints, the other two do not.
e.g. sqrt
flatPoints?
number
Points added to every score by the flat method. Defaults to 0.
e.g. 5
capAt100?
boolean
Whether curved scores are capped at 100. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "method": "sqrt",
    "capAt100": true,
    "flatPoints": 5,
    "count": 8,
    "scores": [
      {
        "original": 72,
        "curved": 84.85
      }
    ],
    "before": {
      "mean": 75.5,
      "median": 74.5,
      "min": 58,
      "max": 91
    },
    "after": {
      "mean": 86.65,
      "median": 86.3,
      "min": 76.16,
      "max": 95.39
    }
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool grade_curve (Grade Curve) with scores: [72,85,64,91,58,77,69,88], method: sqrt, flatPoints: 5, capAt100: true.

The assistant then makes this tool call:

{
  "name": "grade_curve",
  "arguments": {
    "scores": [
      72,
      85,
      64,
      91,
      58,
      77,
      69,
      88
    ],
    "method": "sqrt",
    "flatPoints": 5,
    "capAt100": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/grade-curve-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scores":[72,85,64,91,58,77,69,88],"method":"sqrt","flatPoints":5,"capAt100":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/grade-curve-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "scores": [
      72,
      85,
      64,
      91,
      58,
      77,
      69,
      88
    ],
    "method": "sqrt",
    "flatPoints": 5,
    "capAt100": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/grade-curve-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"scores":[72,85,64,91,58,77,69,88],"method":"sqrt","flatPoints":5,"capAt100":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/grade-curve-calculator · Page: /tools/grade-curve-calculator

Percentage to CGPA Calculatorpagepercentage-to-cgpa-calculatorpercentage_to_cgpa1 credit a call

Convert percentage marks to CGPA on the Indian 10-point scale using the CBSE divisor of 9.5, or convert a CGPA back to a percentage. Returns the indicative American 4-point GPA alongside it, which is what an overseas application asks for.

What it takes

value
number
The percentage to convert, or the CGPA when direction is toPercent.
e.g. 85
direction?
string
toCgpa (default) or toPercent.
e.g. toCgpa
divisor?
number
The conversion factor, 9.5 by default.
e.g. 9.5

What comes back

{
  "ok": true,
  "data": {
    "direction": "toCgpa",
    "divisor": 9.5,
    "input": 85,
    "cgpa": 8.95,
    "percentage": 85,
    "gpa4": 3.15,
    "formula": "85 / 9.5 = 8.95 CGPA"
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool percentage_to_cgpa (Percentage to CGPA) with value: 85, direction: toCgpa, divisor: 9.5.

The assistant then makes this tool call:

{
  "name": "percentage_to_cgpa",
  "arguments": {
    "value": 85,
    "direction": "toCgpa",
    "divisor": 9.5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/percentage-to-cgpa-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":85,"direction":"toCgpa","divisor":9.5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/percentage-to-cgpa-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "value": 85,
    "direction": "toCgpa",
    "divisor": 9.5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/percentage-to-cgpa-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"value":85,"direction":"toCgpa","divisor":9.5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/percentage-to-cgpa-calculator · Page: /tools/percentage-to-cgpa-calculator

Dutch Exam Grade Calculatorpagedutch-exam-grade-calculatordutch_exam_grade1 credit a call

Turn Dutch exam results into final grades and a havo/vwo pass check: per subject the eindcijfer is the average of the schoolexamen and centraal examen grade rounded to a whole number, and the slaag-zakregeling is then applied in full, the CE average of 5.50, the kernvakkenregel for Nederlands, Engels and wiskunde, and the compensation rules. A CE grade may be given directly or derived from the points scored, the maximum score and the N-term. An indication, not an official determination, and vmbo has its own regulation.

What it takes

subjects
array
The exam subjects, each with a name, an se grade and either a ce grade or ceScore plus ceMaxScore and nTerm. A subject without a central exam gets its rounded se grade.
e.g. [{"name":"Nederlands","se":6.5,"ce":6.2},{"name":"Engels","se":7.1,"ce":6.8},{"name":"Wiskunde A","se":5.8,"ce":5.4},{"name":"Geschiedenis","se":6.9,"ce":7.2},{"name":"Biologie","se":6.4,"ce":6.1},{"name":"Economie","se":7,"ce":6.6}]

What comes back

{
  "ok": true,
  "data": {
    "subjects": [
      {
        "name": "Nederlands",
        "se": 6.5,
        "ce": 6.2,
        "hasCe": true,
        "final": 6,
        "core": true
      }
    ],
    "subjectCount": 6,
    "ceAverage": 6.38,
    "finalAverage": 6.5,
    "passed": true,
    "checks": [
      {
        "ok": true,
        "text": "All final grades are 6 or higher"
      }
    ],
    "note": "This is an indication, not advice. Always check examenblad.nl."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool dutch_exam_grade (Dutch Exam Grade) with subjects: [{"name":"Nederlands","se":6.5,"ce":6.2},{"name":"Engels","se":7.1,"ce":6.8},{"name":"Wiskunde A","se":5.8,"ce":5.4},{"name":"Geschiedenis","se":6.9,"ce":7.2},{"name":"Biologie","se":6.4,"ce":6.1},{"name":"Economie","se":7,"ce":6.6}].

The assistant then makes this tool call:

{
  "name": "dutch_exam_grade",
  "arguments": {
    "subjects": [
      {
        "name": "Nederlands",
        "se": 6.5,
        "ce": 6.2
      },
      {
        "name": "Engels",
        "se": 7.1,
        "ce": 6.8
      },
      {
        "name": "Wiskunde A",
        "se": 5.8,
        "ce": 5.4
      },
      {
        "name": "Geschiedenis",
        "se": 6.9,
        "ce": 7.2
      },
      {
        "name": "Biologie",
        "se": 6.4,
        "ce": 6.1
      },
      {
        "name": "Economie",
        "se": 7,
        "ce": 6.6
      }
    ]
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/dutch-exam-grade-calculator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"subjects":[{"name":"Nederlands","se":6.5,"ce":6.2},{"name":"Engels","se":7.1,"ce":6.8},{"name":"Wiskunde A","se":5.8,"ce":5.4},{"name":"Geschiedenis","se":6.9,"ce":7.2},{"name":"Biologie","se":6.4,"ce":6.1},{"name":"Economie","se":7,"ce":6.6}]}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/dutch-exam-grade-calculator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "subjects": [
      {
        "name": "Nederlands",
        "se": 6.5,
        "ce": 6.2
      },
      {
        "name": "Engels",
        "se": 7.1,
        "ce": 6.8
      },
      {
        "name": "Wiskunde A",
        "se": 5.8,
        "ce": 5.4
      },
      {
        "name": "Geschiedenis",
        "se": 6.9,
        "ce": 7.2
      },
      {
        "name": "Biologie",
        "se": 6.4,
        "ce": 6.1
      },
      {
        "name": "Economie",
        "se": 7,
        "ce": 6.6
      }
    ]
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/dutch-exam-grade-calculator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"subjects":[{"name":"Nederlands","se":6.5,"ce":6.2},{"name":"Engels","se":7.1,"ce":6.8},{"name":"Wiskunde A","se":5.8,"ce":5.4},{"name":"Geschiedenis","se":6.9,"ce":7.2},{"name":"Biologie","se":6.4,"ce":6.1},{"name":"Economie","se":7,"ce":6.6}]},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/dutch-exam-grade-calculator · Page: /tools/dutch-exam-grade-calculator

Test data

Test BSN Generatorpagetest-bsn-generatorgenerate_test_bsn1 credit a call

Generate Dutch BSN numbers that pass the elfproef, for test environments where a real citizen number must never appear.

What it takes

count?
number
How many numbers to generate, 1 to 100. Defaults to 1.
e.g. 5

What comes back

{
  "ok": true,
  "data": {
    "count": 5,
    "bsns": [
      "123456782"
    ],
    "note": "Test numbers that pass the elfproef (11-check). They are not linked to real persons."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_test_bsn (Test BSN) with count: 5.

The assistant then makes this tool call:

{
  "name": "generate_test_bsn",
  "arguments": {
    "count": 5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/test-bsn-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count":5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/test-bsn-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "count": 5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/test-bsn-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"count":5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/test-bsn-generator · Page: /tools/test-bsn-generator

Test IBAN Generatorpagetest-iban-generatorgenerate_test_iban1 credit a call

Generate IBANs for NL, DE, BE, FR or GB that satisfy the country's own format and every check digit inside it, tied to no real account.

What it takes

count?
number
How many IBANs to generate, 1 to 100. Defaults to 1.
e.g. 5
country?
string
Country code: "NL" (default), "DE", "BE", "FR" or "GB".
e.g. NL

What comes back

{
  "ok": true,
  "data": {
    "count": 5,
    "country": "NL",
    "ibans": [
      "NL21INGB0123456789"
    ],
    "note": "Structurally valid IBANs: the country's own character layout, the mod-97 check digits, and for BE and FR the national check digit the bank computes over the account. Not linked to real bank accounts. For test environments only."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_test_iban (Test IBAN) with count: 5, country: NL.

The assistant then makes this tool call:

{
  "name": "generate_test_iban",
  "arguments": {
    "count": 5,
    "country": "NL"
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/test-iban-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count":5,"country":"NL"}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/test-iban-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "count": 5,
    "country": "NL"
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/test-iban-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"count":5,"country":"NL"},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/test-iban-generator · Page: /tools/test-iban-generator

BRP Test Data Generatorpagebrp-test-data-generatorgenerate_brp_test_data1 credit a call

Generate Dutch BRP/GBA test persons with life events, families and addresses; the same seed always returns the same people.

What it takes

format?
string
"json" (default), "csv", or "gba-totaalfile" for the fixed-width GBA file.
e.g. json
options?
object
Generator settings: count, seed, minAge, maxAge, eventMix, outputMode and the rest of the tool page's options.
e.g. {"count":3,"seed":42}
totaalfile?
object
Extra settings used only by the gba-totaalfile format, such as the record layout.

What comes back

{
  "ok": true,
  "data": {
    "format": "json",
    "count": 3,
    "seed": 42,
    "people": [
      {
        "bsn": "123456782",
        "lifeEvent": "birth"
      }
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_brp_test_data (BRP Test Data) with format: json, options: {"count":3,"seed":42}.

The assistant then makes this tool call:

{
  "name": "generate_brp_test_data",
  "arguments": {
    "format": "json",
    "options": {
      "count": 3,
      "seed": 42
    }
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/brp-test-data-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"format":"json","options":{"count":3,"seed":42}}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/brp-test-data-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "format": "json",
    "options": {
      "count": 3,
      "seed": 42
    }
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/brp-test-data-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"format":"json","options":{"count":3,"seed":42}},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/brp-test-data-generator · Page: /tools/brp-test-data-generator

UPA File Generatorpageupa-file-generatorgenerate_upa_files1 credit a call

Generate UPA pension declaration XML with employments, schemes and deliberate defects, deterministic per seed.

What it takes

format?
string
"xml" (default) for the files themselves, "summary" for names and counts, "participants-csv" for the people.
e.g. summary
options?
object
Nested generator settings: schemaVersion, schemeType, schemes, declaration, population, household and period.
e.g. {"population":{"count":3}}

What comes back

{
  "ok": true,
  "data": {
    "format": "summary",
    "fileCount": 1,
    "peopleCount": 3,
    "seed": 20270101,
    "fileNames": [
      "UPA_2027-01.xml"
    ]
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_upa_files (UPA File) with format: summary, options: {"population":{"count":3}}.

The assistant then makes this tool call:

{
  "name": "generate_upa_files",
  "arguments": {
    "format": "summary",
    "options": {
      "population": {
        "count": 3
      }
    }
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/upa-file-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"format":"summary","options":{"population":{"count":3}}}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/upa-file-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "format": "summary",
    "options": {
      "population": {
        "count": 3
      }
    }
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/upa-file-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"format":"summary","options":{"population":{"count":3}}},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/upa-file-generator · Page: /tools/upa-file-generator

Lorem Ipsum Generatorpagelorem-ipsum-generatorgenerate_lorem_ipsum1 credit a call

Generate classic lorem ipsum placeholder text as paragraphs, sentences, words or a list, optionally wrapped in HTML. Deterministic: the same options give the same text.

What it takes

count?
number
How many paragraphs, sentences, words or list items. Defaults to 3. Max 20 paragraphs, 50 sentences, 500 words or 30 list items.
e.g. 2
type?
string
What to count: "paragraphs" (default), "sentences", "words" or "list".
e.g. sentences
startWithLorem?
boolean
Start with "Lorem ipsum dolor sit amet". Defaults to true.
e.g. true
html?
boolean
Wrap output in HTML: <p> per paragraph or a <ul> list. Defaults to false.
e.g. false
seed?
number
Any whole number. The same seed gives the same text. Defaults to 1.
e.g. 1

What comes back

{
  "ok": true,
  "data": {
    "text": "Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet consectetur adipiscing elit.",
    "type": "sentences",
    "count": 2,
    "words": 26,
    "characters": 172,
    "paragraphs": 1
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_lorem_ipsum (Lorem Ipsum) with count: 2, type: sentences, startWithLorem: true, html: false, seed: 1.

The assistant then makes this tool call:

{
  "name": "generate_lorem_ipsum",
  "arguments": {
    "count": 2,
    "type": "sentences",
    "startWithLorem": true,
    "html": false,
    "seed": 1
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/lorem-ipsum-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count":2,"type":"sentences","startWithLorem":true,"html":false,"seed":1}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/lorem-ipsum-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "count": 2,
    "type": "sentences",
    "startWithLorem": true,
    "html": false,
    "seed": 1
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/lorem-ipsum-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"count":2,"type":"sentences","startWithLorem":true,"html":false,"seed":1},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/lorem-ipsum-generator · Page: /tools/lorem-ipsum-generator

Random Number Generatorpagerandom-number-generatorrandom_numbers1 credit a call

Draw random whole numbers between a minimum and maximum, inclusive, using cryptographic randomness. Ask for several at once, with or without repeats, for dice, lottery draws or samples.

What it takes

min?
number
Lowest possible number, inclusive. Defaults to 1.
e.g. 1
max?
number
Highest possible number, inclusive. Defaults to 100.
e.g. 6
count?
number
How many numbers you want, 1 to 1000. Defaults to 1.
e.g. 3
allowDuplicates?
boolean
Whether the same number may appear twice. Defaults to true.
e.g. true

What comes back

{
  "ok": true,
  "data": {
    "numbers": [
      4,
      1,
      6
    ],
    "min": 1,
    "max": 6,
    "count": 3,
    "unique": true
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool random_numbers (Random Number) with min: 1, max: 6, count: 3, allowDuplicates: true.

The assistant then makes this tool call:

{
  "name": "random_numbers",
  "arguments": {
    "min": 1,
    "max": 6,
    "count": 3,
    "allowDuplicates": true
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/random-number-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"min":1,"max":6,"count":3,"allowDuplicates":true}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/random-number-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "min": 1,
    "max": 6,
    "count": 3,
    "allowDuplicates": true
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/random-number-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"min":1,"max":6,"count":3,"allowDuplicates":true},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/random-number-generator · Page: /tools/random-number-generator

Test Document Number Generatorpagetest-documentnummer-generatorgenerate_test_document_number1 credit a call

Generate random Dutch test document numbers in the structural format of an ID card (4 letters + 5 digits), passport (2 letters + 7 digits) or driving licence (10 digits). Format only, no check digit, tied to no real document, for test environments.

What it takes

type?
string
Document type: "idkaart" (default) for an ID card, "paspoort" for a passport, "rijbewijs" for a driving licence.
e.g. idkaart
count?
number
How many numbers to generate, 1 to 50. Defaults to 5.
e.g. 5

What comes back

{
  "ok": true,
  "data": {
    "type": "idkaart",
    "label": "ID Card (Identiteitskaart)",
    "format": "4 letters + 5 digits (e.g. SPFC12345)",
    "count": 5,
    "numbers": [
      "SPFC12345"
    ],
    "note": "Test numbers only. They follow the structural format of Dutch documents but are random, belong to no real document and carry no check digit."
  }
}
Ask your AI assistant (MCP)

With the server connected, say something like:

Use the ToolForte tool generate_test_document_number (Test Document Number) with type: idkaart, count: 5.

The assistant then makes this tool call:

{
  "name": "generate_test_document_number",
  "arguments": {
    "type": "idkaart",
    "count": 5
  }
}
curl
curl -X POST https://toolforte.com/api/v1/tools/test-documentnummer-generator \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"idkaart","count":5}'
JavaScript
const response = await fetch("https://toolforte.com/api/v1/tools/test-documentnummer-generator", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "type": "idkaart",
    "count": 5
  }),
});
const { ok, data, error } = await response.json();
Python
import requests

response = requests.post(
    "https://toolforte.com/api/v1/tools/test-documentnummer-generator",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"type":"idkaart","count":5},
)
result = response.json()  # {"ok": true, "data": {...}}

Describe it: GET https://toolforte.com/api/v1/tools/test-documentnummer-generator · Page: /tools/test-documentnummer-generator

Files, pages and memory

These produce a file or read a web page, so they run on ToolForte servers and hand back a download link. They are on the MCP server under the names below and, for most of them, at POST /api/v1/render/<name>. Prices and the full reference are on the API page and the MCP page.

Render and read

  • html_to_pdf HTML to PDF
  • url_to_pdf Web page to PDF
  • url_screenshot Web page screenshot
  • qr_code_png QR code image
  • pdf_merge Merge PDFs
  • pdf_split Split PDF
  • images_to_pdf Images to PDF
  • image_resize Resize image
  • image_convert Convert image
  • image_compress Compress image
  • read_page Read web page
  • strip_metadata Remove file metadata
  • pdf_to_docx PDF to Word
  • docx_to_pdf Word to PDF

Memory across sessions

  • memory_set Remember a value
  • memory_get Recall a value
  • memory_list List remembered keys
  • memory_delete Forget a value

Also at /api/v1/memory.

Your saved workflows

  • workflow_list List saved workflows
  • workflow_run Run a saved workflow
  • workflow_propose Propose a workflow for a goal

Also at POST /api/v1/workflows/{id}/run. A workflow is private to the account that made it; an assistant with your key sees only yours.

Connect the MCP server in one line

Paste the URL into any client with an MCP settings screen, or use the npm bridge for one that only takes a command. Per-client steps, with screenshots of where the field is, are on the MCP page.

https://toolforte.com/api/mcp

npx -y toolforte-mcp