Askew
This server lets an AI agent control and communicate with a user's Apple device (iPhone/iPad/Mac) through Askew.
Run Shortcuts on the phone via
askew_run, even while locked, and poll async results withaskew_get_run.Discover available routes/devices/connection mode with
askew_list_routes.Send notifications to the phone (agent → person, one-way) with
askew_notify.Read phone-sent items (triggers, share-sheet data, payments, etc.) with
askew_inbox_list,askew_inbox_wait, and acknowledge them withaskew_inbox_ack.Read and write encrypted shared variables with
askew_variables_get/askew_variables_set.All payloads are end-to-end encrypted; the relay only sees metadata.
Allows agents to use Apple devices (iPhone, iPad, Mac) by running Shortcuts and receiving notifications or results.
Uses iCloud to sync Shortcut recipes across the user's Apple devices.
Runs Shortcuts on iOS devices, including a locked iPhone, and returns their output.
Runs Apple Shortcuts on the phone and retrieves results, such as adding calendar events, reminders, or notes.
askew-mcp
Let any AI agent use your iPhone, iPad or Mac. askew-mcp is the local connector for Askew: an MCP server (stdio) that lets Claude Code, Claude Desktop, Cursor, Codex or any MCP client run Shortcuts on your Apple devices, send you notifications, and read what your phone sends back. The iPhone can stay locked. Recipes sync across devices via iCloud; iPad and Mac support is in testing. Inputs, results and inbox items are sealed on this computer with your key, so the relay never sees plaintext.
iPhone (iOS 27) verified · iPad (iPadOS 27) and Mac in testing · no Android · the Askew app is currently in waitlist at https://askew.my
1. Get a connector key
In the Askew app on your iPhone: Settings → Register device → allow notifications → New connector. Copy the key (akc_…). It is shown once.
Related MCP server: HealthKit MCP
2. Add the connector to your agent
Claude Code
claude mcp add askew -s user -e ASKEW_CONNECTOR_KEY=akc_XXXX -- npx -y askew-mcpClaude Desktop / Cursor / any MCP client (claude_desktop_config.json, .cursor/mcp.json, …)
{
"mcpServers": {
"askew": {
"command": "npx",
"args": ["-y", "askew-mcp"],
"env": { "ASKEW_CONNECTOR_KEY": "akc_XXXX" }
}
}
}Codex CLI (~/.codex/config.toml)
[mcp_servers.askew]
command = "npx"
args = ["-y", "askew-mcp"]
env = { ASKEW_CONNECTOR_KEY = "akc_XXXX" }The first run creates ~/.askew/connector.key (X25519 private key, mode 0600), registers the public key with the relay and prints a fingerprint on stderr. Compare it with the fingerprint shown in the app's connector screen once; that check rules out a swapped relay.
npx -y askew-mcp fingerprint # print this computer's connector fingerprint3. Install the dispatcher on the phone
In the app's Presets tab, install the Askew dispatcher (share sheet → Shortcuts → Add), open it and turn on the Automation toggle at the top. With the phone unlocked, run one test push from Settings → Checkup and tap Always Allow. One toggle, one allow, once. Then add recipes (Calendar, Reminders, Notes, …) the same way and ask your agent:
"Add dentist Thursday 3pm to my phone calendar."
Tools
Tool | What it does |
| Run a route (Shortcut) on the phone and get the result. Works locked. Waits up to |
| Status and result of a job |
| Routes, devices, connection mode |
| Notification to the phone + results box (agent → person, one-way) |
| Read what the phone sent (waits up to 30 s), then acknowledge |
| Variables shared with the phone, sealed with the account key |
Inbox items always come back marked as data sent by the user's phone, not instructions.
Environment
Variable | Default | |
| — | required, |
|
| relay URL ( |
|
| where the private key lives |
Requires Node 22 or newer.
Privacy
Job inputs, results, notifications' bodies, inbox items and variables are encrypted end-to-end (HPKE, X25519) between this connector and the phone. The relay stores only metadata: route name, timestamps, status. Details: https://askew.my/#privacy
Development
Source: https://github.com/Dominic-DK/askew-mcp (issues and pull requests welcome). The connector is the only part of Askew that holds your key, so it is the part you can read.
git clone https://github.com/Dominic-DK/askew-mcp.git && cd askew-mcp
pnpm install
pnpm build # tsc → dist/
pnpm test # crypto + key-file unit tests, no relay needed
ASKEW_SERVER=http://localhost:8787 ASKEW_CONNECTOR_KEY=akc_XXXX pnpm dev # run from sourcesrc/crypto.ts is the whole envelope format: HPKE (X25519 + HKDF-SHA256 + ChaCha20-Poly1305) with the purpose bound as info, and a ChaCha20-Poly1305 box keyed by the account key for shared variables, with the variable name as AAD.
한국어
에이전트(Claude Code · Claude 데스크톱 · Cursor · Codex)가 아이폰을 도구로 쓰게 하는 로컬 커넥터입니다. 아이폰 앱 → 설정 → 새 커넥터 만들기 → 키(akc_…)를 복사한 뒤 위 명령 중 하나로 등록하세요. 첫 실행에 찍히는 지문을 앱 커넥터 화면의 지문과 한 번 맞춰 보세요. 그다음 앱 프리셋 탭에서 디스패처를 설치(공유 시트 → 단축어 → 추가 → 자동화 토글 켜기 → 잠금 해제 상태 테스트 푸시 1회 "항상 허용")하면 잠긴 폰에서도 단축어가 돕니다. iPhone(iOS 27) 확인됨, iPad·Mac은 테스트 중. Android 없음.
Available Tools
9 toolsaskew_get_runA
Return the current status and, when finished, the decrypted result of a job started with askew_run. Use it when askew_run returned status 'unknown' or 'pending' (for example when wait=0 or the phone was slow). Set wait to long-poll up to 60 seconds. Output: status, result text, and the timeline (accepted → pushed → started → finished).
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | Seconds to long-poll for a terminal status, 0–60 (default 0 = return the current status immediately). | |
| jobId | Yes | Job id returned by askew_run (e.g. 'job_…'). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the tool's asynchronous behavior (status first, result when finished), the decrypted nature of the result, the long-poll capability up to 60 seconds, and the expected output components (status, result text, timeline). This is rich behavioral context, though it omits error handling, auth, and rate-limit details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose, usage condition, and output summary. The most relevant information is front-loaded, with no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description compensates by spelling out the return content (status, result text, timeline) and the state transitions. It also references the companion tool askew_run and the condition that triggers this call. It stops short of covering edge cases like invalid job ids or terminal failure states, but for this tool's moderate complexity it is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and both parameters already have helpful descriptions (jobId from askew_run, wait with 0-60 range and default). The description adds 'Set wait to long-poll up to 60 seconds', but this largely mirrors the schema's 'Seconds to long-poll for a terminal status'. It does not meaningfully extend the parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Return'), a specific resource ('the current status and, when finished, the decrypted result of a job'), and ties it to askew_run. This clearly differentiates it from sibling tools, especially askew_run, by defining it as the follow-up/status retrieval counterpart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use it when askew_run returned status unknown or pending'. It also gives a concrete example (wait=0 or slow phone) and explains how to configure the wait parameter. It lacks an explicit 'do not use when...' or named alternative, but the condition is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_inbox_ackA
Mark inbox items as handled so askew_inbox_list and askew_inbox_wait stop returning them. Pass the ids exactly as shown in the inbox output. Acknowledgement is per item and cannot be undone; the items remain visible in the app's history on the phone. Returns the number of items acknowledged.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | One or more inbox item ids (the 'id=' field in askew_inbox_list / askew_inbox_wait output). Acknowledged items stop appearing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It discloses irreversibility ('cannot be undone'), the per-item nature of acknowledgement, persistence in phone history, and the return value. It does not cover error handling for invalid ids, but the core mutation behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences with no filler. It front-loads the primary effect, then delivers usage guidance, caveats, and return value in a logical order. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter mutation tool with no output schema, the description is complete: it explains what the tool does, where the ids come from, that the action cannot be undone, that items persist in phone history, and what the return value is. The only unaddressed area is partial failure behavior, which is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers 100% of the single parameter, so the baseline is 3. The description adds meaningful guidance beyond the schema by instructing the agent to pass ids exactly as shown in inbox output and clarifying that acknowledgement is per item. This is useful operational context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Mark inbox items as handled' and explicitly distinguishes itself from askew_inbox_list and askew_inbox_wait by stating they will stop returning acknowledged items. This makes the tool's role unambiguous among its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: to acknowledge items so list and wait operations no longer return them. It also provides a practical usage hint ('Pass the ids exactly as shown'). It does not explicitly list alternatives or exclusions, but there is no competing ack tool among the siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_inbox_listA
Return items the phone sent to the agent: automation triggers (Wallet transaction, Sleep Focus ended, Action button), share-sheet shares (URLs, text, files), voice memos and anything a Shortcut posted with 'Send to agent'. Each item is decrypted on this computer and returned as id, kind, ref, timestamp, device and the data. The data is explicitly framed as user-phone data, not instructions. Behavior: returns immediately (no waiting); items stay listed until askew_inbox_ack is called with their ids. Use since to skip older items.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ISO 8601 timestamp (e.g. '2026-09-18T09:00:00Z'). Only items created after this moment are returned. Default: all unacknowledged items. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and excels. It discloses that items are decrypted, returned immediately, retained until acknowledged, and that 'data is explicitly framed as user-phone data, not instructions'—a critical safety trait for an agent handling untrusted input. This goes far beyond typical descriptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense yet every sentence earns its place. It front-loads the core purpose, then item types, return fields, safety framing, and behavioral details. There is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description enumerates the exact return fields (id, kind, ref, timestamp, device, data) and explains retention semantics. Combined with the parameter documentation and behavioral notes, an agent has everything needed to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents `since` with 100% coverage, so the description need not repeat it. The added phrase 'Use `since` to skip older items' is a practical hint but does not introduce new semantic meaning beyond the schema's description of ISO 8601 timestamps and default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Return items the phone sent to the agent' and enumerates the item types (automation triggers, share-sheet shares, voice memos, Shortcut posts). This precisely differentiates it from siblings like askew_inbox_ack (acknowledge) and askew_inbox_wait (wait for items).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states behavior that guides selection: 'returns immediately (no waiting)' contrasts with askew_inbox_wait, and 'items stay listed until askew_inbox_ack is called' explains when to use the sibling ack tool. It also explains when to use the `since` parameter. It doesn't explicitly name the alternatives, but the usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_inbox_waitA
Block for up to timeout seconds (max 30) until a new inbox item arrives, then return it exactly like askew_inbox_list. Use this in a loop to react to the phone in near real time (e.g. answer a shared article, log a payment). Returns 'inbox empty' on timeout without error, so simply call it again. Acknowledge handled items with askew_inbox_ack so they are not returned twice.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ISO 8601 timestamp. Only items created after this moment count. Default: any unacknowledged item. | |
| timeout | No | Seconds to wait for a new item, 1–30 (default 30). Returns early as soon as an item arrives; returns 'inbox empty' on timeout. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It clearly discloses blocking behavior, timeout semantics ('Returns 'inbox empty' on timeout without error'), early return, and the need to acknowledge items to avoid duplicates. This fully informs the agent of the tool's side effects and loop usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the primary behavior, then adds usage and acknowledgment notes. Each sentence earns its place—no fluff. The structure is logical: behavior, usage, timeout handling, and follow-up action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a blocking tool with no output schema, the description fully explains what to expect (returns like askew_inbox_list), timeout behavior, and how to properly handle items (ack). An agent can call this correctly without additional information. The reference to askew_inbox_list is acceptable since it's a sibling tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add parameter-specific details beyond the schema (e.g., it repeats the timeout range but doesn't explain 'since' beyond what's in the schema). It does add behavioral context about looping and acknowledgment, but that's not parameter semantics. Thus a 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (block/wait) and resource (inbox item), and explicitly distinguishes from askew_inbox_list by noting it returns the item exactly like that tool. It also names askew_inbox_ack for acknowledgment, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: 'Use this in a loop to react to the phone in near real time' and instructs to call it again on timeout. It also mentions the ack tool for handling items. However, it doesn't explicitly contrast with askew_inbox_list (e.g., 'use list instead if you don't want to block'), so the guidance is strong but not fully explicit about when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_list_routesA
List everything an agent can act on in this account: the connector's name and mode, each registered device with its key fingerprint and last-seen time, and every route (an installed Shortcut) with its routeId, name, target Shortcut name, execution mode, enabled flag, last success time, inputExample, input hint and output hint. Call this before askew_run to learn the exact input keys a route expects. Takes no arguments. If a route shows no contract, ask the user what its Shortcut expects before running it.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses what the tool returns in detail, states that it takes no arguments, and positions it as an inspection step before execution, implying no side effects. It stops short of explicitly stating that it does not modify state or describing failure behavior, but for a list operation these are minor gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then provides a dense but purposeful enumeration of returned fields and usage guidance. Every sentence adds value, with no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description compensates by enumerating every category of returned data and explaining the field-level semantics, including inputExample, input hint, and output hint. It also tells the agent what to do when a route lacks a contract, making it complete for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is empty and schema description coverage is 100%, so the baseline is 4. The description reinforces this by explicitly saying 'Takes no arguments,' leaving no ambiguity about invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and a clear resource ('everything an agent can act on in this account'), then enumerates the exact contents: connector details, devices, and routes. It also distinguishes itself from the sibling askew_run by framing this as the discovery step before execution.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs the agent to call this before askew_run to learn the exact input keys a route expects. It also provides a clear conditional behavior: if a route shows no contract, ask the user what the Shortcut expects before running it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_notifyA
Send a lock-screen notification to the user's phone (mirrored to Apple Watch) and keep the full text in the app's results box. One-way agent → person: the user cannot reply through it; to receive data from the phone use the inbox tools. title is sent in clear text, body and content are end-to-end encrypted. Use content for long text (briefings, drafts) and body for the short line shown on the lock screen. Returns the delivery ids. Use ref to group related notifications.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | Optional reference (≤200 chars) to group deliveries in the results box, e.g. 'morning-briefing' or an inbox item id you are answering. | |
| body | No | Short notification body shown on the lock screen and Apple Watch. End-to-end encrypted; the relay only carries an encrypted hint. | |
| title | Yes | Notification title, 1–200 chars. Sent to the phone in clear text, so keep sensitive details in body/content. | |
| content | No | Longer text kept in the app's results box (e.g. a full briefing or draft). End-to-end encrypted. Markdown is shown as plain text. | |
| deviceId | No | Send to one device only (id from askew_list_routes). Default: every registered device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden and succeeds: it reveals one-way delivery, Apple Watch mirroring, clear-text `title`, end-to-end encryption for `body` and `content`, and that delivery ids are returned. These are behavioral facts an agent needs beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences front-load the core action and then layer security, field guidance, return value, and grouping without filler. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, no annotations, and no output schema, the description is remarkably complete: it covers routing, encryption, one-way nature, return value, and `ref` grouping. The only omitted details, like auth or error behavior, are not essential for an agent to call this notify tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces role distinctions between `body` and `content` and warns about `title` being clear text, but these are already present in the schema's parameter descriptions—so the added semantic value is modest.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: sending a lock-screen notification to the user's phone and keeping full text in the app's results box. It clearly separates this send-oriented tool from the sibling inbox tools by framing it as one-way agent-to-person communication.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when-not to use this tool ('the user cannot reply through it') and names the alternative for the opposite direction ('to receive data from the phone use the inbox tools'). It also gives practical field-selection guidance: use `content` for long text and `body` for the short lock-screen line.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_runA
Run a Shortcut (a 'route') on the user's iPhone, iPad or Mac and return its result. Works while the phone is locked: the relay pushes a notification, one dispatcher automation runs the target Shortcut, and the result comes back end-to-end encrypted. Behavior: call askew_list_routes first; each route lists an inputExample and the input MUST use exactly those keys (dates 'YYYY-MM-DD HH:mm'), otherwise the call is rejected before anything runs. Waits up to wait seconds (default 45) and returns status (done | failed | unknown | pending), the decrypted result text and a timeline. If status is 'unknown' or 'pending', poll with askew_get_run using the returned jobId. Usage: one route per call; do not retry a failed job blindly — read the error text, fix the input, or ask the user. Use idempotencyKey when you must retry a network error.
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | Seconds to wait for the result, 0–60 (default 45). 0 returns immediately with status 'pending'; poll with askew_get_run. A locked phone usually answers within 1–3 seconds. | |
| input | Yes | Input for the Shortcut. MUST follow the route's inputExample from askew_list_routes: the same JSON keys, dates as 'YYYY-MM-DD HH:mm', send "" for keys you do not need. A JSON object for routes whose example is an object; a plain string only for routes whose example is a string. A mismatched input is rejected before anything runs on the phone. | |
| routeId | No | Route id from askew_list_routes (e.g. 'rt_…'). Give either routeId or routeName; routeId wins when both are present. | |
| routeName | No | Route name from askew_list_routes (e.g. 'calendar.add'). Case-sensitive. Use this when you know the name but not the id. | |
| idempotencyKey | No | Optional client-chosen key (≤200 chars). Re-sending the same key returns the existing job instead of running the Shortcut again; use it for retries. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and meets it impressively. It discloses locked-phone execution, end-to-end encryption, rejection of mismatched input before any run, wait/polling behavior, status values, and the meaning of idempotencyKey for retries.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence adds necessary operational detail, and it is well structured with purpose first, then behavior, then usage guidance. There is no filler or redundant repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex async execution tool with no annotations and no output schema, the description is remarkably complete: it explains how results arrive, what statuses to expect, how to poll, how to handle failures, and how to retry safely. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds meaning beyond the schema: input must use exactly the route's example keys with 'YYYY-MM-DD HH:mm' dates, empty strings for unused keys, routeId precedence over routeName, and the recommended use of idempotencyKey for network-error retries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Run a Shortcut (a 'route') on the user's iPhone, iPad or Mac and return its result." It clearly separates this from sibling tools by naming askew_list_routes as a prerequisite and askew_get_run for polling, so an agent can tell what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: call askew_list_routes first, match input to the route's inputExample, and poll with askew_get_run when status is 'unknown' or 'pending'. It also gives when-not-to-retry guidance: don't blindly retry a failed job, read the error and fix the input.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_variables_getA
Read a variable shared between the agent and the user's phone (for example a location, a plan or a preference a Shortcut stored). Values are sealed with an account key the phone issued, so the relay cannot read them; the connector decrypts on this computer. Returns the value text and when it was last updated. Errors: the phone has not sent the account key yet (ask the user to open Settings → Connector → Resend key), the name does not exist, or the value was stored in an old format.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Variable name as stored (case-sensitive), e.g. 'home', 'mood', 'today.plan'. Names are set by askew_variables_set or by the phone's Shortcuts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden and meets it: it explains the end-to-end encryption model (values sealed with an account key, relay cannot read them, connector decrypts locally), states exactly what is returned (value text and last-updated timestamp), and enumerates three error conditions with a concrete remediation for the most likely one. This goes well beyond what structured fields would provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences are front-loaded with the core action ('Read a variable...') before layering security context, return value, and error handling. Every sentence earns its place — no filler, and the error block is structured as an actionable list.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema and no annotations, the description covers everything needed to call it correctly: purpose, value semantics, security model, return contents, and failure modes. The only minor gap is remediation for the old-format error, which an agent can readily infer from the askew_variables_set sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with the name parameter already documented as case-sensitive, with examples and provenance, so the baseline is 3. The description adds value above baseline by explaining what kinds of content variables hold (location, plan, preference), reinforcing the semantics beyond the schema's formal constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Read') and resource ('a variable shared between the agent and the user's phone') with illustrative examples (location, plan, preference). The get/set naming plus the schema's explicit cross-reference to askew_variables_set clearly distinguishes it from its sibling setter, and it does not overlap with the other run/inbox/notify siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the purpose — it reads a shared variable — and the schema names askew_variables_set as the writer, but the description itself gives no explicit when-to-use versus when-not-to-use advice. Error remediation is provided for the missing-account-key case, but there is no guidance for the name-not-found or old-format errors, and no alternatives are excluded.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
askew_variables_setA
Write a variable shared between the agent and the user's phone. The value (a string or a JSON object) is encrypted with the account key before leaving this computer, and the phone's Shortcuts read it with the same key; the relay stores only ciphertext. Writing an existing name replaces the value; there is no versioning. Returns the name and update time. Errors: the account key has not arrived yet (ask the user to open Settings → Connector → Resend key). Use it for data a Shortcut should pick up later (e.g. 'today.plan'), not for large blobs.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Variable name (case-sensitive), e.g. 'home' or 'today.plan'. Writing an existing name replaces its value; the name is authenticated with the value, so it cannot be read back under another name. | |
| value | Yes | The value to store: a plain string, or a JSON object (stored as JSON text). Encrypted with the account key before it leaves this computer; the phone's Shortcuts read it with the same key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carres the full burden — and it delivers: encryption before leavg the computer, relay stores only ciphertext, overwrite-on-existing-name with no versioning, return values, and an actionable error case with user remediation steps. Exemplary beavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries distinct information: purpose, security model, overwrite beavior, return value, error handling, and usage limits. The purpose is front-loaded and nothing is redundant or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and no output schema, the description covers all decision-relevant aspects: what it writes, how it protects data, what happens on conflict, what it returns, how to handle the key-not-arrived error, and suitable payload sizes. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the schema already documents name (case-sensitive, overwrite beavior) and value (string or JSON object, encrypted). The description reinforces these facts but adds little parameter-specific meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb-resource statement — 'Write a variable shared between the agent and the user's phone' — so an agent knows exactly the operation and resource. The write operation is clearly distinct from sibling askew_variables_get and the run/inbox tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit context — 'Use it for data a Shortcut should pick up later (e.g. 'today.plan')' — and an exclusion ('not for large blobs'). It does't explicitly name askew_variables_get as the read counterprat, so the when-not-to-use guidance is slightly less direct than it could be.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
- Changed
askew_get_run2 fields changed- added
Input schema / properties / jobId / descriptionAdded value: +"Job id returned by askew_run (e.g. 'job_…')." - added
Input schema / properties / wait / descriptionAdded value: +"Seconds to long-poll for a terminal status, 0–60 (default 0 = return the current status immediately)."
- Changed
askew_inbox_ack1 field changed- added
Input schema / properties / ids / descriptionAdded value: +"One or more inbox item ids (the 'id=' field in askew_inbox_list / askew_inbox_wait output). Acknowledged items stop appearing."
- Changed
askew_inbox_list1 field changed- changed
Input schema / properties / since / descriptionPrevious value: -"ISO 시각 — 이 이후 항목만"New value: +"ISO 8601 timestamp (e.g. '2026-09-18T09:00:00Z'). Only items created after this moment are returned. Default: all unacknowledged items."
- Changed
askew_inbox_wait2 fields changed- added
Input schema / properties / since / descriptionAdded value: +"ISO 8601 timestamp. Only items created after this moment count. Default: any unacknowledged item." - added
Input schema / properties / timeout / descriptionAdded value: +"Seconds to wait for a new item, 1–30 (default 30). Returns early as soon as an item arrives; returns 'inbox empty' on timeout."
- Changed
askew_notify5 fields changed- added
Input schema / properties / body / descriptionAdded value: +"Short notification body shown on the lock screen and Apple Watch. End-to-end encrypted; the relay only carries an encrypted hint." - added
Input schema / properties / content / descriptionAdded value: +"Longer text kept in the app's results box (e.g. a full briefing or draft). End-to-end encrypted. Markdown is shown as plain text." - added
Input schema / properties / deviceId / descriptionAdded value: +"Send to one device only (id from askew_list_routes). Default: every registered device." - added
Input schema / properties / ref / descriptionAdded value: +"Optional reference (≤200 chars) to group deliveries in the results box, e.g. 'morning-briefing' or an inbox item id you are answering." - added
Input schema / properties / title / descriptionAdded value: +"Notification title, 1–200 chars. Sent to the phone in clear text, so keep sensitive details in body/content."
- Changed
askew_run5 fields changed- changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"같은 요청을 다시 보낼 때 같은 키를 쓰면 중복 실행되지 않음"New value: +"Optional client-chosen key (≤200 chars). Re-sending the same key returns the existing job instead of running the Shortcut again; use it for retries." - changed
Input schema / properties / input / descriptionPrevious value: -"Input for the Shortcut. MUST follow the route's inputExample from askew_list_routes (same JSON keys; dates as 'YYYY-MM-DD HH:mm'). A JSON object for routes whose example is an object; a plain string only for routes whose example is a string."New value: +"Input for the Shortcut. MUST follow the route's inputExample from askew_list_routes: the same JSON keys, dates as 'YYYY-MM-DD HH:mm', send \"\" for keys you do not need. A JSON object for routes whose example is an object; a plain string only for routes whose example is a string. A mismatched input is rejected before anything runs on the phone." - added
Input schema / properties / routeId / descriptionAdded value: +"Route id from askew_list_routes (e.g. 'rt_…'). Give either routeId or routeName; routeId wins when both are present." - added
Input schema / properties / routeName / descriptionAdded value: +"Route name from askew_list_routes (e.g. 'calendar.add'). Case-sensitive. Use this when you know the name but not the id." - changed
Input schema / properties / wait / descriptionPrevious value: -"결과를 기다릴 초(0이면 즉시 반환)"New value: +"Seconds to wait for the result, 0–60 (default 45). 0 returns immediately with status 'pending'; poll with askew_get_run. A locked phone usually answers within 1–3 seconds."
- Changed
askew_variables_get1 field changed- added
Input schema / properties / name / descriptionAdded value: +"Variable name as stored (case-sensitive), e.g. 'home', 'mood', 'today.plan'. Names are set by askew_variables_set or by the phone's Shortcuts."
- Changed
askew_variables_set2 fields changed- added
Input schema / properties / name / descriptionAdded value: +"Variable name (case-sensitive), e.g. 'home' or 'today.plan'. Writing an existing name replaces its value; the name is authenticated with the value, so it cannot be read back under another name." - added
Input schema / properties / value / descriptionAdded value: +"The value to store: a plain string, or a JSON object (stored as JSON text). Encrypted with the account key before it leaves this computer; the phone's Shortcuts read it with the same key."
9 tool updates
v0.1.2- First observed
askew_get_run - First observed
askew_inbox_ack - First observed
askew_inbox_list - First observed
askew_inbox_wait - First observed
askew_list_routes - First observed
askew_notify - First observed
askew_run - First observed
askew_variables_get - First observed
askew_variables_set
TDQS
Scored across 9 tools
Each tool has a clearly distinct purpose: running shortcuts, checking run status, listing routes, managing inbox items (list/wait/ack), sending notifications, and reading/writing shared variables. There is no overlap or ambiguity between tools.
All tools share the 'askew_' prefix, but the verb/noun order varies (e.g., 'askew_run' vs 'askew_inbox_list' vs 'askew_variables_get'). The pattern is readable and grouped by domain, but not perfectly uniform.
With 9 tools, the server is well-scoped for its purpose: discovering routes, executing them, polling results, handling phone-to-agent inbox messages, sending notifications, and managing shared variables. Each tool earns its place.
The tool surface covers the core lifecycle: route discovery, execution, status polling, inbox list/wait/ack, notification, and variable get/set. Minor gaps exist (e.g., no variable delete or run cancellation), but these are not essential for the main workflows.
Maintenance
Related MCP Connectors
MCP connector that lets ChatGPT list, search, and run your Apple Shortcuts via a local Mac agent
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Give your AI agent a memory and body on your iPhone: set alarms, ring your phone, over MCP.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP Server Integration with Apple Shortcuts21,339 npm348Apache 2.0
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to access Apple HealthKit workout data by receiving workout information from iOS Shortcuts and serving it through MCP protocol endpoints.-
- AlicenseNot gradedqualityBmaintenanceMCP server that lets ChatGPT list, search, and run your Apple Shortcuts on your own Mac through a local agent and stateless relay.MIT
- AlicenseNot gradedqualityBmaintenanceEnables generation of Apple Shortcuts through schema-validated MCP tools for catalog navigation, control-flow construction, validation, and signing.MIT