Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions run/docs/arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Type hints (`str`, `int`, `float`/`number`, `bool`, `object`/`obj`/`dict`) are u
- `bool`/`boolean` — parsed as a boolean (truthy: `true`, `1`, `yes`)
- `object`/`obj`/`dict` — parsed from a JSON string into a native object/dict

Signature type hints take precedence over any type keyword in a matching `@arg` attribute. The `@arg` type is only consulted when the function has no typed signature (e.g., legacy shell functions using `$1`, `$2`). See [`@arg` type vs. signature type hint](./attributes-and-interpreters.md#descriptions-and-args) for the full precedence rules.

## Quoting and spaces
Arguments are passed as plain CLI tokens. Quote values containing spaces or shell-sensitive characters:
```bash
Expand Down
9 changes: 8 additions & 1 deletion run/docs/attributes-and-interpreters.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Attributes live in comments (`# @key value`) and adjust how a function is expose

## Descriptions and args
- `@desc` — one-line summary shown in listings and MCP tool schemas.
- `@arg <name> [type] <description>` — add human-readable parameter docs. Names should match the signature. Optional type keyword (`string`, `integer`, `float`/`number`, `boolean`, `object`/`dict`) sets the JSON schema type for MCP.
- `@arg <name> [type] <description>` — add human-readable parameter docs. Names should match the signature. Optional type keyword (`string`, `integer`, `float`/`number`, `boolean`, `object`/`dict`) sets the JSON schema type for MCP when the function has no typed signature.
- `@instructions <text>` — top-level MCP guidance line appended to server `initialize.instructions`. This is single-line and repeatable; lines are aggregated in merged/source order.

```bash
Expand All @@ -14,6 +14,13 @@ Attributes live in comments (`# @key value`) and adjust how a function is expose
deploy(env: str, version = "latest") { ... }
```

> **`@arg` type vs. signature type hint:** The type keyword in `@arg` and the type annotation in the function signature serve related but distinct purposes:
>
> - **Signature type hint** (e.g., `env: str`) is the primary driver. When a typed signature is present, it controls the MCP JSON schema type *and*, in polyglot functions (Python, Node.js, Ruby), drives automatic runtime value conversion.
> - **`@arg` type keyword** (e.g., `# @arg env string …`) is a fallback used when the function has no typed signature — for example, shell functions that rely on positional variables (`$1`, `$2`). In that case, the `@arg` type sets the MCP schema type.
> - **`@arg` description** is always used regardless of whether a signature type hint is present.
> - The two do not need to agree, but keeping them consistent is recommended. If they conflict, the signature type hint wins for MCP schema generation.

Top-level MCP instruction example:

```bash
Expand Down
6 changes: 3 additions & 3 deletions run/tests/mcp_server_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ greet(name: str) echo "Hello, $name!"
writeln!(stdin, "{}", serde_json::to_string(&call_request).unwrap()).unwrap();
stdin.flush().unwrap();

std::thread::sleep(Duration::from_millis(1000));
std::thread::sleep(Duration::from_secs(1));

child.kill().expect("Failed to kill process");
let output = child.wait_with_output().unwrap();
Expand Down Expand Up @@ -604,7 +604,7 @@ fail() {
writeln!(stdin, "{}", serde_json::to_string(&call_request).unwrap()).unwrap();
stdin.flush().unwrap();

std::thread::sleep(Duration::from_millis(1000));
std::thread::sleep(Duration::from_secs(1));

child.kill().expect("Failed to kill process");
let output = child.wait_with_output().unwrap();
Expand Down Expand Up @@ -994,7 +994,7 @@ check() {

// Allow extra time because the MCP server spawns a subprocess to run the function.
// Existing tests use 500 ms for requests that don't fork; we need more here.
std::thread::sleep(std::time::Duration::from_millis(2000));
std::thread::sleep(std::time::Duration::from_secs(2));

child.kill().expect("Failed to kill process");
let output = child.wait_with_output().unwrap();
Expand Down
Loading