Skip to content
AI Architecture
12 min readVuong Ngo

Scoped MCP Tool Access Ships in Agiflow ChatGPT Plugin v3

ChatGPT plugin v3 adds scoped MCP tool access: an exact per-task allow-list enforced before execution. Agiflow for iPhone 1.0.1 opens Home on the work that needs you.

Scoped MCP Tool Access Ships in Agiflow ChatGPT Plugin v3

Narrow task authority and current human visibility are two halves of the same handoff.

Two Agiflow releases landed in the same fortnight. They solve one delegation problem from opposite ends.

What shipped: ChatGPT plugin v3 adds scoped MCP tool access. You attach an explicit allow-list to an individual task. find_connected_tools discovers candidate actions, update_task writes an exact mcpTools replacement naming the server IDs and tool names that task may use, and task_exec refuses any server or tool outside that list. Passing an empty array revokes all external access. A task-scoped session can execute its allow-list but cannot browse the catalogue or widen its own permissions.

The other half is Agiflow for iPhone 1.0.1, released on 14 August 2026. Home now opens on work that needs a person, with opt-in push when a task or work unit changes status. [1]

On a changelog, those updates could look unrelated. Operationally, they close the same loop. An assistant that can reach every connected tool is unsafe to delegate to. A person who cannot see stuck work cannot intervene. v3 narrows what the assistant may execute. 1.0.1 surfaces what a person needs to handle. One behaviour flag, isBlockedState, connects both ends.

What is new in this release

ReleaseChange
ChatGPT plugin v3New: find_connected_tools discovers actions on organization-connected third-party MCP servers
ChatGPT plugin v3New: task_exec executes an external tool only when that exact server and tool are selected for the target task
ChatGPT plugin v3New: create_task, get_task and update_task carry the mcpTools exact-replacement field and allowedMcpTools read-back
ChatGPT plugin v3Improved: create_task returns discovery next-actions instead of embedding the whole tool catalogue in its response
ChatGPT plugin v3Improved: attach_task_artifact now takes a strict artifactFile schema requiring both download_url and file_id
ChatGPT plugin v3Compatibility: the 0.0.2 tool surface is frozen as a contract. 0.0.1 is retired and returns UNSUPPORTED_MCP_VERSION
iPhone 1.0.1New: Home opens on decisions waiting on an answer, then work in flight grouped by project and work unit
iPhone 1.0.1New: push notifications on task and work-unit status change, opt-in per device
iPhone 1.0.1Changed: the App Store listing is now Agiflow: AI Project Board
The enforcement path starts with the task record.

How scoped MCP tool access works per task

A prompt cannot enforce an execution boundary.

Suppose an organization has connected a documentation server, a CRM, a billing system and a deployment server. Those connections are authenticated once, at organization scope, and every assistant conversation then inherits the whole catalogue. A release-notes task needs a documentation read and a project update, not customer records or deployment actions.

That is a connection boundary being asked to do an execution boundary's job. OAuth answers "may this client reach this server". Client-side controls such as app toggles and write confirmations answer "may this conversation use this app". Neither one answers "may this task call this tool right now".

ChatGPT plugin v3 puts that last decision on the task record. The allow-list is per task, not per user or per server, and Agiflow checks it server-side before dispatching a call upstream. Discovery proposes candidates. Stored task permissions decide what runs.

The four calls

Take a hypothetical release-notes task, REL-27. It needs a documentation read_page and one project update tool, and nothing else external. To restrict MCP tools per task in v3, use the four-step loop in the Agiflow MCP guide. [2]

  1. Discover with find_connected_tools. The schema describes it as finding "external tools that match an explicit user-requested action before attaching the smallest suitable set to a task". It is read-only, takes a required intent, and paginates with offset and hasMore; limit defaults to 10 and tops out at 25.
  2. Attach with update_task. Set mcpTools to the selected mcpServerId values and exact tool names. The field describes itself precisely: "Exact replacement for task external tool access. Omit to keep access unchanged. Pass [] to revoke all external tools."
  3. Verify with get_task. Read allowedMcpTools back, a field described in code as "only the external MCP tools explicitly allowed for this task". The stored task record is the authority, not the assistant's report that setup worked.
  4. Execute with task_exec. Described as executing a named external tool "only when that exact server and tool are selected under Tools & access for the target task". Its taskId field reads: "task whose selected tool access must authorize this call".

