- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
5 hours ago
You Built an AI Agent. Now Make It Reachable.
You've built an AI Agent in ServiceNow that detects duplicate knowledge articles. It works beautifully inside Virtual Agent, NAP, the Portal. But the moment an external system — a content management platform, a partner's orchestration layer, a Google Vertex AI pipeline — needs to call it, you hit a wall. There's no standard way in. That wall is what Google's Agent2Agent (A2A) protocol was designed to remove.
Think of it like USB-C for AI agents. One standard connector, and suddenly your ServiceNow agent can talk to anything.
Why Should You Care About A2A?
If you're building AI agents inside ServiceNow, A2A changes the boundary of what those agents can do. Instead of being locked to ServiceNow-native channels, your agents become first-class participants in any multi-agent ecosystem.
❌ BEFORE A2A: External systems that need ServiceNow AI Agent capabilities must go through custom REST integrations, bespoke middleware, or manual handoffs. Every new consumer means another integration to build and maintain.
✅ AFTER A2A: Any A2A-compliant client — Google Vertex AI, AWS Bedrock, Microsoft Azure AI Foundry, a Python script on a laptop — discovers your agent's capabilities automatically and invokes it through a single standard protocol. Zero custom integration code.
What A2A Is NOT
| Misconception | Reality |
|---|---|
| "A2A replaces MCP" | A2A and MCP are complementary. MCP connects agents to tools (vertical). A2A connects agents to agents (horizontal). Different layers, different purposes. |
| "A2A requires custom agent development" | You can expose existing OOTB AI Agents via A2A with zero code changes — just configuration toggles and OAuth setup. |
| "A2A needs a streaming/callback infrastructure" | A2A supports synchronous mode (message/send). The client sends a request, blocks, and gets a complete response. No SSE, no webhooks, no polling. |
| "A2A is Google-only" | A2A is an open protocol backed by 50+ partners. ServiceNow, Salesforce, SAP, LangChain, CrewAI, and others support it. |
| "Setting this up requires deep platform customization" | The entire PoC described here uses OOTB capabilities — AI Agent Fabric, Machine Identity Console, and standard OAuth 2.0. |
Under the Hood: How A2A Works on ServiceNow
ServiceNow natively supports A2A as part of AI Agent Fabric, introduced in the Now Assist AI Agents 6.0.x store app. Any AI Agent with "Allow third party to access this AI agent" toggled on becomes an A2A-compliant secondary agent.
Agent Card — The discovery mechanism. A JSON document that advertises the agent's name, description, capabilities, and input schema. External clients fetch this first to understand what the agent can do before invoking it.
JSON-RPC 2.0 — The wire format. A2A doesn't use traditional REST verbs. Instead, it uses JSON-RPC method calls (message/send, message/stream, tasks/get) transported over standard HTTPS.
OAuth 2.0 Client Credentials — The authentication layer. Service-to-service, no user interaction. ServiceNow's Machine Identity Console (Zurich+) handles this natively.
The Two A2A Endpoints
| Operation | Method | Endpoint |
|---|---|---|
| Agent Card discovery | GET | /api/sn_aia/a2a/v2/agent_card/id/{agent_sys_id} |
| Agent invocation | POST | /api/sn_aia/a2a/v2/agent/id/{agent_sys_id} |
Architecture
End-to-End Flow
| Step | Actor | Action | Protocol |
|---|---|---|---|
| 1a | A2A Client | Sends Client ID + Secret to obtain Bearer token | HTTPS POST to /oauth_token.do |
| 1b | OAuth Endpoint | Returns Bearer token | HTTPS response |
| 2a | A2A Client | Requests agent capabilities (Agent Card) | A2A v2 GET .../agent_card/id/{sys_id} |
| 2b | A2A Protocol Layer | Returns Agent Card JSON | HTTPS response |
| 3 | A2A Client | Sends article number via message/send JSON-RPC call |
A2A v2 POST .../agent/id/{sys_id} |
| 4 | A2A Protocol Layer | Authenticates token, routes request to AI Agent | Internal |
| 5–8 | AI Agent | Invokes Find Duplication tool, returns duplicate list | Internal |
| 9–10 | A2A Protocol Layer | Wraps response in JSON-RPC format, returns to client | JSON-RPC 2.0 response |
A2A vs MCP — Which Protocol Do You Need?
| Criterion | A2A | MCP |
|---|---|---|
| Purpose | Agent-to-agent collaboration | Agent-to-tool/data connectivity |
| Direction | Horizontal (peer agents) | Vertical (agent → tool/service) |
| Discovery | Agent Card (capabilities, skills, input schema) | Tool manifest |
| Wire format | JSON-RPC 2.0 over HTTPS | JSON-RPC 2.0 over stdio/HTTP |
| Use this when | An external system needs to invoke a ServiceNow AI Agent as a peer | A ServiceNow agent needs to call external tools or data sources |
Bottom line: If an external system is acting as a consuming agent that wants to invoke your ServiceNow AI Agent, use A2A. If your agents need external tools, that's MCP. Most production architectures will use both.
ServiceNow Platform Prerequisites
| Requirement | Details |
|---|---|
| Platform version | Zurich or later |
| Store app | Now Assist AI Agents 6.0.x (includes AI Agent Fabric with A2A support) |
| AI Agent | Any active agent with a tool — this guide uses the OOTB KB Content Consolidation AI Agent |
| Machine Identity Console | Available on Zurich+ for OAuth Client Credentials setup |
Build It: Step-by-Step Implementation
Step 0 — Create a Service Account
Navigate to: User Administration > Users > New
| Field | Value |
|---|---|
| User ID | a2a_service_account |
| First name | A2A |
| Last name | Service Account |
| Active | true |
Assign these roles:
| Role | Purpose |
|---|---|
sn_aia.integration |
A2A runtime access to AI Agent endpoints |
rest_service |
REST API access |
snc_platform_rest_api_access |
Platform REST API access |
knowledge_manager |
Required for KB Content Consolidation agent tools |
knowledge_admin |
Required for KB Content Consolidation agent tools |
Step 1 — Enable A2A and OAuth Properties
1a. Enable A2A Discoverability
Navigate to AI Agent Studio > Settings > External AI agents > Discoverability and set:
| Property | Value | Purpose |
|---|---|---|
sn_aia.external_agents.enabled |
true |
Enables external agent access via A2A |
sn_aia.internal_agents.enabled_external |
true |
Allows internal agents to be exposed externally |
Set Communication mode = Synchronous.
1b. Enable Client Credentials Grant Type
This property does not exist by default — create it manually.
Navigate to: sys_properties.list > New
| Field | Value |
|---|---|
| Name | glide.oauth.inbound.client.credential.grant_type.enabled |
| Type | true|false |
| Value | true |
401 access_denied.Step 2 — Activate and Configure the AI Agent
- Switch application scope to Now Assist in Knowledge Management (
sn_km_gen_ai) - Navigate to AI Agent Studio > Create and manage > AI agents
- Open KB Content Consolidation AI Agent
- Set Active = true, Allow third party to access this AI agent = ON
- Save
Step 3 — OAuth Setup (Machine Identity Console)
3a. Create Inbound Integration
- Navigate to Machine Identity Console > Inbound Integrations tab
- Click New Integration
- Select OAuth - Client credentials grant
- Set Name =
A2A Client Credentials, OAuth Application User =a2a_service_account - Save
- Copy the auto-generated Client ID and Client Secret — store securely
3b. Add A2A Auth Scope
On the same integration record, add a2aauthscope to the Auth Scopes. Without this scope, token-authenticated requests to /api/sn_aia/a2a/... will fail.
Step 4 — Test OAuth Token
Send this request:
POST https://<instance>.service-now.com/oauth_token.do
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=<CLIENT_ID>
&client_secret=<CLIENT_SECRET>
Expected response (200 OK):
{
"access_token": "<BEARER_TOKEN>",
"scope": "",
"token_type": "Bearer",
"expires_in": 1799
}
Step 5 — Test Agent Card Discovery
GET https://<instance>.service-now.com/api/sn_aia/a2a/v2/agent_card/id/<AGENT_SYS_ID>
Authorization: Bearer <ACCESS_TOKEN>
Expected: 200 OK with JSON containing agent name, description, capabilities, and input schema.
Step 6 — Test Agent Invocation
POST https://<instance>.service-now.com/api/sn_aia/a2a/v2/agent/id/<AGENT_SYS_ID>
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
Request body:
{
"jsonrpc": "2.0",
"id": "1",
"method": "message/send",
"params": {
"message": {
"kind": "message",
"role": "user",
"messageId": "msg-001",
"parts": [
{
"kind": "text",
"text": "Check duplicates for KB0010001"
}
]
},
"metadata": {}
}
}
message.kind and message.messageId are both required. ServiceNow uses a discriminated-union model — without kind, you get "Invalid method parameters: Kind missing". Without messageId, you get "Message Id missing".Expected: 200 OK with a JSON-RPC response containing either a list of duplicate articles with hyperlinks, or "No duplicates were found."
Step 7 — Test via sn-a2a CLI (Optional)
The sn-a2a CLI is a ServiceNow-maintained A2A command-line client with interactive chat and OAuth token handling.
Install:
cd "<any-directory-outside-your-project>"
git clone https://github.com/ServiceNow/sn-a2a.git
cd sn-a2a
Configure:
cp .env.example .env
Edit .env:
| Variable | Value |
|---|---|
A2A_CLIENT_BASE_URL |
https://<instance>.service-now.com/ |
A2A_CLIENT_AGENT_ID |
Agent sys_id from Step 2 |
A2A_CLIENT_AUTH_TOKEN |
A fresh Bearer token from Step 4 |
Run:
uv sync
uv run python main.py
Interactive session:
Connected to agent: KB content consolidation AI agent
You: Check duplicates for KB0010067
Agent: Similar article(s) found for KB0010067:
- KB0000004
- KB0010001
- KB0010002
Task has been completed
Troubleshooting
| Problem | Fix |
|---|---|
oauth_token.do returns 401 access_denied |
Create/set glide.oauth.inbound.client.credential.grant_type.enabled = true in sys_properties.list |
oauth_token.do returns 400 Bad Request |
Verify inbound integration is set to Client Credentials grant type with correct OAuth Application User |
| Agent Card returns 404 | Verify agent sys_id, ensure Active = true |
| Agent Card returns 403 | Service account missing sn_aia.integration role |
| Agent Card returns empty capabilities | "Allow third party to access this AI agent" is not toggled ON |
| "Cloud Agent Error: Request is taking longer than 30 seconds" | This is Postman Cloud Agent's hard timeout, not a ServiceNow issue. Use Postman Desktop Agent, curl, or sn-a2a CLI |
message/send returns 403 |
Service account missing required roles — verify all five from Step 0 |
| A2A endpoints return 403 despite valid token | OAuth client missing a2aauthscope — add it in Step 3b |
| Agent returns "Could not find a published accessible article" | Article doesn't exist or is not in Published state |
| sn-a2a CLI auth failure | Double-check CLIENT_ID, CLIENT_SECRET, and AUTH_TOKEN in .env |
Resources
| Resource | Where |
|---|---|
| A2A Protocol Specification | google.github.io/A2A |
| Google A2A Announcement | Google Cloud blog |
| ServiceNow A2A Documentation | Enable MCP and A2A for your agentic workflows — Zurich Patch 4 |
| A2A Authentication Guide | Authentication for Google A2A — ServiceNow as Secondary Agent |
| Machine Identity Console Docs | Introducing Machine Identity Console (New in Zurich) |
| sn-a2a CLI Repository | github.com/ServiceNow/sn-a2a |
Three Takeaways
- ServiceNow already speaks A2A. AI Agent Fabric in Now Assist AI Agents 6.0.x gives you OOTB A2A endpoints. No custom REST APIs, no middleware, no scripted integrations — toggle a setting and your agent is discoverable.
- A2A and MCP solve different problems. A2A is horizontal (agent-to-agent), MCP is vertical (agent-to-tool). If external systems need to invoke your agents, A2A is the protocol. If your agents need external tools, that's MCP. Most production architectures will use both.
-
The A2A protocol itself is straightforward. Care is primarily required around OAuth configuration — specifically the Client Credentials grant, non‑default system properties, and explicit auth scopes.
Fastest path to try this yourself: Spin up a ServiceNow Zurich sandbox, install Now Assist AI Agents 6.0.x, follow Steps 0–6 above, and send your first message/send via curl. Then clone the sn-a2a CLI for a proper interactive experience.
- 107 Views
