Atlas / MCP servers / pascalorg / lingo

lingoCAUTION

mcp/pascalorg/lingo

Make forms easier, LLM tools safer. Natural-language quantities, units, dates & ranges parsed into canonical values — zero dependencies, two-way.

Verdict
CAUTION
Grade
B
Trust score
86 /100
Exposed tools
11 10r · 1w · 0d
Transport
—
License
MIT
Stars
20
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://github.com/user-attachments/assets/c2115174-db48-4e81-8c8b-b794b616c19e)

Make forms easier, LLM tools safer.

npm install @pascal-app/lingo

Docs with live demos: [lingo.pascal.app](https://lingo.pascal.app) · npm: `@pascal-app/lingo` · coding agents start at lingo.pascal.app/llms.txt

People type fast and loose: 180cm, 5ft 11, 1.5 cups, 90 min, next friday, 1,5 kg, typos included. Models emit fluent, over-formatted strings: "5'11\"", "11⁄2 cups", "twenty-five kg", "3pm EST", "1,234 kg". Your database wants canonical values: one number in one unit, one ISO date. The library is the layer in between: natural-language quantities, units, dates, and ranges parsed into validated values, then humanized back. Zero dependencies; English by default with opt-in locale packs (Spanish, French, Portuguese, Chinese, Japanese, en-GB) for parsing, plus locale-aware number formatting via Intl.

For the web. Use one text field instead of a value box plus a unit dropdown:

  • Accepts how people actually type: 180cm, 5ft 11, 2 lb 3 oz,

an hour and a half, typos with did-you-mean (5 meterz), and fuzzy words (it's hot) where a field opts in.

  • Validation UX ships as data: fields are never yelled at mid-typing (2 f is

incomplete, not invalid), and every issue carries a stable code, a human message you can override, a span into the original input, and did-you-mean suggestions.

  • No silent guesses: ambiguous input (1,234: 1.234 or 1234?) returns a

deterministic best reading plus ranked alternatives and a warning; confirm strictness turns each assumption into a one-click confirmation.

  • Two-way and tested: whatever format()/humanize*() emits re-parses to the

same value. 1.9999 m formats as 6′7′′, never 5′12′′.

  • Headle
Read from source at commit 3f2738c4d2f0OBSERVED · 2026-10-12
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code
claude mcp add lingo -- npx -y @pascal-app/[email protected]
claude-desktop
{
  "mcpServers": {
    "lingo": {
      "command": "npx",
      "args": [
        "-y",
        "@pascal-app/[email protected]"
      ]
    }
  }
}
03

Exposed tools (11)

10 read · 1 write · 0 destructive.

ToolRiskDescription
Anthropicread
Evalsread
LangChainread
MCPread
OpenAIreadStrict function tools via
create_shipmentwriteCreate a shipment; natural-language values welcome.
failreadAlways fails.
log_shipmentreadRecord a shipment weight and note.
uses_paramsreadUses a params argument object.
weighreadWeigh a package.
weigh_envelopereadWeigh a package.
04

Trust audit

CAUTIONgrade B · trust 86/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (3 observation(s))
Network
declared (2 observation(s))
Shell
declared (2 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (22)

MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/lingo/scripts/bench.mjs:984
const url = `http://127.0.0.1:${address.port}/`
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
packages/lingo/src/ai/quantity-fields.ts:500
return '"1 M" or "250 μM"'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/site/next.config.ts:5
const lingoDist = '../../packages/lingo/dist'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/lingo/scripts/check-docs-sync.mjs:5
const ROOT = new URL('../../..', import.meta.url)
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/lingo/scripts/check-llms-index.mjs:2
import { assertLlmsIndexLinks, buildLlmsIndex } from '../../../apps/site/src/lib/llms-index.ts'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/lingo/scripts/gen-schemas.mjs:12
const OUT = new URL('../../../apps/site/public/schema/', import.meta.url)
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/lingo/tests/corpus/contract.test.mjs:3
import { lingo } from '../../src/index.ts'
LOWObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
apps/site/src/components/site/landing-sections.tsx:114
answer: `parseQuantity with kind: 'length' reads it as one compound value, and .to('m').value returns 1.8034. The same call handles 2 lb 3 oz, 1h30, unicode (1⁄2, μm, ′ ′′), number words, and typos wi
LOWObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
apps/site/src/lib/docs.md.ts:361
'Kinds include SI bases, pressure units (`psi`, `hPa`, `inH2O`, `kgf/cm2`), data rates (`Mbps`, `MB/s`), flow rates (`gpm`, `mL/min`), acceleration (`m/s2`, `gee`), torque (`N⋅m`, `lb-ft`), electrical
LOWObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
packages/lingo/src/ai/ai.test.ts:215
const field = quantityField({ kind: 'concentration', unit: 'μM' })
LOWObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
packages/lingo/src/ai/ai.test.ts:217
expect(String(input.description)).toContain('"1 M" or "250 μM"')
LOWObfuscation / stealth · obf.rtl_override · CWE-506, CWE-94
packages/lingo/src/parse/hostile.test.ts:31
'5 kg', // RTL override
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/lingo/src/date/range.test.ts:223
const input = '3 days starting tomorrow'
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/lingo/src/date/range.test.ts:236
const input = '3 days starting tomorrow'
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/lingo/src/date/range.test.ts:248
const input = '3 days starting 2026-03-01'
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/lingo/src/parse/hostile.test.ts:12
'',
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/lingo/src/parse/hostile.test.ts:30
'5 kg', // zero-width space inside
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
apps/site/package.json
@base-ui/react, @tanstack/react-table, @vercel/analytics, class-variance-authority, clsx, geist, katex, lucide-react
Why it matters. 24 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
lefthook, turbo
Why it matters. 2 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
packages/lingo/package.json
@standard-schema/spec, @types/react, @types/react-dom, esbuild, jsdom, react-dom, tsup, typescript
Why it matters. 9 dependency range(s) float
Fix. pin exact versions or ship a lockfile
INFOInventory / provenance · inv.oversize · CWE-1104
assets/lingo-intro.mp4
assets/lingo-intro.mp4
Why it matters. 5223973 bytes not read
INFOPrompt injection · prompt.conditional_escalation · CWE-94, CWE-1427
wiki/decisions.md:629
When the input contains a `\d{4}-\d{2}` run the pass demands a *spaced* dash

Gates applied: no_behavioural_pass.

Audited 2026-10-12 · audit v0.4.1 · source sha 3f2738c4d2f0full audit observations/trust-audit/mcp-server/pascalorg__lingo.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-123f2738c4d2f0CAUTIONB86first audit
06

Questions

What is the @pascal-app/lingo MCP server?

Make forms easier, LLM tools safer. Natural-language quantities, units, dates & ranges parsed into canonical values — zero dependencies, two-way.

What tools does @pascal-app/lingo expose?

11 in total: 10 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is @pascal-app/lingo safe to connect to an agent?

With care. The audit graded it B (86/100) and found 22 things worth knowing before you trust this server, listed below with the exact line each was found on.

What credentials does @pascal-app/lingo need?

No credential environment variables were found in its source, so it appears to need none.

How current is this page?

The grade is for one exact copy of the source (3f2738c4d2f0), read on 2026-10-12. The repository is watched and re-audited when it changes.

Advertisement