Agent Skills, Tools, and MCP: Giving AI Agents Useful Capabilities


Greetings, traveler!

A SwiftUI screen stutters when a user scrolls through a long list. You ask an AI agent to investigate, and it suggests adding Equatable to the row view. The suggestion sounds plausible, but the agent has not reproduced the stutter, inspected an Instruments trace, or established that unnecessary view updates are responsible. Conforming a row to Equatable alone does not establish that SwiftUI will skip the work: the view structure and how comparison is applied, including whether the .equatable() modifier is used, matter. Any benefit needs to be measured in the affected screen.

A better investigation requires more than another prompt. The agent needs access to the project, a way to build and run the app, profiling data, and guidance on how to interpret that data. Those needs belong to different parts of an agent’s environment. A tool can carry out an operation. MCP can expose capabilities from another application. A skill can describe a repeatable way to use those capabilities.

What happens when an agent calls a tool

A language model produces a response from the information it receives. On its own, it cannot inspect your Xcode project or run a simulator. An agent application can give the model access to operations that do those things.

Suppose the agent needs to find the implementation of a screen. The interaction might look like this:

  1. The application tells the model that a code-search tool is available, including the arguments it accepts.
  2. The model requests a search for a view or type name.
  3. The application executes the search and returns matching files and lines.
  4. The model uses the results to decide what to inspect next.

The model chooses a requested operation and supplies arguments. The surrounding application controls how that request is handled, whether it is allowed, and what result comes back. A tool call may fail, return incomplete data, or require permission. The agent has to account for those outcomes.

A tool can search files, execute a command, query an issue tracker, or launch an app. Its implementation can be a function in the agent application, a local command, or a capability provided by an external service. Tool calling describes the interaction; it does not prescribe one integration architecture.

For the scrolling issue, file search can reveal where state is stored and which views depend on it. A build tool can check whether a proposed change compiles. Neither operation explains why a frame was slow. That requires a suitable measurement and an interpretation of the result.

Where MCP fits

Model Context Protocol, or MCP, defines a common way for an AI application to connect to external capabilities. An MCP host manages connections through clients; each client communicates with a server that exposes supported capabilities. A server might run locally or be reached over a network, depending on the setup.

An MCP server can expose several kinds of capability:

  • Tools perform operations, such as running a build or querying a service.
  • Resources provide data that a client can read, such as a document or a configuration.
  • Prompts provide reusable message templates for an interaction.

A server does not have to provide all three. What the agent can actually discover and use depends on both the server and the host application.

For example, a mobile development MCP server could expose operations for building an Xcode scheme, launching an app in a simulator, and capturing a screenshot. An agent could invoke those operations as part of its investigation. MCP makes the integration available through a common protocol; the server still needs an implementation, and the host still controls access and presentation.

A tool does not need MCP. If the agent already has a shell command that runs the project’s tests, that may be enough. MCP becomes useful when capabilities need a consistent interface across clients or when a service owns the integration. It also adds a component to configure, maintain, and trust.

What a skill adds

A skill packages instructions and supporting materials for a task that may recur. In a common Agent Skills format, a skill is a directory containing a SKILL.md file. It can also include scripts, reference documents, and templates.

For a performance investigation, the skill might tell the agent to establish a baseline, identify a plausible bottleneck from evidence, make a focused change, and repeat the same measurement. A reference file can describe how to read a particular report. A script might transform a supported export into a smaller summary.

The skill gives the agent a method. The tools available to the agent provide access to the project and perform operations. If no profiling tool or trace is available, the instructions cannot produce a trace by themselves. The agent can still review code and propose hypotheses, but it should report that the performance claim remains unverified.

These pieces are often combined:

ComponentRole in the investigation
ToolSearches source code, runs a build, or retrieves a report.
MCP serverExposes one or more capabilities to the agent through MCP.
SkillDescribes when and how to investigate a performance problem.
Project instructionsRecord conventions and constraints that apply across tasks.

These responsibilities can overlap in a package: a skill may contain a script and instruct an agent to call an MCP tool. The script still needs an execution environment and permission to run.

A small SwiftUI performance skill

The following example shows the shape of a portable skill. It is illustrative: adapt the profiling steps and project commands to the host and Xcode version you use.

