Announcing CIMD support for MCP Client registration
Learn more

Pylon MCP vs Pylon API for AI Agents (2026)

TL;DR

  • Pylon's hosted MCP server covers issues, accounts, contacts, projects, milestones, and tasks. It has no customer-facing reply tool. An agent on the MCP path can read an entire conversation and change issue state, but it cannot send the customer a message.
  • The usual MCP vs API auth tradeoff is inverted for Pylon. MCP is OAuth 2.0 with per-user identity. The REST API accepts one thing: an admin-created Bearer token scoped to the whole organization. There is no OAuth on the API path and no per-user token.
  • That makes the API path the one with the identity problem. Pylon's docs state that actions performed by a token show up under the token's name. Attribution is recoverable, but only on the endpoints that accept a user_id, and only if you resolve the right Pylon user yourself.
  • Pylon's MCP tool surface changed at least six times between March and June 2026 with no version header. The REST API publishes explicit per-endpoint rate limits and a stable contract. For deterministic pipelines, that difference is the whole argument.
  • Scalekit's Pylon MCP connector handles the per-user OAuth flow, vaulted token storage, and refresh, so the MCP vs API decision does not change what you build for auth infrastructure.

Your agent needs to work inside Pylon. It needs to find the open issues for an account, read the thread, update state, and hand something back to a human or a customer. Pylon ships a hosted MCP server at mcp.usepylon.com and a REST API at api.usepylon.com. They are not two views of the same surface: they differ on what the agent can do, and they put you on auth paths that are close to opposites. Here is the decision framework.

What Pylon MCP and Pylon API actually are

Both paths are official and both are maintained by Pylon. The difference starts at the first line of setup, because one of them requires an org admin to turn a feature on and the other requires an org admin to mint a secret.

Pylon MCP

The Pylon MCP Server went live in March 2026 at https://mcp.usepylon.com. Transport is streamable HTTP, stateless, with no server-side sessions. Auth is OAuth 2.0 through AuthKit, and every action runs as the authenticated user.

An org admin enables the server from Settings, then AI Controls, then MCP Server. Individual access needs a Member or Admin seat with the MCP Access role. Access follows dashboard scoping exactly: the server cannot return data the user cannot already see, and cannot write what the user cannot already write in the UI.

Official docs: Pylon MCP Server.

Pylon API

The Pylon REST API is a bearer-authenticated interface at https://api.usepylon.com, spanning 22 documented resource groups. That covers issues, messages, accounts, contacts, users, teams, tags, custom fields, custom objects, knowledge base, macros, surveys, ticket forms, tasks and projects, attachments, activities, call recordings, feature requests, training data, and audit logs.

Authentication is a single mechanism: Authorization: Bearer <token>. Only Admin users can create tokens, from the API Tokens page under Settings. Tokens can be restricted by IP range or web domain, and the admin center shows each token's prefix for identification.

Official docs: Pylon API reference and Pylon API authentication.

The documentation gap worth knowing about before you scope

Pylon's MCP documentation page enumerates 11 tools across issues, accounts, and contacts. The live surface is larger. As catalogued on 6 June 2026, Scalekit's Pylon MCP connector lists 29 tools, adding projects, milestones, tasks, project templates, and account file upload.

Pylon's changelog confirms the expansion: "Projects & Tasks are now accessible via MCP" shipped 8 June 2026, and file upload to an account's Files tab shipped 27 April 2026. Do not scope your agent from the docs page alone. Enumerate the live tool list against your own connection before you plan around it.

Comparing them where it matters for agents

Four dimensions decide this for a Pylon agent: what the agent can do, which auth path you land on, what breaks in production, and which workloads each path actually suits.

What your agent can actually do

The MCP surface is well shaped for reading and triaging. Search issues by account, assignee, state, tags, custom fields, and date range. Pull the full message history. Update state, assignee, team, and tags. Search accounts, manage projects and tasks, upload files.

The API covers everything above plus the entire platform surface underneath it.

