// 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

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

From your own code

All 84 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 84 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

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

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

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

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

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

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

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

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