Connect ChatGPT plugin v3 at https://agiflow.io/api/v1/chatgpt-app/0.0.3. The path uses the code version, 0.0.3, while the release name remains v3. For setup, use the ChatGPT integration page.

Four-step MCP flow from tool discovery to task execution, with allowed and denied branches.

Discovery proposes the set. The stored task allow-list and the execution gate decide what runs.

What the gate actually checks

Here is where MCP tool permissions become enforceable. task_exec resolves task scope, then applies two gates before dispatching anything to the upstream server.

An unselected server returns:

External MCP server "{server}" is not enabled for this task. Enable it before calling task_exec.

A tool that is not on a selected server's list returns:

External MCP tool "{tool}" is not allowed for server "{serverName}" on this task.

Only after both gates pass does Agiflow dispatch the call upstream. Separate messages distinguish a missing server selection from a tool-level denial.

If the upstream server requires authorization, task_exec returns authorizationRequired with an authorizationUrl instead of hard-failing. find_connected_tools surfaces the same signal in its results.

The ceilings, and the asymmetry

One task may select at most 5 external servers and 64 external tools. Validation rejects duplicate servers and tool names. It also requires each server to be enabled for the project and not pending authorization, and each selected tool to exist in the live catalogue. Those are ceilings, not targets. REL-27 still gets two tools.

Task scope is deliberately asymmetric. Across scopes, v3 registers the two proxy tools like this:

text
organization  ->  find_connected_tools, task_exec
project       ->  find_connected_tools, task_exec
work unit     ->  find_connected_tools, task_exec
task          ->  task_exec
A task-scoped session can execute its allow-list, but it cannot browse the catalogue. Discovery is deliberately withheld in task scope.

The same session also cannot widen its own access: in a task-bound context, mcpTools is omitted from the update_task schema entirely, and that schema is strict, so an attempt to smuggle the field in is rejected rather than ignored. Changing the allow-list requires a wider scope. A task-bound session cannot do it itself.

Passing an empty array is the revoke button. mcpTools is an exact replacement, not a merge.

Omit mcpTools, and existing access stays unchanged. Send [], and every external tool is revoked. Exact replacement removes partial-merge ambiguity and makes revocation explicit.

When a call goes through, the TaskExecution result card states: "Access was checked against this task before execution." That line captures the release.

Custom project statuses the assistant can resolve

Tool access is only half the handoff. The assistant and the person also need a shared way to interpret project state when a team replaces the default labels.

An organization can own project templates. Each template defines an ordered set of statuses, with behaviour flags alongside each display name. Custom project statuses in ChatGPT work because meaning lives in those flags as well as the label:

FlagWhat it tells the system
isStartedStatehelps resolve review
isCompletionStatehelps resolve done
isTerminalStatemarks a terminal status
isBlockedStatefeeds Needs You on iPhone
isAgentPickablehelps resolve todo
list_project_statuses returns every status with its key, name, position, colour and all five flags. Its description tells the model to discover valid names before creating or updating tasks and work units. list_templates shows the template catalogue, while manage_project_template can create, update or delete an organization-owned template. The ProjectStatuses widget gives one direct instruction: "Use these status names when creating tasks or work units."

The resolver is strict by design

The resolver matches a supplied status against its ID, then a normalized key, then a normalized name. In strict mode, an arbitrary off-list value is rejected with the available names echoed back:

Status "{value}" not found. Available statuses: {names}

Where legacy fallback is allowed, known vocabulary can map to a custom status set by behaviour. Roughly 35 common terms map onto eight canonical keys: backlog, ideation and planned reach planning; doing and started reach in progress; hold and paused reach blocked. From there, todo picks the first isAgentPickable status, review the last isStartedState, and done the first isCompletionState.