Capability
Pylon MCP
Pylon API
Search issues with filters
Yes (search_issues)
Yes (POST /issues/search)
Fetch an issue and its full message history
Yes (get_issue, get_issue_messages)
Yes
Create and update issues
Yes (create_issue, update_issue)
Yes
Search and update accounts
Yes (search_accounts, update_account)
Yes
Projects, milestones, tasks
Yes (added June 2026)
Yes
Send a customer-facing reply
No
Yes (POST /issues/{id}/reply)
Snooze an issue
No
Yes (POST /issues/{id}/snooze)
Add or remove issue followers
No
Yes
Link issues to Jira, Linear, GitHub, Asana
No
Yes
Knowledge base articles and collections
No
Yes
Macros, tags, custom field definitions
No
Yes
Surveys, CSAT and NPS results
No
Yes
Audit logs and account activities
No
Yes
Redact or delete a message
No
Yes

The reply gap decides most support agents

This is the gap that matters, and it is easy to miss until the agent is built. The MCP server exposes get_issue_messages, so the agent can read every reply and internal note on a thread. There is no corresponding tool to write one back to the customer.

The API has POST /issues/{id}/reply, which sends a customer-visible message on an existing conversation. It requires the top-level Pylon message_id of a customer-visible message to identify which thread to continue.

What the reply endpoint expects

For email conversations, email_info must carry at least one recipient across to_emails, cc_emails, and bcc_emails. Recipients are not inherited from the referenced message, which is a common first-run failure.

So a Pylon agent on the MCP path can research, classify, reassign, and escalate. It cannot answer the customer. If answering is the job, the API is not optional.

Internal notes are the ambiguous case

Pylon's changelog entry for 16 March 2026 reads that the MCP server now supports posting internal notes via the AI agent. Neither Pylon's MCP documentation page nor the catalogued live tool list includes a note tool.

Treat this as unresolved rather than settled, and verify against your own connection. It is also a clean illustration of the versioning problem covered below: on the MCP path, the changelog, the docs, and the live surface can disagree, and there is no version header to pin.

Rate limits are published on one path only

The REST API documents a limit per endpoint, which lets you plan concurrency before you ship. The MCP server applies limits per tool and per organization and returns a standard 429, but does not publish the numbers.

Operation
Documented API limit
GET /issues
10 requests per minute
POST /issues
10 requests per minute
POST /issues/{id}/reply
10 requests per minute
POST /issues/{id}/note
10 requests per minute
POST /issues/search
20 requests per minute
PATCH /issues/{id}
20 requests per minute
GET /issues/{id}
60 requests per minute

One more constraint for background syncs: GET /issues requires both start_time and end_time, and the window cannot exceed 30 days. A backfill is a loop over 30-day windows at 10 requests per minute, not a single paginated crawl.

The auth path each one puts you on

The MCP server runs on OAuth 2.0 exclusively. Pylon's support documentation is direct about the consequence: API key authentication is not currently available, which may affect usage in remote environments or platforms that do not support OAuth for remote connections.

The REST API is the mirror image. One mechanism, one credential type: an admin-created Bearer token that belongs to the organization, not to a person. There is no OAuth flow, no per-user token, and no delegated grant.

Why the usual tradeoff is inverted here

For GitHub, Notion, and Salesforce, the direct API is the path that gives you more auth options, including headless service credentials the MCP server does not support. Pylon reverses this.

Here, MCP is the path with correct per-user identity and no headless story. The API is the path with a clean headless story and no per-user identity at all. You are not choosing between convenience and control. You are choosing which of the two properties you give up. This is the core tension that OAuth vs API keys for AI agents plays out in real connector architecture.

Property
Pylon MCP
Pylon API
Auth mechanism
OAuth 2.0, browser consent
Bearer token, admin-created
Identity of the actor
The authorizing user
The token
Runs headless without a user
No
Yes
Permissions enforced
The user's own dashboard scope
Organization-wide
Revocation granularity
Per user
Per token, affects every workload using it
Credential creation
Any Member or Admin with MCP Access
Admin only

Attribution, and how to get it back on the API path

Pylon's authentication docs state it plainly: actions performed by the token show up with the name of the token. Pylon even exposes this as a filter, since the Account Activity timeline can be filtered by actor type, API token versus user.