swiftui-performance/
├── SKILL.md
└── references/
    └── measurement-notes.md

The SKILL.md file gives the agent a focused procedure and points to a reference it can read when preparing measurements:

---
name: swiftui-performance
description: Investigate SwiftUI rendering and scrolling performance issues, including slow updates and visible hitches. Use when profiling or reviewing a suspected performance problem in a SwiftUI screen.
---

# SwiftUI performance investigation

1. Identify the affected interaction and the conditions needed to reproduce it.
2. Inspect the relevant views, state dependencies, and expensive work.
3. Read references/measurement-notes.md before preparing a profiling run.
4. Use available measurements to identify a candidate cause. Treat code inspection
   without measurements as a source of hypotheses, not a confirmed diagnosis.
5. Make a focused change that preserves behavior, then run relevant checks.
6. Repeat the measurement under comparable conditions when possible.
7. Report evidence, checks performed, and any missing measurements.

The referenced references/measurement-notes.md can be equally short:

# Measurement notes

Record the device, OS, build configuration, dataset, and interaction. Capture
comparable baseline and follow-up recordings. Look for work that coincides
with the reported hitch; consider both update frequency and duration. Repeat
runs when practical and report variation. If a recording is unavailable,
state that the effect on performance has not been measured.

Install the directory where your agent application expects skills, then ask it to investigate a particular screen. Some hosts also support selecting the skill explicitly. The project still supplies the scheme, device, test data, and commands. If the agent cannot operate Instruments, a developer can provide a recording or perform that part of the investigation manually. Check the host’s supported skill format and activation behavior before using the example.

Loading instructions when they are needed

A project may have skills for networking, accessibility, performance, release preparation, and many other tasks. Supplying the complete contents of every skill on every request would consume context even when most instructions are irrelevant.

A common approach is to make short descriptions available for discovery, then load the selected skill’s detailed instructions when needed. Additional references can be read later. This is often called progressive disclosure.

For the scrolling task, the agent might first see that a SwiftUI performance skill exists. After selecting it, the agent reads SKILL.md. It opens the measurement notes only when preparing a profiling run. This keeps specialized detail close to the task that needs it.

The exact loading and activation behavior varies by host. Some applications allow explicit selection; others may select a skill based on the task and its description. A skill can be missed, selected for the wrong task, or only partly followed. A specific description helps discovery, but it does not guarantee it.

The same caution applies to tool descriptions. Some hosts expose many tool definitions up front; others discover or load them on demand. Whether an MCP integration adds significant context depends on the client and configuration, not on MCP alone.

Investigating a slow SwiftUI screen

Consider a hypothetical activity screen with a list of several hundred entries. Scrolling occasionally feels uneven after the user changes a filter. The project has a build tool and access to Instruments, either through an agent integration or with a developer operating it. The scenario below describes an investigation, not a measured result.

First, define the conditions. Which device and OS version show the issue? Is the build optimized? What data and interaction reproduce it? A simulator can help with functional checks, but a representative physical device is often a better choice for judging on-device performance. Record the conditions so the comparison can be repeated.

Next, the agent searches the project for the screen, its row views, and the state used by the filter. It might find that filtering occurs inside a view’s computed body, or that a high-level state change causes many rows to be evaluated. Those observations narrow the investigation. They do not establish the cause of the hitch.

A profiling run can connect the visible delay to work performed during the interaction. In a supported version of Xcode, choose Product → Profile, select the SwiftUI template in Instruments, and record the interaction that reproduces the issue. Locate the relevant period on the timeline and compare hitch events with SwiftUI update groups and long view body updates. Use Time Profiler where appropriate to inspect code running during the expensive work. Available instruments and their presentation depend on the Xcode version.

A view body being evaluated often is a lead, not proof that it is expensive. Many individually short updates can also add up to substantial work. Examine both duration and frequency, and check whether the activity coincides with the visible delay. A trace can narrow the cause; it may take additional experiments to confirm it.

Suppose the trace indicates that the screen repeatedly performs an expensive transformation when the filter changes. The agent can propose moving that work to a more appropriate place, then verify that the resulting data stays correct as entries and filters change. It should not introduce caching without defining when the cached value becomes invalid.

