Built the same ServiceNow agent three ways, native, external MCP, interactive. Here's what changed.

AlexMcDonald
Tera Contributor

I wanted to know how much of an agent survives when you change where it runs, so I built the same one three times against the same platform.

 

External over MCP, a Python orchestrator calling Claude through the Anthropic API and reaching ServiceNow through an MCP connector. Interactive through Claude Desktop, same connector, no deployment. Native inside the platform, a Script Include and Scripted REST API, no MCP hop at all.

 

The native version runs as the requesting user through GlideImpersonate, so permissions come from the platform's own ACLs rather than something I had to build. It places real Service Catalog orders through the Cart API, and every reasoning step gets written to a trace table so a run can be replayed later.

 

One tool design bug worth sharing separately: a query string with strict syntax let the model silently malform a sort clause, no error, just quietly wrong order. Fixed by moving sort out of the string into typed parameters the model can't get wrong syntactically.

 

Full writeup: https://www.linkedin.com/pulse/most-enterprise-ai-agents-chatbots-i-built-real-one-three-mcdonald-rl... 
Repo, open source: https://github.com/BrianMcD47/servicenow-claude-mcp-bridge

 

Curious how others here are drawing the line between building natively versus reaching for MCP.

2 REPLIES 2

Abhishek Pal
Giga Guru

Hi @AlexMcDonald ,

This is a very useful comparison, especially because you implemented the same business outcome through three different execution models.

With the capabilities now available in the Australia release, I would draw the architecture boundary less around "where does the LLM run?" and more around:

Reasoning ownership
-> Tool ownership
-> Authorization boundary
-> Transaction ownership
-> Governance / observability

1. Native ServiceNow Agent

I would prefer the native approach when the business process and the majority of the data/actions already belong to ServiceNow.

For example:

User request
-> ServiceNow AI Agent
-> Catalog tool / Flow / Subflow / Script
-> ServiceNow ACL enforcement
-> ServiceNow transaction

This is the strongest fit when the agent primarily needs to work with:

Incident
Case
Catalog
Change
HR
CMDB
ServiceNow workflows

One thing I would reconsider for a production implementation is relying on custom GlideImpersonate logic for the agent security boundary.

AI Agent Studio now provides an OOB security model based on:

Dynamic User

and:

AI User

For most user-initiated agents, ServiceNow recommends Dynamic User.

The agent executes using the invoking user's identity and existing platform authorization.

For additional least privilege, Role Masking can restrict the roles available to the agent to only the approved subset of the invoking user's roles.

Conceptually:

Invoking User Roles
INTERSECT
Agent Role Mask

Effective Agent Roles

This means the agent cannot gain a role simply because it needs it.

ServiceNow ACLs still make the final authorization decision.

For sensitive actions, I would also consider Supervised execution:

Agent proposes action
-> Human approval
-> Tool executes

That is preferable to implementing another custom approval mechanism around the agent.

2. External Agent -> ServiceNow

Your external MCP implementation is valid when the external agent is intentionally the orchestration layer and ServiceNow is one of several enterprise systems it needs to operate.

However, on Australia I would evaluate the OOB ServiceNow MCP Server Console before maintaining a custom MCP bridge.

The architecture can now be:

Claude / external agent
-> OAuth
-> ServiceNow MCP Server
-> Approved ServiceNow tools
-> Platform ACL/security
-> Transaction

Navigate to:

MCP Server Console
-> Configuration
-> Servers

You can create different MCP servers for different domains/use cases and expose only the required tools.

For example:

IT MCP Server
-> Get Incident
-> Create Incident
-> Submit Catalog Request

HR MCP Server
-> Get HR Case
-> Search HR Knowledge

This is significantly safer than exposing a generic:

query_any_table
update_any_record

tool.

I would expose business capabilities rather than unrestricted CRUD APIs wherever possible.

For example:

Better:

submit_laptop_request

get_major_incident_summary

create_customer_case

Rather than:

query_table

update_record

The more deterministic and purpose-specific the tool contract is, the easier it is to secure and govern.

3. Your typed-parameter finding is particularly important

I agree with the change you made after the sort-clause issue.

I would apply that principle to every agent tool.

Avoid letting the model construct something similar to:

active=true^priority=1^ORDERBYDESCsys_created_on

when the same contract can be expressed as structured inputs:

Filter:
active = true
priority = 1

Sort field:
sys_created_on

Sort direction:
DESC

Limit:
10

Then deterministic code generates the final query.

The principle I use is:

LLM
-> decides WHAT operation is required

Tool
-> validates HOW that operation can be executed

Platform
-> decides WHETHER it is authorized

That separation becomes extremely important once agents perform writes.

4. ServiceNow Agent -> External System

There is now another MCP pattern worth separating from your external-agent implementation.

ServiceNow provides an MCP Client.

This is the inverse architecture:

ServiceNow AI Agent
-> MCP Client
-> External MCP Server
-> External tool

Use this when ServiceNow should remain the orchestration/reasoning layer but the agent needs capabilities outside ServiceNow.

For example:

ServiceNow Agent
-> External source-code MCP
-> External documentation MCP
-> External business system
-> Continue ServiceNow workflow

So I would distinguish:

External Agent needs ServiceNow tools
-> ServiceNow MCP Server

ServiceNow Agent needs external tools
-> ServiceNow MCP Client

5. There is now a fourth architecture: A2A

I would also separate MCP from Agent2Agent.