The endpoints that let you name a person

Attribution is recoverable, but only in specific places. POST /issues accepts user_id or contact_id to attribute the first message, and the docs note that if neither is set, the API token's user is used. POST /issues/{id}/reply and POST /issues/{id}/note both accept an optional user_id to post as a specific person.

That is a real mechanism, and it is also a real amount of work. Your agent has to resolve the correct Pylon user ID for the human who triggered the run, pass it on every write, and handle the endpoints that accept no such parameter. Miss it once and the audit trail records a service account. For more on building proper audit trails for agent auth in B2B SaaS, the patterns apply directly here.

What you own in production

On the MCP path, Pylon owns the server, the tool schemas, and permission enforcement. You own per-user token storage, refresh, re-authorization when a session expires, and the provisioning dependency: an admin has to enable the server, and each user needs the MCP Access role before your agent can do anything for them.

On the API path, you own the full stack. Endpoint selection, cursor pagination, per-endpoint retry logic against seven different rate limits, the 30-day window constraint on issue listing, and the user resolution required to keep attribution intact. You also own secret rotation for a credential that, if leaked, reaches the entire organization.

The MCP schema moved six times in four months

This is the most concrete argument for the API in deterministic pipelines. Pylon's public changelog records repeated changes to the MCP tool surface, none of them behind a version header.

Date
Change to the MCP surface
10 March 2026
Hosted MCP server released
16 March 2026
get_account returns objects; new get objects endpoint added
27 April 2026
File upload to an account's Files tab added
4 May 2026
search_issues gains custom state slugs and exclusion
1 June 2026
search_issues gains custom field filtering
8 June 2026
Projects and tasks exposed via MCP
22 June 2026
update_issue gains custom field writes

Most of these are additive and harmless. The point is the absence of a contract. The REST API tells you what changed and when in the same changelog, but the endpoint you pinned keeps behaving the way it did. If an unplanned schema change is an incident for your team, that distinction is the decision. Understanding the difference between MCP and APIs helps frame why this versioning gap exists at all.

When to use MCP, when to use the API

The split is cleaner for Pylon than for most tools, because the reply gap and the identity gap fall on opposite sides.

Use Pylon MCP when:

  • The agent is interactive and a support engineer is present to complete OAuth, whether in Claude Code, Cursor, ChatGPT, or your own product's chat surface
  • The job is research and triage: find the open issues for an account, read the thread, set state, reassign, tag, escalate
  • You want Pylon's own permission model to constrain the agent, so a support rep's agent can never reach an account the rep cannot see
  • The agent works across projects, milestones, and tasks for account management workflows
  • Per-user attribution on issue and task edits is a requirement, not a nice-to-have

Use the Pylon API directly when:

  • The agent must send a customer-facing reply, which the MCP tool surface does not expose
  • The agent runs headless: nightly digests, SLA breach monitors, warehouse syncs, scheduled reporting with no user session available
  • The workload touches knowledge base articles, macros, tags, custom field definitions, surveys, audit logs, or message redaction
  • You need to link Pylon issues to Jira, Linear, GitHub, or Asana, or manage issue followers and snoozes
  • You are pinning a contract for a deterministic pipeline and cannot absorb an unannounced tool schema change
  • You need published rate limits to plan concurrency before you ship

The credential problem that exists on both paths

Both paths hand you a credential and stop there. Neither gives you a vault, rotation logic, or a revocation flow. In a multi-tenant B2B agent, that is N credentials to store, refresh, and revoke, and the two paths fail in different ways. The broader problem of credential ownership across agent tool-calling patterns shapes every decision here.

The MCP session expiry problem

Pylon's support documentation is unusually candid here. OAuth sessions expire periodically, the exact duration varies by MCP client, and some sessions last a few hours while others last several days. When a session expires, you may see authentication errors, or your MCP tools may simply stop returning results.

That second failure mode is the one that costs you. An agent that returns no issues looks identical to an account with no open issues. Your triage agent reports a clean queue and nobody checks. This is a silent failure that only surfaces when a customer escalates.

The shared admin token problem

