원클릭으로
fstarmcp
Use the F* MCP server for interactive, incremental typechecking of F* and Pulse code
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use the F* MCP server for interactive, incremental typechecking of F* and Pulse code
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Verify F* and Pulse code with fstar.exe and interpret errors
Extract verified F*/Pulse code to C via KaRaMeL (.krml intermediate representation)
Structure a new F*/Pulse verification project with Makefile and directory layout
Systematic workflows for debugging F*/Pulse verification failures
Debug F* queries sent to Z3, diagnosing proof instability and performance issues
Build F*, Pulse, and KaRaMeL from source (fstar2 branch) for use in a verification project
| name | fstarmcp |
| description | Use the F* MCP server for interactive, incremental typechecking of F* and Pulse code |
The F* MCP server (fstar-mcp) provides an HTTP API wrapping F*'s --ide protocol.
It enables incremental typechecking: create a session once, then re-typecheck modified
code without restarting F* or reloading dependencies. This dramatically speeds up iterative
proof development.
Source: FStarLang/fstar-mcp
See the sourcebuild skill for instructions on building fstar-mcp from source.
Register the server in .copilot/mcp-config.json at your project root:
{
"mcpServers": {
"fstar-mcp": {
"type": "http",
"url": "http://localhost:3001/"
}
}
}
Copilot CLI auto-connects when the server is running.
# Start on port 3001 (matches mcp-config.json)
FSTAR_MCP_PORT=3001 path/to/fstar-mcp &
# With debug logging
RUST_LOG=fstar_mcp=debug FSTAR_MCP_PORT=3001 path/to/fstar-mcp &
The server runs on http://127.0.0.1:3001. All API calls are JSON-RPC 2.0 POST
requests to /.
All requests use JSON-RPC 2.0 over HTTP POST:
curl -s -X POST http://localhost:3001/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{"jsonrpc": "2.0", "method": "tools/call", "id": 1, "params": {"name": "TOOL_NAME", "arguments": {...}}}'
Responses contain result.content[0].text with a JSON string that must be parsed again.
curl -s -X POST http://localhost:3001/ \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tools/call","id":1,"params":{"name":"create_session","arguments":{
"file_path": "/path/to/Module.fst",
"cwd": "/project/root",
"include_dirs": ["/path/to/lib", "/path/to/specs"],
"options": ["--cache_dir", "/path/to/obj", "--already_cached", "Prims FStar"]
}}}'
Parameters:
file_path (string, optional): Path to the F* file. Must exist on disk. If omitted, creates a temp file.fstar_exe (string, optional): Path to fstar.exe. Defaults to fstar.exe in PATH.cwd (string, optional): Working directory. Defaults to file's directory.include_dirs (string[], optional): Directories for --include.options (string[], optional): Extra F* CLI options.Returns: session_id, status ("ok"/"error"), diagnostics[], fragments[]
The initial create_session typechecks the file's current on-disk contents. The returned
session_id is used for all subsequent operations.
curl -s -X POST http://localhost:3001/ \
-d '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"typecheck_buffer","arguments":{
"session_id": "UUID",
"code": "module Foo\nlet x = 42",
"kind": "full"
}}}'
Parameters:
session_id (string, required): From create_session.code (string, required): Full module source code. Must start with matching module declaration.lax (boolean, optional): Shortcut for kind: "lax".kind (string, optional): "full" (default), "lax", "cache", "reload-deps", "verify-to-position", "lax-to-position".to_line / to_column (integer, optional): For position-based kinds.Returns: status, diagnostics[], fragments[]
Each fragment has start_line, end_line, start_column, end_column, and status ("ok"/"failed").
curl -s -X POST http://localhost:3001/ \
-d '{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"lookup_symbol","arguments":{
"session_id": "UUID",
"file_path": "/path/to/Module.fst",
"line": 10, "column": 5,
"symbol": "my_function"
}}}'
Returns: kind ("symbol"/"module"/"not_found"), name, type_info, defined_at.
| Tool | Description |
|---|---|
list_sessions | List all active sessions with their file paths |
restart_solver | Restart Z3 for a session (useful when solver gets stuck) |
get_proof_context | Get proof obligations from tactic-based proofs |
update_buffer | Add/update files in F*'s virtual file system (vfs-add) for dependency resolution |
close_session | Clean up a session |
To use fstar-mcp with your project, determine the correct include_dirs and
options from your project's Makefile or build system. Common patterns:
{
"file_path": "/project/src/Module.fst",
"cwd": "/project",
"include_dirs": ["src/spec", "src/impl", "obj"],
"options": [
"--cache_dir", "obj",
"--already_cached", "Prims FStar Pulse.Lib PulseCore"
]
}
{
"file_path": "/project/code/algo/Module.fst",
"cwd": "/project",
"include_dirs": [
"lib", "specs",
"code/algo", "code/utils",
"obj",
"../FStar/pulse/out/lib/pulse/lib",
"../karamel/krmllib"
],
"options": [
"--cache_dir", "obj",
"--already_cached", "Prims FStar PulseCore Pulse.Lib Pulse.Class Pulse.Main",
"--ext", "pulse:rvalues",
"--ext", "fly_deps",
"--ext", "optimize_let_vc"
]
}
If your project has a Makefile that drives F* verification, extract the flags:
# See what flags make passes to fstar.exe
make VERBOSE=1 verify-module 2>&1 | grep fstar.exe
# Common Makefile variables to look for:
# FSTAR_INCLUDES = --include src/spec --include src/impl
# FSTAR_OPTIONS = --cache_dir obj --already_cached "Prims FStar"
Map --include flags to include_dirs and the rest to options.
typecheck_buffer
repeatedly (fast, only re-checks changed fragments).module declaration in code must match the
file name from create_session (e.g., file Spec.Poly1305.fst → module Spec.Poly1305).#lang-pulse
directive in the file is handled automatically."lax": true for fast syntax/type checking without SMT verification.
Useful for validating structure before committing to full verification."kind": "verify-to-position" with to_line to verify
only up to a specific point — useful for large files where you're working on one function.file_path replaces the old one.restart_solver rather
than recreating the entire session (which would reload all dependencies).