Connectors
Reach real HTTP APIs and run sandboxed logic. Connectors are declared as data with brokered credentials.
A connector is how a Noodle Seed server reaches a backing system: a SaaS API, a first-party service, or your own API. Connectors are declared as data, and their credentials are resolved by the platform's credential broker, never hard-coded.
Build one with the connector builder, then bind it on the server's use map so tools can call it.
HTTP connectors
connector(id).version(v).http({...}) describes a real HTTP API: a baseUrl, an auth block, and an
operations map. Requests and responses map with ${...} expressions.
import { server, tool, connector, secret, z } from '@noodleseed/one';
const weather = connector('weather')
.version('1.0.0')
.http({
baseUrl: 'https://api.example.com',
allowedOrigins: ['https://api.example.com'],
auth: { kind: 'apiKey', header: 'X-Api-Key', secret: secret('WEATHER_API_KEY') },
operations: {
current: {
type: 'read',
method: 'GET',
path: '/v1/weather',
query: { city: '${input.city}' },
input: z.object({ city: z.string() }),
output: z.object({ temp_c: z.number() }),
response: { temp_c: '${response.temperature}' },
},
},
});
export default server('weather', { title: 'Weather', version: '1.0.0', use: { weather } }, [
tool('current_weather', {
description: 'Get the current temperature for a city.',
input: z.object({ city: z.string() }),
output: z.object({ temp_c: z.number() }),
fulfil: ({ input, connectors }) => connectors.weather.current({ city: input.city }),
}),
]);Credentials
Reference secrets and non-secret config by name; the broker resolves them per tenant at call time.
secret("NAME")for credentials (API keys, tokens). Set withnoodle secrets set.variable("NAME")for non-secret config (a base URL, a tenant id). Set withnoodle variables set.
Supported auth kinds today are bearer, apiKey, and clientCredentials
(Shipped) — the latter defaults to the RFC-6749
client-credentials grant, with profile: "custom" for non-standard partner token endpoints. Per-user
delegated auth kinds are Roadmap (Phase 3).
Hosts are allowlisted
HTTP connectors are SSRF-guarded: set allowedOrigins to the exact hosts the connector may reach.
Requests to other hosts are rejected.
Expressions
An operation maps its request and response declaratively with ${...} expressions instead of imperative
code. The common scopes:
| Expression | Resolves to |
|---|---|
${input.x} | A field of the operation input. |
${response} | The raw HTTP response body (use ${response.field} for a field). |
${env.NAME} | A managed variable (variable("NAME")). |
operations: {
get_order: {
type: 'read',
method: 'GET',
path: '/orders/${input.id}', // interpolate input into the path
input: z.object({ id: z.string() }),
output: z.object({ total: z.number() }),
response: { total: '${response.amount}' }, // map response body to output
},
}Managed config (secret("NAME") / variable("NAME")) is set with noodle secrets set /
noodle variables set and resolved per tenant by the broker at call time. Per-user
${user.*} expressions are Roadmap (Phase 3).
Compute connectors
When a bit of logic is genuinely needed (reshaping a response, deriving a value), a compute connector runs self-contained TypeScript in a sandbox with no ambient authority: no network, filesystem, secrets, or tokens.
const convert = connector('convert')
.version('1.0.0')
.compute('c_to_f', {
type: 'read',
input: z.object({ temp_c: z.number() }),
output: z.object({ temp_f: z.number() }),
run: (input) => ({ temp_f: input.temp_c * 1.8 + 32 }),
});The run function must be self-contained: no closures over outer variables, no imports, no fetch.
It reaches other operations only through an allowlisted host.callOperation, and you can bound it
with limits (timeout, memory, output size). Bind it on use and call it like any connector.
Binding connectors
useexposes a connector to your tools, callable asctx.connectors.<name>.<operation>().providesregisters a connector in the catalog for compute steps to reach viahost.callOperation, without exposing it directly to tools.
Roadmap
Adopting an existing MCP server as a connector, or generating a connector from an OpenAPI spec, is
Roadmap. noodle import openapi today scaffolds starter
code, not a managed connector.