The API path has the opposite shape. One token, created by an admin, valid across the whole organization, with no expiry pressure to force the issue.

It works perfectly in a demo. In production, every action the agent takes is attributable to a token rather than a person, one leaked secret reaches every account in the workspace, and revoking it to contain the blast radius takes down every other workload using the same credential. IP and domain restrictions narrow the exposure. They do not give you per-user isolation.

Where Scalekit fits

Scalekit's Pylon MCP connector resolves the per-user token on every tool call, so issue updates and task edits stay attributed to the Pylon user who authorized the agent. Tokens live in an AES-256 vault namespaced per tenant, refresh automatically, and never enter the agent runtime or the LLM context.

When a user revokes Pylon access, the connection is invalidated on the next tool call and subsequent requests fail closed with a clear error, rather than silently returning nothing. The same auth infrastructure serves both paths, so the MCP versus API decision does not change what you build at the credential layer. This is what secure token management for AI agents at scale looks like in practice.

Building a Pylon agent with Scalekit

Scalekit ships the Pylon MCP connector today under the connection slug pylonmcp, with 29 tools and OAuth 2.1 with dynamic client registration. The examples below use Python with LangChain for the direct tool-calling path, and TypeScript with Mastra for the Virtual MCP path.

Connect the user before anything else

Install the SDK and initialize the client. The connection name must match the connection configured in your Scalekit dashboard exactly; this is the single most common integration error.

pip install scalekit-sdk-python langchain langchain-openai
import os import scalekit.client scalekit_client = scalekit.client.ScalekitClient( client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), env_url=os.getenv("SCALEKIT_ENV_URL"), ) actions = scalekit_client.actions # Must match the connection name configured in the Scalekit dashboard CONNECTION_NAME = "pylonmcp" IDENTIFIER = "dana@acme.com" account = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) if account.connected_account.status != "ACTIVE": magic_link = actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) print("Authorize Pylon:", magic_link.link)

Retrieve the tools this user is authorized to call

Before the agent sees anything, decide what it is allowed to see. list_scoped_tools does not explore an unknown surface; it returns the tools this user's connected account is authorized to call. That distinction is what separates a per-user agent from a shared-credential agent.

For Pylon it matters twice over. Dana gets Dana's Pylon scope, and the tool list you hand the model is the ceiling on what any prompt can reach.

scoped = actions.tools.list_scoped_tools( identifier=IDENTIFIER, page_size=100, ) for tool in scoped.tools: print(tool.name, "->", tool.description)

Execute a single tool

For a deterministic pipeline that does not need a reasoning loop, call execute_tool directly. Scalekit resolves Dana's Pylon token server-side and returns structured output.

result = actions.execute_tool( tool_name="pylonmcp_search_issues", tool_input={ "account": "ref.tools", "states": ["new", "waiting_on_you"], "limit": 25, }, identifier=IDENTIFIER, ) issues = result.data print(result.execution_id)

Run the full agent loop with LangChain

actions.langchain.get_tools() returns native StructuredTool objects, so no schema reshaping is needed. Set page_size=100 so the 29-tool Pylon surface is not truncated by the default page.

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage tools = actions.langchain.get_tools( identifier=IDENTIFIER, connection_names=["pylonmcp"], page_size=100, ) tool_map = {t.name: t for t in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ HumanMessage( "Find every open issue for the account ref.tools from the past week. " "For the oldest one, read the message history and summarise what the " "customer is blocked on, then set its state to waiting_on_you." ) ] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: result = tool_map[tc["name"]].invoke(tc["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

Scope the surface with a Virtual MCP server

Twenty-nine tools is a real cost. A triage agent needs about five of them, and the other twenty-four are context you pay for on every run plus surface area you did not intend to grant. A Virtual MCP server declares exactly which tools an agent role can see, and whose credentials it acts with.

Create the config once per agent role, then mint a per-user instance before each run.

from scalekit.actions.types import McpConfigConnectionToolMapping config = actions.mcp.create_config( name="pylon-triage-agent", description="Read and triage Pylon issues. No task deletion, no file upload.", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="pylonmcp", tools=[ "pylonmcp_search_issues", "pylonmcp_get_issue", "pylonmcp_get_issue_messages", "pylonmcp_get_account", "pylonmcp_update_issue", ], ) ], ) instance = actions.mcp.ensure_instance( config_name="pylon-triage-agent", user_identifier=IDENTIFIER, ) mcp_url = instance.instance.url

