mcpField
F
forthling

forthling

本地服务
deschaker.github.io开发工具04 天前更新

关于 forthling

forthling 是在沙箱中运行 Forth 代码的 MCP 服务,面向 AI Agent 和其他 MCP 客户端。它会在多次调用间保留定义和栈,并返回文本及结构化结果,包括错误、跟踪信息和栈数据。

主要功能

  1. 01在持久会话中执行 Forth
  2. 02检查数据栈和浮点栈
  3. 03列出会话词并查询帮助
  4. 04加载并保留内存中的文件
  5. 05返回结构化错误、跟踪和测试结果
  6. 06限制每次调用的时间和资源

适用场景

  1. 01通过 Agent 运行并检查 Forth 代码片段
  2. 02跨调用复用 Forth 定义
  3. 03根据跟踪信息和源位置诊断栈错误

MCP 相关

通过 stdio 向 MCP 客户端提供 Forth 执行和会话检查工具。每个客户端会话均在沙箱中运行;可选 HTTP 访问仅限明确允许的主机。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
cargoforthling-mcp0.2.5
mcpbforthling.mcpb

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

forthling-mcp

一个 MCP 服务,让 AI Agent(Claude Code、 Claude Desktop 和其他 MCP 客户端)在 forthling 中运行 Forth,且始终处于沙盒中。Agent 保留一个会话:它定义的单词和栈会在多次调用之间保持不变。

安装

无需 Rust,作为 MCP bundle 安装:从 最新版本下载 forthling.mcpb,然后在 Claude Desktop(或其他可安装 .mcpb 文件的客户端)中打开。该 bundle 包含适用于 Windows(x64)、macOS(Apple Silicon 和 Intel)以及 Linux(x64)的 服务。

从 crates.io 安装,需要 Rust 1.85 或更高版本:

cargo install forthling-mcp

它会同时构建 SQLite,因此需要 C 编译器(Windows 上使用 Visual Studio 的 C 编译器;Rust 在 Windows 上也会用到它);cargo install forthling-mcp --no-default-features 则不会包含 SQLite。从仓库克隆版本安装:cargo install --path mcp,或 cargo build --release --manifest-path mcp/Cargo.toml,生成的程序位于 mcp/target/release/forthling-mcp。在 Claude Code 中:

claude mcp add forthling -- forthling-mcp

其他客户端也以相同方式启动它:通过 stdio 执行命令 forthling-mcp。

客户端连接时,服务会在指令中向模型介绍基础知识:容易让模型出错的惯用写法、用局部变量而非 ROT、 PICK 和 ROLL、JSON 单词以及各种限制。llms.txt 为预先阅读该文件的模型提供了更详细的相同内容;测试会确保两处的限制保持一致。

工具

工具参数
forth_evalcode, data, files, trace运行 Forth 代码;返回输出、数据栈和浮点栈,以及错误(如果有)
forth_stack显示栈,不运行任何内容
forth_words显示此会话中定义的词,最新定义的排在最前
forth_helpword显示词的栈效果、功能、示例及所属词表;对于未定义的名称,显示相近名称。会话中的词会在名称后显示 ( ) 注释
forth_reset开启新会话:所有定义、栈值、数据和文件都会清除

