Recipes
A recipe tells Sallyport how to reach one service: its hosts, the key it takes, and how each call is classed.
What a recipe decides
The catalog holds one recipe per service: GitHub, Stripe, Cloudflare, AWS and more than a hundred others. A recipe says where the key goes, which hosts it may reach, and whether a call reads, writes or destroys.
A connection uses the recipe it was created from. Otherwise Sallyport picks the recipe whose host matches, and the most exact host wins. A host no recipe claims still works, classed by its method.
Read the catalog
GET /v1/recipes lists the catalog, filtered by q (name, key or vendor), vendor or host. GET /v1/recipes/{key} returns one. Both take a console key, see REST API.
{
"data": {
"key": "github",
"name": "GitHub API",
"vendor": "GitHub",
"hosts": ["api.github.com"],
"connection_hosts": ["api.github.com"],
"connection_domains": [],
"channel": "http",
"adapter": "bearer",
"adapters": ["bearer", "oauth2-ac"],
"credential_fields": [
{ "name": "value", "label": "Personal access token or installation token", "secret": true, "required": true, "sent_as": [] }
],
"methods": [
{
"adapter": "bearer",
"fields": [
{ "name": "value", "label": "Personal access token or installation token", "secret": true, "required": true, "sent_as": [] }
],
"provider": "",
"sallyport_app": false,
"redirect_uri": ""
},
{
"adapter": "oauth2-ac",
"fields": [],
"provider": "GitHub",
"sallyport_app": false,
"redirect_uri": "https://mcp.sallyport.cloud/callback/upstream"
}
],
"notes": null,
"docs_url": "https://docs.github.com/en/rest",
"create_url": "https://github.com/settings/personal-access-tokens/new",
"revoke_url": "https://github.com/settings/tokens",
"scopes_recommended": [],
"default_profile": "direct",
"oauth": true,
"version": 2
},
"request_id": "5d0c2f7e8a1b4c6d9e0f1a2b3c4d5e6f"
}| Field | Meaning |
|---|---|
hosts | Hosts the service answers on. A leading *. covers every subdomain. |
connection_hosts, connection_domains | Hosts a new key connects to as they are, and domains under which you give your own address, such as acme.zendesk.com. |
adapter, adapters | How the key is presented: bearer, basic, header, api_key, aws-sigv4, oauth2-ac for signing in, and a few more. |
credential_fields | What a person types. secret says whether the value is a password. sent_as names the headers and query parameters a setting field is sent in on every call, and is empty for every other field. |
methods | Every way to connect the service, in the order the console offers them. A method with a provider is signing in at the vendor. |
create_url, revoke_url, docs_url | Where to issue the key, where to revoke it, and the vendor’s API reference. |
default_profile | The rule a new agent and connection pair starts on. Every recipe says direct: read, write and destructive all run without asking. |
The class rules and the key placement stay inside Sallyport and are not part of this answer.
How a call is classed
Every call is read, write or destructive. The agent’s rule for that class on the connection decides: run it, ask a person, or refuse.
- The method sets the floor:
GET,HEADandOPTIONSread;POST,PUTandPATCHwrite;DELETEand any other method is destructive. - The recipe’s rules are tried in order and the first match wins. A rule only raises, and the only raise is a
GETthe vendor changes something with, which becomes a write. No recipe rule makes a call destructive. - A path segment that starts with
webhook,hooks,build,trigger,send,invoke,execute,execorrunmakes the call at least a write. A recipe rule that matches the path overrides this. - A recipe may list exact read operations that travel as
POST, such as AWSDescribeInstancesor a GraphQL query. They count as reads only when the whole request reads one way. - GraphQL, JSON-RPC and batch requests take the highest class of their parts.
- Method overrides such as
_methodandX-HTTP-Method-Overrideare removed before the call is classed and sent.
Tools of an MCP server are classed by their own readOnlyHint and destructiveHint, and a tool that states neither is a write. SSH commands are writes, except a short list of exact reads, and commands such as rm or dd are destructive. See SSH commands. File operations on an SSH host are classed by what they do. list, stat and read are reads, write, mkdir and rename are writes. delete and rmdir are destructive, see Files over SFTP.
Checking a key
Some recipes, GitHub among them, name one harmless read that proves a key works: GET /user for GitHub. Sallyport runs it when a key is saved, when it is replaced, and when you press Check again.
A key the service refuses is marked on its page with the vendor’s own message. An answer that proves nothing, such as a missing permission, changes nothing.