pylonmcp_delete_task and pylonmcp_upload_account_files are not in that list, so no prompt can reach them. That is enforcement at the endpoint, not an instruction the model can be talked out of.

Confirm authorization before the run

ensure_instance is idempotent, so call it every session. Check auth state first and generate fresh links for any connection that needs re-authorization, which is exactly the MCP session expiry case discussed earlier.

auth_state = actions.mcp.get_instance_auth_state( instance_id=instance.instance.id, include_auth_links=True, ) for conn in auth_state.connections: if conn.connected_account_status != "ACTIVE": print(f"{conn.connection_name} needs authorization: {conn.authentication_link}")

Consume the endpoint from Mastra in TypeScript

Mastra has native MCP support, so it discovers the scoped tool list and Zod schemas straight from the URL. Mint the URL on your backend for the authenticated user and pass it through; a process-wide URL runs every request as one person.

npm install @mastra/core @mastra/mcp @ai-sdk/openai
import { Agent } from '@mastra/core/agent'; import { MCPClient } from '@mastra/mcp'; import { openai } from '@ai-sdk/openai'; // Resolved per authenticated user from your backend, never a shared constant const mcpUrl = await getPylonMcpUrlForUser(currentUserId); const mcp = new MCPClient({ servers: { pylon: { url: new URL(mcpUrl) }, }, }); const tools = await mcp.getTools(); const agent = new Agent({ name: 'pylon_triage_agent', instructions: 'You triage Pylon issues. Only act on the account named in the request. ' + 'Never change state without summarising the thread first.', model: openai('gpt-4o'), tools, }); const result = await agent.generate( 'Summarise every open issue for ref.tools and flag the ones waiting on us.', ); console.log(result.text); await mcp.disconnect();

Cover the REST-only gaps with a custom tool

The reply gap does not disappear because you picked a good connector. Scalekit's prebuilt Pylon connector targets the MCP server, so for POST /issues/{id}/reply and the rest of the REST-only surface you register Pylon's API as your own connector with bearer auth, then define the tool contract yourself.

Once registered, actions.request injects the stored credential and forwards your path to Pylon. Design the contract around the agent's intent rather than the raw endpoint shape.