代码行(包括 S" 中的字符串)最多为 1024 个字符。更大的输入(例如 JSON 文档)应放入 data:代码使用 DATA ( -- c-addr u ) 读取它,该词会返回一份存储在 ALLOCATE 分配的内存中的副本(记得用 FREE 释放)。数据会保留,供后续调用使用,直到某次调用发送其他数据;数据大小最多可与 Forth 内存相同:

{"name": "forth_eval", "arguments": {"code": "ALSO JSON DATA JSON-LENGTH .", "data": "[[59],[73,41]]"}}

每个会话都有自己的文件,这些文件保存在内存中,不会写入磁盘:INCLUDE、REQUIRE、FILE 词和块词都会使用这些文件,且文件会一直保留,直到调用 forth_reset。代码运行前,files 会以名称和文本组成的对象形式将文件放入会话,并替换同名文件;因此,Agent 可以提供一次库文件,然后使用 INCLUDE 引入,而代码写入的内容也可由后续调用读取。所有文件总大小最多为 4 MiB;超出上限的写入会以该词的 ior 失败,无法放入的 files 也会被拒绝。

{"name": "forth_eval", "arguments": {"code": "INCLUDE square.fs 7 SQUARE .", "files": {"square.fs": ": SQUARE DUP * ;"}}}

每个结果都是 REPL 所显示的文本:

2401  ok
stack: 1 2

结果也会以结构化 JSON 的形式返回(structuredContent,并带有 outputSchema): {"output": "2401 ", "stack": [1, 2], "fstack": [], "compiling": false, "error": null, "steps": …, "max_depth": …};steps 和 max_depth(仅适用于 forth_eval)分别表示此次调用执行的步数,以及数据栈达到的最大深度;系统运行的词也会计入步数(. 是用 Forth 编写的,因此也会计入)。

发生错误时,栈会清空,因此结果还会显示错误发生时栈中的内容、错误发生位置以及当时正在运行的词;模型可以据此一次性修正问题:

error -10: division by zero
at input, line 2, column 3: MAIN
in: MAIN > STEP > /
stack at the error: 5 1
stack: empty

JSON 中的形式为:"error": {"code": -10, "message": "division by zero", "stack": [5, 1], "fstack": [], "words": ["MAIN", "STEP", "/"], "source": "input", "line": 2, "column": 3, "token": "MAIN", …},并且 isError 为 true。像这里的 / 这样,在失败前已取走参数的词,其参数已被取走。若未定义的词位于搜索顺序之外的词表中,则会提供 hint;文本会在该词后附上提示:error -13: undefined word: JSON@ (it is in the word list JSON; ALSO JSON finds it)。

失控的程序可能在栈上留下十万个单元,或留下同样多的运行中词(无限递归)。此时结果会保留栈顶的 32 个单元和最内层的 32 个词;文本会显示 ... (n more),JSON 中则会在 stack_depth、fstack_depth 和 words_depth 中给出完整深度。若定义尚未结束(compiling 为 true),文本会说明这一点:compiled (a definition is still open; ; ends it)。

若代码运行了 T{ ... -> ... }T 测试(ALSO TESTING),结果还会包含此次调用的测试计数,文本开头会显示 tests: 1 passed, 1 failed。失败行(FAIL input:3 (sums): incorrect result: expected <1> 3, got <1> 2)会出现在输出中。 JSON 中的形式为:"tests": {"passed": 1, "failed": 1, "failures": [{"source": "input", "line": 3, "group": "sums", "expected": [3], "expected_depth": 1, "actual": [2], "actual_depth": 1, "stack": [], "expected_floats": [], "expected_floats_depth": 0, "actual_floats": [], "actual_floats_depth": 0}], "failures_dropped": 0}。最多保留前 32 个失败记录;每个列表最多保留栈顶的 32 个单元和浮点数(深度字段会显示实际数量)。通过 files 提供的文件会将其名称显示为 source。

Agent 遇到典型错误时会看到的内容

每个案例都通过 forth_eval(#47)运行;答案是文本的首几行。 代码从一个全新会话中运行。

错误代码答案
未定义的单词1 2 FOO .error -13: undefined word: FOO,列号,以及出错时的栈 1 2
单词位于不在搜索顺序中的单词表中S" :memory:" DB-OPENerror -13: undefined word: DB-OPEN (it is in the word list SQLITE; ALSO SQLITE finds it)
定义中的未定义单词: sq DUPP * ;error -13: undefined word: DUPP,以及它所在的列
栈下溢: add2 + ; 1 add2error -4: stack underflow,in: ADD2 > +,以及出错时的栈
消耗过多内容的单词: f ( n -- ) DROP ; ferror -4,in: F > DROP
定义外的 IF、DO、BEGIN1 IF 2 THENerror -14: interpreting a compile-only word: IF
未闭合的 IF: foo 1 IF 2 ;error -22: control structure mismatch,位于 ; 处
没有 DO 的 LOOP: f LOOP ;error -22: control structure mismatch
未闭合的定义: foo 1 2 +compiled (a definition is still open; ; ends it)
除以零1 0 /error -10: division by zero,in: /,出错时栈为空(/ 已取走参数)
地址无效12345678 @error -9: invalid memory address: 12345678
步数超限: spin BEGIN 1 DROP AGAIN ; spinerror -258: limit exceeded: steps,in: SPIN > DROP
输出超限: p BEGIN 65 EMIT AGAIN ; p输出达到上限前的内容,然后是 error -258: limit exceeded: output
栈无限增长: grow BEGIN 1 AGAIN ; growerror -3: stack overflow,栈顶 32 个单元以及 ... (n more)
无限递归: r RECURSE ; rerror -5: return stack overflow,最内层的 32 个单词
文件缺失S" nofile.fth" INCLUDEDerror -38: non-existent file: nofile.fth: no such file
EVALUATE 内部出错S" 1 2 FOO" EVALUATEat evaluate, line 1, column 5: FOO,栈为 1 2
行超过 1024 个字符S" xxxx…" TYPEerror -18: parsed string overflow: input line too long
ABORT": chk 0= ABORT" zero" ; 0 chkerror -2: aborted: zero
CATCH: t 1 0 / ; : u ['] t CATCH . ; u输出 -10,没有错误结果

以下情况不会报错,因此也不会有消息:未闭合的 S" 或 ( 会取走该行剩余内容(符合标准);: f >R ; 会让返回栈失去平衡,而 1 f 返回时没有单词;负数大小的 ALLOCATE 和重复两次的 FREE 会在栈上返回非零 ior(-59、-60),DB-EXEC 失败时也一样(-261);不存在的 JSON 路径会给出 0 0 0。这些情况符合标准或该单词的栈效应;Agent 必须读取栈。

设置 "trace": true 后,forth_eval 还会返回跟踪信息:每个运行过的单词、嵌套深度,以及它开始运行时的数据栈(最多显示栈顶 8 个单元);最多记录 1000 个单词,其余数量由 trace_dropped 统计。系统自身单词的内部执行过程不会显示。文本以跟踪信息开头,并采用 TRACE-ON 输出的缩进格式:

trace:
F <0>
  SQ <1> 3
    DUP <1> 3
    * <2> 3 3
  1+ <1> 9
. <1> 10
end of trace
10  ok
stack: empty

JSON 中还会包含 "trace": [{"word": "F", "depth": 0, "stack": [], "stack_depth": 0}, {"word": "SQ", "depth": 1, "stack": [3], "stack_depth": 1}, …], "trace_dropped": 0。调用失败时的跟踪信息会显示它如何到达错误。在代码本身中,ALSO DEBUG TRACE-ON … TRACE-OFF 会输出相同的行。

BREAK(也可用 ALSO DEBUG)会标记一个检查位置。它不会停止程序,因为没人能在一次调用过程中作答;相反,结果中会包含 breaks,记录程序在每个 BREAK 处的状态(最多 100 条,其余数量由 breaks_dropped 统计),字段与错误信息相同:stack、fstack、words、source、line、column 和 token。文本会以每个断点对应的一行开头:

break 1: in F > BREAK, at input, line 1, column 3: stack <2> 7 9

ALSO TUTORIAL 提供教程:共 20 节 Forth 课程,十节适合初学者,十节进阶课程,Agent 可以引导用户逐步学习(LESSONS、n LESSON、CHECK 用于检查答案、HINT、NEXT)。

JSON 词已安装(ALSO JSON);用于内存中数据库的 SQLite 词(ALSO SQLITE,仅支持 :memory:,SQL 会在时间耗尽时停止,且数据库不能大于 Forth 内存)、正则表达式词(ALSO REGEX,以线性时间进行匹配),以及向量、矩阵、线性代数和特殊函数词(ALSO SCIENCE)也已安装;如果不启用 Cargo 功能 sqlite、regex 和 science(--no-default-features),服务将不会编译这些功能。

HTTP 词(ALSO HTTP,参见 http/README.md)是第三项功能 http,默认关闭,因为它会访问网络。使用该功能构建服务(cargo install forthling-mcp --features http),并为 Forth 代码可能发送请求的主机启动服务,每个主机指定一次:forthling-mcp --allow-host api.example.com(*.example.com 和 * 也可用)。如果没有 --allow-host,网络访问将保持关闭,模型也不会获知这些词。它是唯一能打开沙箱外部访问的选项,且仅限于你指定的主机;Forth 词无法添加主机。

沙箱

每个会话都在 forthling 的沙箱中运行:文件仅存在于内存中,每次调用最多执行 1000 万步、耗时 5 秒,并输出 1 MiB;会话定义等内容总计最多 4 MiB。以下选项可以更改这些限制,但每项都不能超过程序设定的上限:

  -m, --memory SIZE      Forth memory (default 1M) [64M]
      --max-steps N      steps per call (default 10000000) [1000000000]
      --max-time T       time per call, such as 5s or 500ms (default 5s) [60s]
      --max-output SIZE  output per call (default 1M) [16M]
      --max-space SIZE   definitions and the like in all (default 4M) [64M]
      --allow-host HOST  a host that Forth code may send HTTP requests to (repeat)

没有关闭沙箱或允许访问文件的选项,因此更改服务的启动方式也不会开放文件访问。只有 --allow-host 可以开放网络访问,且仅限于它指定的主机(见上文)。

如何强制执行。 沙箱由服务强制执行,而非依赖模型获知或承诺遵守:工具只接受 Forth 代码(其他参数都会被拒绝),且没有 Forth 词能更改限制或权限。用户要求 AI 绕过沙箱,无法通过 forthling 实现。不过,如果 Agent 还拥有其他工具,例如 shell 或文件编辑工具,就可以绕过沙箱:更改 MCP 配置,或启动另一个程序。forthling 无法防范这种情况;请改用 Agent 的权限设置。在 Claude Code 中:拒绝或限制 shell,拒绝编辑 MCP 配置(.mcp.json、~/.claude.json),并通过托管设置仅允许你需要的 MCP 服务。为进一步防范 forthling 中的错误,可在容器中运行服务,或使用权限较少的用户运行服务。

测试

cargo test --manifest-path mcp/Cargo.toml
cargo test --manifest-path mcp/Cargo.toml --no-default-features
cargo test --manifest-path mcp/Cargo.toml --all-features

链接

  • forthling 的源代码及其他内容:https://github.com/DeSchaker/forthling
  • MCP Registry 将此服务登记为 io.github.DeSchaker/forthling(下面这一行可让它验证此 crate 属于我们)。
  • mcp-name: io.github.DeSchaker/forthling

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。