The boundary I use is:

MCP
-> Agent invokes a TOOL

A2A
-> Agent delegates/collaborates with another AGENT

ServiceNow Australia supports external AI agents through the Agent2Agent protocol.

For example:

ServiceNow Customer Service Agent
-> A2A
-> External Logistics Agent
-> Investigates delivery status
-> Returns business result
-> ServiceNow Agent continues the case

That is different from:

ServiceNow Agent
-> MCP
-> getShipmentStatus()

The second interaction is a tool invocation.

The first is delegation to another autonomous agent.

6. Interactive MCP

I think your interactive Claude Desktop version is excellent for:

Exploration
Developer productivity
Human-assisted administration
Proof of concept
Troubleshooting

But I would not normally make a desktop conversational session the production orchestration layer for a process that is:

Scheduled
Event-driven
SLA-bound
High-volume
Recoverable
Audited

Once those requirements exist, I would move the orchestration into:

ServiceNow Agentic Workflow

or:

A managed external agent runtime

depending on which platform owns the business process.

7. Observability

Your replayable trace table is a very useful pattern.

For the native implementation, however, I would avoid recreating all platform execution telemetry.

ServiceNow already records agentic execution information through the Agentic AI execution framework.

I would keep the custom trace focused on business-level information such as:

Correlation ID
User request
Business decision
Tool selected
Business result
Record created/updated
Final status

and use ServiceNow's execution records for the lower-level AI execution trace.

For MCP governance, Australia also introduces AI Gateway.

AI Gateway provides:

Governance
Security
Observability

for MCP transactions and can be used with approved MCP servers through AI Control Tower.

That becomes particularly valuable when the number of external agents and MCP servers starts growing.

My architecture decision would therefore be:

Native ServiceNow AI Agent

Use when:
ServiceNow owns the business process and most of the tools/data.

ServiceNow MCP Server

Use when:
An external agent owns orchestration but needs controlled ServiceNow capabilities.

ServiceNow MCP Client

Use when:
ServiceNow owns orchestration but needs tools hosted outside ServiceNow.

A2A

Use when:
A ServiceNow agent and another autonomous agent need to collaborate/delegate work.

Interactive MCP

Use when:
A human is intentionally in the loop for exploration or assisted execution.

The design principle I would keep across all five patterns is:

Keep authorization as close as possible to the system performing the transaction.

For example:

External AI decides:
"Create the request"

ServiceNow decides:
"Is this identity actually allowed to create this request?"

That authorization should remain enforced by the platform rather than being trusted to the upstream model.

So your three-agent experiment demonstrates something important:

The user experience can look almost identical while the trust boundary underneath it is completely different.

Given Australia, I think an especially interesting fourth implementation would be:

Your custom external MCP bridge

vs.

ServiceNow MCP Server Console

using the same catalog-order use case.

That comparison would show exactly how much custom authentication, tool exposure, authorization and observability code can now be moved back into supported ServiceNow capabilities.

Official ServiceNow references:

Action Fabric - MCP Server, MCP Client and A2A:
https://www.servicenow.com/community/now-assist-articles/action-fabric-mcp-server-mcp-client-and-a2a...

MCP Server Console:
https://www.servicenow.com/docs/r/intelligent-experiences/create-mcp-server.html

MCP Client:
https://www.servicenow.com/docs/r/intelligent-experiences/enable-ai-experiences/mcp-client.html

External agents / A2A:
https://www.servicenow.com/docs/r/intelligent-experiences/external-agent-protocols.html

AI Agent security:
https://www.servicenow.com/docs/r/intelligent-experiences/aia-security-implementation.html

Role Masking:
https://www.servicenow.com/docs/r/platform-security/identity/role-masking.html

AI Gateway:
https://www.servicenow.com/docs/r/intelligent-experiences/ai-control-tower/ai-gateway-overview.html

Really useful experiment. Thanks for sharing the implementation details with the Community.

Kind Regards,
Abhishek Pal

Abhishek, this is a more complete map than the one I drew. Moving the boundary from "where does the LLM run" to reasoning, tool, authorization, and transaction ownership is the right level to argue at. I was using placement as a proxy for those four, and you're right that they can come apart.

 

On Dynamic User and Role Masking, I'll take the correction. Worth saying what impersonation was doing in my build, though. An async Business Rule runs in a system context, so GlideImpersonate was the mechanism to make the platform's own ACLs apply rather than a security layer I wrote myself. Dynamic User is the supported version of that same intent, and Role Masking solves something impersonation does not, since inheriting the invoking user's roles wholesale is not the same as intersecting them with an approved subset.

 

One clarification on the external build. The custom bridge was not a preference. The native MCP Server and AI Agent Studio sit behind Now Assist licensing that a free developer instance does not include, which I checked directly before routing around it. On an entitled instance I would start with MCP Server Console.

 

Your split between the model deciding what, the tool validating how, and the platform deciding whether is a cleaner statement of the sort clause lesson than the one I wrote. I have eleven purpose specific tools and one generic create_record guarded by a table denylist. Your framing suggests the generic one is the one to retire.

 

The MCP Client and A2A distinction is the piece I had not separated at all. Tool invocation against delegation to another agent is a real boundary, and I was collapsing both into "external."

 

The comparison you suggest is the right next experiment. Same catalog order, custom bridge against MCP Server Console, measuring how much authentication, tool exposure, and observability code stops being mine. Thanks for the references and for the time this took.