def pylon_reply_to_issue(identifier: str, issue_id: str, message_id: str, body_html: str, to_emails: list[str]): """Send a customer-facing reply on an existing Pylon conversation. message_id must be the top-level Pylon message id of a customer-visible message from GET /issues/{id}/messages, not email_info.message_id. """ response = actions.request( connection_name="pylon-rest", # your registered connector identifier=identifier, method="POST", path=f"/issues/{issue_id}/reply", body={ "message_id": message_id, "body_html": body_html, "email_info": {"to_emails": to_emails}, }, ) data = response.json() return { "message_id": data["data"]["id"], "issue_id": data["data"]["issue_id"], }

Setup for the registered connector is covered in bring your own connector and custom tools.

Why the Scalekit path holds up in production

Two things carry disproportionate weight once a Pylon agent has more than one user: knowing what the agent did, and controlling what it could have done.

Downstream tool-calling auth logs

Every Pylon tool call through Scalekit is logged with the user who triggered it, the tool invoked, and what came back, retained for 90 days and exportable to your SIEM. Each execution returns an execution_id you can correlate against your own traces.

This is the part a shared admin token cannot give you. Pylon's own activity timeline can only tell you that an API token acted. Scalekit's logs tell you which human authorized the credential that acted, which is the question a SOC 2 auditor asks and the question an engineer asks at 3am when an issue got reassigned and nobody knows why. Agent tool observability is what separates a supportable production system from one that generates mysteries.

Virtual MCP for multi-tool and multi-tenant agents

Real Pylon agents are rarely Pylon-only. Triage means reading the issue in Pylon, checking the linked ticket in Linear, and posting to the account's Slack channel. Each of those is a separate MCP server with its own full catalogue.

A Virtual MCP server composes across them: five tools from Pylon, two from Linear, one from Slack, and nothing else reaches the model. One server definition serves every tenant, and a short-lived session token minted before each run binds the endpoint to one user's connected accounts. There is no MCP server to deploy, host, or maintain, and no per-user server configuration. The challenges of moving from single-tenant to multi-tenant tool-calling agent auth are exactly what this architecture is designed to solve.

The token arithmetic on a 29-tool connection

A Pylon connection at 29 tools, roughly 200 tokens each, costs about 5,800 tokens of context before the agent does any work. Scoping to five cuts that by roughly 80 percent, and shrinks the decision space the model chooses from. Surface reduction is the lever. Model upgrades help. They are not the lever.

Which one to build against

If your Pylon agent is user-facing and its job is research and triage, build on MCP. Per-user OAuth is already correct, Pylon's own permission model constrains the agent for free, and the tool surface covers issues, accounts, projects, and tasks well.

If your agent has to answer the customer, run on a schedule, reach the knowledge base or audit logs, or hold a contract you can pin, use the REST API and accept that you are responsible for identity.

Most teams will run both

Pass user_id on every write that supports it, or your audit trail records a token where a person should be. Most production Pylon agents will need both paths, because reading and replying sit on opposite sides of the line. The credential management problem is the same either way, and that is the part that needs production-grade infrastructure.

Talk to other Pylon agent builders

If you are working through the reply gap, per-user attribution, or scoping a Pylon agent across multiple tools, come compare notes. Join the Scalekit Slack community, or talk to us if you want help now.

Browse the Scalekit Pylon connector: connector page and connector docs.

FAQs

Does Pylon's MCP server support sending customer-facing replies?

No. The MCP server exposes get_issue_messages for reading threads but has no tool for writing a reply back to the customer. Sending a customer-facing message requires the REST API's POST /issues/{id}/reply endpoint. Most production support agents need both paths for this reason.

Why does Pylon's auth model invert the usual MCP vs API tradeoff?

Most platforms offer broader auth options on the API path. Pylon is the opposite: the MCP server uses OAuth 2.0 with per-user identity, while the REST API only accepts an org-wide admin-created Bearer token. So MCP is the delegated identity path and the API is the headless path—not the other way around.

How do I maintain per-user attribution when using the Pylon REST API?

Attribution is recoverable but requires explicit effort. POST /issues, POST /issues/{id}/reply, and POST /issues/{id}/note all accept an optional user_id parameter. Your agent must resolve the correct Pylon user ID for the human who triggered the run and pass it on every write. Endpoints that do not accept user_id will attribute the action to the API token.

What happens when an MCP OAuth session expires silently?

When a session expires, MCP tools may stop returning results rather than raising an explicit error. An agent that returns no issues looks identical to an account with no open issues—a silent failure that only surfaces when a customer escalates. Checking auth state before each run and generating fresh authorization links for expired connections is essential.

How does Scalekit handle the credential problem on both Pylon paths?

Scalekit vaults per-user OAuth tokens in AES-256 storage namespaced per tenant, refreshes them automatically, and fails closed with a clear error on revocation rather than returning empty results. The same infrastructure works for both the MCP and API paths, so switching between them does not require rebuilding credential management.

What is a Virtual MCP server and why does it matter for Pylon agents?

A Virtual MCP server is a scoped configuration that declares exactly which tools from which connectors an agent role can access. For a triage agent, you might expose five Pylon tools and exclude the other twenty-four. This reduces token cost by roughly 80%, shrinks the model's decision surface, and enforces tool access at the endpoint rather than by instruction.

Can I use Scalekit to call the Pylon REST API endpoints not covered by the MCP connector?

Yes. You register Pylon's REST API as a custom connector with bearer auth in your Scalekit dashboard, then define your own tool contracts using actions.request. Scalekit injects the stored credential and forwards the request. This is how you bridge the reply gap and reach surfaces like knowledge base articles, audit logs, and message redaction.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
zero upfront cost.

Every feature unlocked. No hidden fees.