After the change, repeat the same interaction with the same dataset and comparable build and device conditions. Run relevant tests and check the screen’s behavior. Compare several runs when practical: a single recording can be affected by noise, warm-up, or a different interaction. If the observed improvement is inconsistent, say so.

A useful final report might contain:

  • The interaction and environment used for the baseline and comparison.
  • The evidence behind the proposed cause, including the trace or report location.
  • The code change and the reason it should affect the observed work.
  • Build, test, and manual checks actually performed.
  • Results of the comparison, or an explicit statement that no comparable measurement was available.

This separation lets a developer review the reasoning. It also prevents a successful build from being presented as proof that scrolling improved.

Choosing between instructions, scripts, and integrations

Start with the operation the task requires. If an agent already has access to source files and a build command, a written procedure may be sufficient to guide a one-off investigation. A recurring task becomes a candidate for a skill when the same expertise or sequence needs to be applied across projects.

Use a script when a transformation or check is repeatable and can be specified precisely. For example, a script could summarize a known machine-readable performance export and reject an unsupported input format. Test it against representative inputs, make failures visible, and document what it does. A script packaged with a skill is executable code and deserves the same review as any other dependency.

An MCP server is useful when the agent needs access to capabilities owned by a separate application or service, especially if multiple clients should use the same integration. A profiling integration might expose a way to retrieve a prepared report. It should state which report formats and operations it supports; the word “MCP” alone says nothing about whether it can record an Instruments trace.

These options can coexist. A performance skill might call a build tool through MCP, read a report through another tool, and use a local script to summarize the result. The design should remain useful when one piece is unavailable: report the missing capability and adjust the scope instead of silently substituting a guess.

Keeping skills useful as their number grows

A skill collection can become difficult to use when several descriptions match the same request and their instructions disagree. For example, a general iOS skill might say to use a particular build command, while a performance skill assumes another scheme or device.

Keep reusable methodology separate from project-specific facts. A performance skill can describe how to compare measurements; project instructions can identify the scheme, supported devices, and test data. When two skills cover adjacent work, describe their boundaries: one may investigate performance, while another focuses on accessibility. If a task needs both, the agent should apply both where relevant.

Avoid copying long procedures into multiple skills. Shared material can live in a maintained reference that the relevant skills point to, provided the host can access it. Check that references resolve in the environment where the skill is installed. Also establish which instructions take precedence when a general procedure conflicts with an explicit project or user requirement; that ordering depends on the host.

A concise skill is easier to inspect, but brevity alone is not the goal. Include the decisions that change the outcome, the evidence expected, and what to do when a required tool is unavailable. Remove details that repeat general documentation without helping the agent make a decision.

Testing a skill

A skill should earn its place through use. Select a small set of representative tasks and run them with and without the skill under comparable conditions. Start each run from the same project revision, data, and relevant environment. Use fresh sessions with equivalent task instructions so that earlier investigations or changes do not influence one side of the comparison. Include a case where performance data is available and another where it is missing. Check whether the agent distinguishes a measured bottleneck from a plausible code-level hypothesis.

Review the resulting changes and reports. Did the agent select the skill for the right task? Did it preserve behavior? Did it run appropriate checks? Did it report unavailable measurements honestly? Also record the effort involved, such as extra tool calls or time spent loading instructions. A skill can improve consistency while making simple tasks unnecessarily slow.

Repeat the evaluation when the skill, model, host, or tool integration changes. Results can vary across runs, so a few examples provide useful feedback rather than a universal reliability score. Keep some scenarios out of the initial tuning set to see whether the instructions generalize beyond the cases used to write them.

Trust and operational limits

Skills are instructions interpreted by an agent. They can encourage careful behavior, but they do not enforce access controls or guarantee that every step will be followed. Permissions, sandboxing, credentials, and automated checks need to be configured separately in the environment that executes tools.

The same applies to MCP servers. Connecting a server can grant access to the data and operations it exposes. Review its origin, configuration, permissions, and any scripts it runs. Limit access to what the task requires, and treat returned content as data that may be incomplete or contain misleading instructions.

For a scrolling investigation, an existing performance skill, source access, a build tool, and an Instruments recording may be enough. Add another integration when it gives the agent a capability the investigation actually needs. Keep the recording and verification results with the change so a reviewer can assess the evidence behind it.