Connect Hermes to Portal.io
Set up in minutes
Choose where it runs
On your computer through your own Hermes, or hosted in the cloud. The rest of setup adapts to your choice:
Pick what it can do in Portal.io
A preset of real Portal.io operations. Each one becomes a tool the agent can call, and it can't touch anything outside the list.
Connect Portal.io
One sign-in. The agent acts through your account, scoped to the operations you picked.
Add your personal MCP link
The last step mints a private MCP URL for this agent and walks you through exactly this, with your real link filled in. The page flips to Connected the moment your Hermes first calls in. Hermes connects when it next starts a session.
1. Run this in your terminal
2. Answer no when asked if the server requires authentication — the link itself is the key
<your-link> is your personal server URL — setup mints it for you.
Tools Hermes gets
Portal.io
21 toolsReturns the proposals for the current account. Supports filtering by status, contact, modified date, search text, and archive state, along with sorting and pagination.
Creates a new proposal for the authenticated account. Supply a salesperson ID from the same account and, optionally, a proposal name. If no name is given, the system assigns a default name using the same logic as the Portal UI. The response includes the full proposal detail, including the new proposal ID, number, status, and financial summary.
Returns detailed information for the specified proposal. The HTTP response also sets the Last-Modified header from the response LastModifiedDate. Item costs are left out when costs are not available to your account, so a null cost does not mean the item has none. A recurring-service item is left out of its area option's total and counted in that option's totalRecurringService instead. When an item has total.isCombinedPrice true, its amount already includes the totals of the items nested under it, and those nested items still report their own amounts.
Performs a partial update on an existing proposal. You can update the proposal name, reassign the salesperson, or do both in one request. Both fields are optional, and omitted fields keep their current values. SalesPersonId must reference a user in the same account. The response includes the full updated proposal detail.
Updates the client-facing project description of a proposal. This is the description shown on customer-facing proposal documents. The request body accepts a single description string. The response includes the full updated proposal detail.
Updates the internal installer notes (installer project description) of a proposal. These notes are visible only to the dealer's team and do not appear on client-facing documents. The request body accepts a single internal notes string. The response includes the full updated proposal detail.
Returns detailed information for the specified change order. The HTTP response also sets the Last-Modified header from the response LastModifiedDate. Item costs are left out when costs are not available to your account, so a null cost does not mean the item has none. A recurring-service item is left out of its area option's total and counted in that option's totalRecurringService instead. When an item has total.isCombinedPrice true, its amount already includes the totals of the items nested under it, and those nested items still report their own amounts.
Returns the change orders for the specified proposal, including customer details, total, status, and created and modified dates.
Creates a new area (room) within a proposal. The area name must be unique within the proposal. The system automatically creates one default option in 'Draft' status under the new area. The response includes the full updated proposal detail, including the new area and its default option.
Creates a new option within an existing area. Each area supports a maximum of three options. Client description and internal installer notes are optional at creation time. The new option is created with 'Draft' status. The response includes the full updated proposal detail.
Assigns an existing contact (person/client) to a proposal. The proposal and contact must belong to the same account. If the contact has a single primary location, that location is automatically assigned to the proposal as well. Assigning a contact may trigger tax recalculations based on the contact's location.
Assigns a location to a proposal that already has a contact assigned. The location must belong to the proposal's assigned contact and to the same account. Assigning a location triggers tax recalculations for the proposal. The response includes the full updated proposal detail.
Returns a paged list of contacts for the current account. Supports search, contact type filtering, sorting, and pagination. Pagination defaults to PageNumber 1 and PageSize 10 when values are missing or less than or equal to 0.
Creates a contact in the current account. PartyType, ContactType, and FirstName are required. CompanyName is also required when PartyType is Company.
Returns the contact details for the specified person. PrimaryLocation and BillingLocation are included when available. When IncludeCounts is true, the response also includes proposal and payment counts for the contact.
Returns the contact's locations. Results are ordered with the primary location first, then the billing location, then the most recently modified locations. Pagination defaults to PageNumber 1 and PageSize 10. When PageNumber is less than or equal to 0, all matching locations are returned.
Adds a location to the specified contact. Street is required. When Country is provided, State is also required. Use IsPrimary to make the new location the primary location and IsBilling to make it the billing location.
Returns a list of all active users within the authenticated caller's account. The response includes basic, non-sensitive user details: user ID, first name, last name, email address, and the user's permission group. This is a read-only endpoint intended for integrations that need to look up user IDs before assigning them as salespersons on proposals or for syncing user data with external systems.
Searches the catalog using the provided category, brand, supplier, industry, stock, favorite, price, and item type filters. CategoryId and CategoryIds are mutually exclusive, and ParentCategoryId and ParentCategoryIds are mutually exclusive. If SearchText is omitted it is treated as an empty string. ItemType defaults to Part.
Returns the catalog category hierarchy grouped by industry, including category image URLs when available.
Returns details for the requested catalog item. When ItemType is Labor or CustomItem, the item is returned from the current account's library; otherwise a standard catalog item is returned. ExtendedDetails adds extra information to standard catalog item responses.
About Hermes
Frequently asked questions
More ways to connect
More tools for Hermes
Use Portal.io with other agents
Open your Hermes agent in one click.
NoClick runs Hermes for you with Portal.io wired in as tools. Connect your account and run.