Your AI Agent Doesn't Need to See Every ToolThe first version of an AI agent is usually easy to understand.Give it three MCP tools:Agent ├── search_customer() ├── get_order() └── search_policy()The model can see the options. You can follow the reasoning. When something goes wrong, you can usually understand why.Then the system grows.A new team adds payment tools. Another team exposes shipment APIs. Someone connects an MCP server. Policy search becomes three different tools because the company has three different knowledge systems.Six months later, the agent looks more like this:Agent ├── 10 customer tools ├── 8 payment tools ├── 12 order tools ├── 6 policy tools └── multiple MCP serversNothing is obviously broken.The agent simply has far more decisions to make.Which tool should it call first? Which of the three similar customer tools has the right data? Should it check the shipment before the carrier incident? Does it need another policy search? Which outputs should remain in context? When does it have enough information to stop?I have watched engineers stare at traces wondering why an agent called the same policy endpoint four times in a single turn. The agent was not broken. It was uncertain — and uncertainty in an oversized decision space compounds quickly.At some point, one question becomes unavoidable:Are we giving the agent more capabilities, or simply giving it more decisions to get wrong?The problem is not really the number of toolsAn agent doesn't suddenly become unreliable at tool number 11. There's no magic threshold. A model can handle a large set of tools when they're clearly differentiated and the task genuinely needs flexible exploration.The problem sharpens when the tool surface grows in three specific ways:several tools have overlapping responsibilities,common tasks require repeatable multi-step sequences,and low-level implementation details are exposed directly to the main model.At that point, every new tool expands the agent's decision surface — the set of choices the model must make before it can act.The model must decide:which tool applies,when to call it,what arguments to send,what sequence to follow,which results matter,whether another call is necessary,and when to stop.This creates predictable failure modes.The agent chooses a similar but incorrect tool. It calls the right tools in the wrong order. It skips an important verification step. It repeatedly calls tools that return overlapping data. Raw responses accumulate in context. Two systems disagree, and the model is left to reconcile the conflict on its own.These aren't always model intelligence problems.Often we're asking the model to rediscover a workflow the software already understands.Tool connectivity is confused with tool visibilityMCP, function calling, APIs, plugins, and agent frameworks have made it easier to connect models to external systems. Useful. But it came with a quiet assumption:If a capability can be connected to the agent, the LLM should probably see it as a tool.That assumption doesn't hold.Your backend may have separate APIs, databases, MCP servers, rules engines, and services for orders, payments, shipping, customer history, and policy.The LLM doesn't need your backend org chart.The question should not beCan the model call this capability?The right question is:At what level of abstraction should the model see this capability?That's where a tool abstraction layer helps.A missing package should not require a miniature research projectConsider a customer asking:“Why has my order not arrived, and what can you do about it?”A support agent might have access to:get_customer()get_orders()get_shipment()get_carrier_events()get_support_history()get_active_incidents()search_policy()check_refund_eligibility()check_replacement_eligibility()The LLM has to reconstruct the whole investigation.It needs to retrieve the order and find the shipment. Inspect carrier events and check active incidents. Determine refund and replacement eligibility. Then retrieve the right policy.That sequence isn't wrong.The question is whether the LLM should have to orchestrate it from scratch every time a delivery problem occurs.Instead, the better way is to expose one higher-level tool that will internally call tools:investigate_delivery_issue(customer_id, order_id)Internally, that tool will:Retrieve the orderCheck shipment statusRetrieve recent carrier eventsCheck active incidentsApply refund and replacement rulesRetrieve only the relevant policyReturn structured evidenceFor example:{ "issue": "delivery_delay", "delay_days": 6, "shipment_status": "stuck_in_transit", "active_incident": true, "refund_eligible": false, "replacement_eligible": true, "recommended_action": "offer_replacement", "evidence_ids": [ "shipment-102", "incident-74", "policy-5.2" ]}Now the LLM has a smaller problem to work with.It still needs to understand what the customer wants, explain what happened, ask a clarifying question, handle an edge case, present the options. LLMs are good at that part alreadyBelow is a Python skeleton:def investigate_delivery_issue( customer_id: str, order_id: str) -> dict: order = get_order(order_id) shipment = get_shipment(order.shipment_id) incident = get_active_incident(shipment.carrier) eligibility = evaluate_resolution_options( order=order, shipment=shipment, incident=incident, ) return { "issue": "delivery_delay", "shipment_status": shipment.status, "delay_days": shipment.delay_days, "active_incident": incident is not None, "refund_eligible": eligibility.refund, "replacement_eligible": eligibility.replacement, "recommended_action": eligibility.recommended_action, }The important part is where the orchestration lives.Move repeatable choreography below the main modelWith direct tool exposure, the architecture looks like this:LLM ├── API tool ├── MCP tool ├── database tool ├── search tool ├── policy tool └── workflow toolWith a tool abstraction layer the architecture changes a bit:LLM ↓High-level domain tool ↓Internal orchestration ├── API calls ├── MCP tools ├── databases ├── deterministic rules └── optional LLM substep ↓Structured evidenceNot every MCP tool needs to be directly visible to the main LLM.MCP can still provide the underlying connectivity. A high-level domain tool may call several MCP tools internally.Same goes for APIs, database queries, search functions, and workflow steps.The system may depend on 50 underlying capabilities — in production systems that number is often higher. The main LLM doesn't need to see all of them.This isn't a new idea — skills, subagents, orchestrator-worker systems all exist in public architectures and are examples of advanced tools calling tools internally.The same pattern can work across different domainsDevOpsInstead of exposing:get_logs()get_metrics()get_traces()get_deployments()search_runbook()get_open_incidents()you might expose:diagnose_service_incident(service_id)The tool gathers the standard diagnostic evidence; the model focuses on what's actually ambiguous.E-commerce riskInstead of having the model independently query buyer history, device signals, payment data, velocity checks, and policy rules, expose:assess_order_risk(order_id)The result can contain risk signals, rule outcomes, and evidence references instead of pages of raw records.Fintech: account eligibilityWe ran into this directly. The agent needed to answer a simple question: is this customer eligible for a product?To get there, it was calling:get_account_status()get_kyc_status()get_credit_profile()get_existing_products()get_regulatory_flags()Five tools. Every single time. For a yes/no answer with a reason.We replaced them with one:check_product_eligibility(customer_id, product_id)Internally it pulls account standing, KYC status, credit profile, existing product holdings, and any regulatory restrictions — then applies the eligibility rules. It returns:{ "eligible": false, "reason": "kyc_incomplete", "blocking_factors": ["address_verification_pending"], "next_step": "prompt_document_upload"}The LLM gets a decision, not a pile of records. The agent gets an answer. The five round-trips stay hidden.Customer supportSame pattern. Instead of nine tools for a delivery question, expose:investigate_delivery_issue(customer_id, order_id)The tool handles shipment status, active carrier incidents, refund and replacement eligibility, and policy lookup internally. The model handles the conversation.A bad abstraction layer is worse than no abstraction layerTeams can create dozens of high-level tools and recreate the same selection problem with fancier names. They can hide information the model genuinely needs, duplicate business logic across multiple orchestration layers, or force open-ended tasks into rigid workflows.And they can create monster tools such as:solve_customer_problem()Not useful abstraction. Just a monolith with a vague contract.A good high-level tool should represent a bounded domain operation. It should have a clear purpose, predictable inputs, traceable steps, and structured outputs.Building the abstraction layer has a real cost. Someone has to write the orchestration, the error handling, the contracts, the tests.Moving a decision out of the prompt moves it into software — and software is the right place for repeatable logic.Direct tool calling still makes sense when the toolset is small and clearly differentiated. Same when the task is genuinely exploratory, or when the right sequence actually depends on model reasoning.The goal isn't minimizing tool count. It's putting each decision at the right layer.The design question that is worth askingWhen adding a new capability to an agent, don't just ask:"Can the LLM call this tool?"Also ask:Is this capability meaningful to the user, or only to the implementation?Does the LLM genuinely need to choose when to call it?Is the call sequence mostly repeatable?Can several low-level calls be combined safely?Can the result be returned as structured evidence?Does hiding the low-level tools remove useful model flexibility?If most of those answers point toward "no," the capability belongs below the main model.What to rememberMore tools means a larger decision surface. More choices about routing, sequencing, and when to stop — made on every turn.A tool abstraction layer wraps those backend calls behind domain-level tools that return compact, structured results.The underlying system can still use APIs, MCP tools, databases, rules engines, and smaller LLM calls. The main model just doesn't need to see all of them.The goal isn't fewer tools. It's making sure the LLM only handles decisions that actually need LLM judgment.The harder step is knowing when to keep a tool out of the LLM's sight entirely.So before adding another API, MCP capability, or workflow step to your agent's tool list, ask one question:Should the LLM need to know this tool exists at all?