The result is useful without being permissive: the model does not have to know every display name, and it cannot invent a valid status. Human-side status management remains available in the web dashboard; organization-owned templates can also be managed through the template tools. Those same behaviour flags now shape what Home shows on iPhone.

Agiflow for iPhone 1.0.1

The July launch post covered Agiflow for iPhone 1.0.0 and the role of human authority. Version 1.0.1 is narrower: Home triage and opt-in push, shipped on 14 August. [1]

The release notes, verbatim from the listing:

text
HOME SCREEN

Home now opens on what needs your attention. Decisions waiting on an answer sit at the top, followed by the work currently in flight, grouped by project and work unit.

PUSH NOTIFICATIONS

Tasks and work units now notify you when their status changes. See when work moves to review, gets blocked, or finishes.

The same release changed the listing name from Agiflow to Agiflow: AI Project Board.

Annotated iPhone Home screen showing Machines, Needs You and In Flight sections in Agiflow 1.0.1.

Three stacked sections, with a header counter for the work that needs a person.

Home stacks three sections in a pull-to-refresh view. Machines lists connected devices with running and failed counts, marks a stale heartbeat offline, and can summarise the fleet as "2 of 3 online". Needs You carries the attention count. In Flight groups active tasks by project template and work unit; each task row shows its slug, relative age and a running badge.

In an AI project management app for iPhone, blocked tasks cannot depend on one fixed label. The app reads the organization's statuses, keeps the IDs marked isBlockedState, and queries tasks in those statuses. It sorts the result newest first and caps Needs You at five, so the screen stays a triage list rather than a backlog.

Tapping a card opens task detail: status, priority, assignee, description, tags and comments. The bottom bar offers Move and Delete. Move opens a status-change sheet, so the lead can act without returning to the board.

Push is opt-in per device. Registration pairs an installation ID with an APNs device token. The preference screen distinguishes On, Off, Blocked in device settings and retryable failure. When a status changes, the server sends Task: {title} or Work unit: {title} with the body Moved to {statusName}. A notification can deep-link to task detail, the board or the workflow list, including from a cold start.

Home refetches its data every 30 seconds while mounted. This is polling, not a live stream. Version 1.0.1 is iPhone only. That brings both releases back to one behaviour flag.

Where the two surfaces meet

The releases meet at isBlockedState, a link not documented on the public site.

Each status carries isBlockedState in the project template. The plugin can use that flag to resolve legacy status language onto a team's custom names. The iPhone app uses the same flag to decide which tasks belong in Needs You. No label translation layer is required.

A custom blocked status flows to exact MCP resolution and the iPhone NEEDS YOU group.

The display name belongs to the team. The blocked-state behaviour stays explicit.

Rename Blocked to Waiting on Security, and the behaviour stays intact. The resolver can match the status by ID, key or name, or map supported legacy language through the flag. It still rejects arbitrary off-list values. The phone puts the task in Needs You because it checks the flag, not the display name.

The phone reads the flag, not the name. Rename Blocked to Waiting on Security and it still surfaces under Needs You.

In the REL-27 example, the loop now closes. A wider scope discovers read_page. update_task stores that selection, and get_task verifies it. A billing call outside the list is refused before it reaches the upstream server. When the task moves to Waiting on Security and is among the five newest matches, a subsequent Home poll puts it under Needs You, where task detail offers the Move action.

What this does not do

The boundaries matter as much as the release notes.

  • The allow-list governs reachability, not correctness. A permitted read_page can still fetch the wrong URL, and an allowed update can still write a poor summary. Narrow access limits which action can run. It does not certify the result.
  • Blocked is a status flag, not a dependency graph. Agiflow does not model task dependencies, and the app does not claim a task is blocked by a particular person or upstream task.
  • The phone is not live. Home polls every 30 seconds while mounted. Notifications are opt-in per device.
  • Version 1.0.1 is iPhone only. It does not support iPad or Android.
  • Upstream authorization still applies. If a selected server requires OAuth, task_exec returns authorizationRequired and an authorization URL. The task allow-list does not bypass that step.
  • Client controls still matter. Nothing here replaces OAuth, ChatGPT's app toggles or write confirmations. It sits underneath them and answers a different question.

