Wrapping a REST API into an MCP service lets an LLM agent discover, select, and invoke your endpoints through MCP’s tool interface; the wrapper handles auth, translates calls to HTTP, and returns typed responses back to the agent
With REST API Wrapping, you can:
- Expose any REST endpoint as a callable MCP tool.
- Define multiple sub-tools (actions) with clear, LLM-readable purposes.
- Validate inputs/outputs with JSON Schema.
- Centralize auth via reusable Connections (preferred over raw tokens in headers).
- Log, test, and iterate safely without custom code.
Navigate to REST API Wrapping
- In Tools, choose Add Rest API (or open an existing one).
- Fill the top-level fields:
- Name* – Unique service name (e.g., “HubSpot”).
- Description* – Write for the LLM: when should it use this service? Which objects? Which outcomes?
- Definition Type* – Minimal is fine to start; use Standard/Full if you need richer metadata.
- Base URL* – Root domain (e.g.,
https://api.hubapi.com). - Connection – Select a saved OAuth/API-key connection. Prefer this over putting secrets in headers.
Tip: Think of this page as your “service manifest.” The better the Name/Description, the smarter the tool selection will be.
Define Sub-Tools (Actions)
Each sub-tool is a specific operation the agent may call (e.g., create a contact, search companies).
Click Add Entry and configure:
- Name* – Short, verb-first, and unique (e.g.,
contact_create,companies_search). - Description* – One or two lines that help the LLM choose correctly. Include the object(s), filters, and side-effects.
- Input Schema* – JSON Schema describing the expected input. Keep it minimal but precise. (You can draft with ChatGPT/Claude.)
- Endpoint URL* – Relative path (e.g.,
/crm/v3/objects/contacts). - Method* – GET, POST, PUT, PATCH, DELETE.
- Headers – Only add what’s specific to this call (e.g.,
Content-Type). Leave auth to Connection whenever possible. - Default Params – Static query/body params that should always be included.
LLM prompt hint: “Use
companies_searchwhen the user provides a partial company name or domain; usecontact_createonly when we have at least an email.”
Example: Create a HubSpot Contact
Sub-Tool Name: contact_create
Description: Create a HubSpot contact (lead). Accepts properties and returns the created record.
Endpoint URL: /crm/v3/objects/contacts
Method: POST
Headers:
{ "Content-Type": "application/json" }
Input Schema:
{
"type": "object",
"required": ["properties"],
"properties": {
"properties": { "type": "object" }
}
}
Example input:
{
"properties": {
"email": "pat@example.com",
"firstname": "Pat",
"lastname": "Lee",
"lifecyclestage": "lead"
}
}
Example: Search HubSpot Companies (tolerant contains)
Sub-Tool Name: companies_search
Description: Case-insensitive search using contains (more tolerant of misspellings). Return company type when present.
Endpoint URL: /crm/v3/objects/companies/search
Method: POST
Input Schema (simple pattern):
{
"type": "object",
"required": ["query"],
"properties": {
"query": { "type": "string" },
"limit": { "type": "integer", "minimum": 1, "maximum": 100 }
}
}
Example input:
{ "query": "worknet", "limit": 5 }
Writing Great Names & Descriptions (for LLMs)
- Be explicit: object + action + context (e.g., “Create HubSpot contact from website chat”).
- State preconditions: “Requires
emailorphone.” - Clarify differences between similar tools (“use search before create to avoid duplicates”).
- Mention side-effects: “Also updates conversation summary.”
Schema Tips (that prevent bad calls)
- Require only what’s truly required. Too strict → tool never fires; too loose → validation misses errors.
- Use enums for known fields (e.g.,
"lifecyclestage": {"enum": ["lead","subscriber","customer"]}). - For GET with query params, model them explicitly:
{
"type": "object",
"properties": { "limit": { "type": "integer" }, "after": { "type": "string" } }
}
- For POST bodies, wrap the request in a single
propertiesobject if the API expects that structure (HubSpot does).
Authentication Patterns
- Preferred: set auth in Connection (OAuth/API key managed centrally).
- Fallback: add
Authorization: Bearer {{token}}in sub-tool Headers (use only for quick tests). - Rotate tokens in Connection without editing sub-tools.
- Never hard-code secrets in Default Params.
Testing & Observability
- Use the Test button on each sub-tool with a realistic payload.
- Verify the response shape (IDs, paging cursors, error codes).
- Check logs: status code, request body, response payload.
- Add small guardrails to the Description (e.g., “Do not call without
email.”) to guide the LLM.
Common Pitfalls & Quick Fixes
- 401 / INVALID_AUTHENTICATION
“Authentication credentials not found… OAuth 2.0…”
Fix: Ensure the Connection is selected and valid; don’t rely on missing/expired headers. - 400 / VALIDATION_ERROR: Missing required property (e.g.,
hs_timestamp)
Fix: Add the required field to your Input Schema and pass it in the payload (ISO 8601 or epoch per API spec). - 400 / PROPERTY_DOESNT_EXIST (e.g.,
linkedinurl)
Fix: The property isn’t defined in your HubSpot schema. Rename to a valid field or create the custom property first. - Duplicate creation
Fix: Add and use a*_searchsub-tool first; only call*_createwhen no match is found. - Wrong Content-Type
Fix: SetContent-Type: application/jsonin Headers for JSON endpoints.
Security & Governance
- Prefer Connection over per-tool tokens.
- Scope tokens to least privilege.
- Avoid returning sensitive data to the LLM unless necessary; redact when possible.
- Log requests/responses (with redaction) for auditability.
FAQ
Can I reuse the same Connection across services?
Yes—share connections wherever the auth model matches.
How do I handle pagination?
Expose limit/after (or page/cursor) in the Input Schema and return the cursor in the response so the agent can loop.
Can tools update conversation context?
Yes—mention it in the sub-tool Description (e.g., “append a note to the conversation summary”).
Quick Checklist
- Service Name/Description are LLM-friendly.
- Base URL correct; Connection selected.
- Each sub-tool has: clear Name, precise Description, correct Method/Endpoint, lean Input Schema, proper Headers, and optional Default Params.
- Tested with realistic payloads; logs look good.
- Troubleshooting notes added for your team.
If you want, I can convert this into a product help center article (with screenshots, callouts, and a short “Test your first call” walkthrough), or tailor examples for additional systems (Salesforce, Zendesk, Jira) using the same patterns.
Comments
0 comments
Article is closed for comments.