Scoped access adds nothing for solo users with no external MCP servers connected. Version 1.0.1 also does not serve teams that need iPad or Android today. Neither release turns a product setting into a compliance programme.

My read of the wider context is deliberately an opinion: per-tool MCP authorization remains unsettled, while much of the discussion describes what specifications should do. Agiflow's useful contribution is testable behaviour: distinct refusal strings, numeric ceilings and a task scope that can execute without discovering or widening access.

FAQ

What happens if the assistant calls a tool that is not on the list?

task_exec refuses before the call reaches the upstream server, with one of two distinct errors: External MCP server "{server}" is not enabled for this task or External MCP tool "{tool}" is not allowed for server "{serverName}" on this task.

Can the assistant grant itself more tools?

Not from a task-bound session. In that context, the mcpTools field is omitted from the strict update_task schema, so passing it anyway is rejected. Task scope also cannot browse the catalogue through find_connected_tools.

How many external tools can one task have?

At most 5 external servers and at most 64 external tools, with no duplicate servers or tool names. Each named tool must exist in the live catalogue when the selection is written.

How do I revoke a task's external access?

Send mcpTools: [] on update_task. The field is an exact replacement, not a merge, so an empty array clears everything. Omitting the field leaves access unchanged.

What happens if the upstream server needs OAuth?

The call returns authorizationRequired together with an authorizationUrl and guidance, instead of failing outright. Connect the server, then retry.

Can I rename Agiflow's statuses to match my team's workflow?

Yes. An organization can own project templates, and each template defines its own ordered statuses with display names of your choosing.

If I rename them, does the AI still understand them?

Yes, for an exact ID, key or name, and for supported legacy language mapped by behaviour. todo picks the first agent-pickable status, review the last started status, and done the first completion status. Arbitrary off-list values are still rejected.

Can the AI invent a status that does not exist?

Not arbitrarily. In strict mode, the resolver rejects off-list values and returns the available names. Where legacy fallback is enabled, only known aliases map through behaviour flags.

What does the iPhone app show me first?

Home opens on three stacked sections: Machines, Needs You, and In Flight, with a header count of the items that need you.

How does the app decide a task is blocked?

It reads the organization's statuses, collects the IDs of every status where isBlockedState is true, and queries tasks in those statuses. Results are sorted newest first and capped at five.

How current is what I see on the phone?

Home data refetches every 30 seconds while the screen is mounted. Relative timestamps re-tick every 60 seconds. It is polling, not a live stream.

Can I act on it from the phone?

Yes. Open the task and use Move to change its status from a bottom sheet. Delete is available in the same bar.

Do I get notified when something blocks?

If you opt in on that device. A task or work-unit status change sends Task: {title} or Work unit: {title} with the body Moved to {statusName}. Tapping it opens task detail or the board.

Try it on one task

The smallest useful trial is one real task. Connect ChatGPT plugin v3 at https://agiflow.io/api/v1/chatgpt-app/0.0.3, apply scoped MCP tool access with the four-step loop in the MCP guide, select only what the task needs, and read allowedMcpTools back. Then force one denied call before widening access. Prompt obedience is not evidence of enforcement. A refusal is.

Connect Agiflow to ChatGPT, or read the integration setup first.

References

  1. Apple App Store, "Agiflow: AI Project Board." https://apps.apple.com/au/app/agiflow-ai-project-board/id6775743277 . Captured 2026-08-15. Source for version 1.0.1, the 2026-08-14 release date, the listing name and the verbatim release notes quoted above.
  2. Agiflow, "Agiflow MCP guide." https://agiflow.io/guides/mcp . Captured 2026-08-15. Source for the discover, attach, verify and execute loop and the exact-replacement behaviour of mcpTools.

Put this project board inside ChatGPT

Open Agiflow in ChatGPT to plan campaigns, create tasks, and check what needs attention. Create a free Agiflow account when you are ready to keep the board for your team.