---
title: Agents and coding assistants
description: Give an agent a key, install the MCP server, and create a project and its first resources without a browser.
type: how-to
product: platform
summary: The MCP server, a key for a machine, and a project built end to end from a terminal.
updated: 2026-10-01
order: 0
---

An agent works the same way a person does: one Sylphx key, and the whole API
behind it. There is no separate agent account and no reduced API. What differs
is how the key is obtained and how the API is reached — a terminal instead of a
browser, an MCP tool call instead of a typed command.

The Sylphx **Agents** product — durable sessions, memory, governed tool access —
is **Planned**; see [Sylphx Agents](/products/agents). This page covers the agent
interface that exists today.

## Give the agent a key

A person signs in through the browser. A machine takes a key that already
exists, from the environment or from standard input:

<CodeTabs>
	<CodeTab
		label="Environment"
		language="bash"
		code={`SYLPHX_API_KEY=sylphx_sk_live_… sylphx access whoami`}
	/>
	<CodeTab
		label="Standard input"
		language="bash"
		code={`printf '%s' "$KEY" | sylphx login --api-key -`}
	/>
</CodeTabs>

The SDK reads `SYLPHX_API_KEY` with no configuration at all, so a program needs
no change to run under an agent: `new Sylphx()` picks the key up. A key created
in the console, or minted with
`sylphx access api-keys create --spec.label ci --spec.scopes hosting:read,data:read`,
works the same way — the secret is shown once, when it is created, and never
again.

<Callout tone="warning" title="Scope the key to an environment">
	A key is bound to one environment and one mode, so a test key cannot touch a
	live environment. Give an agent a key in `development` and let it add one
	for `production` when you have read what it intends to do there.
</Callout>

## Install the MCP server

The MCP server exposes the same API to any MCP client — Claude Code, an IDE, or
your own agent loop. It speaks stdio and holds one key.

<CodeTabs>
	<CodeTab label="Run it" language="bash" code={`npx -y @sylphx/mcp    # or: sylphx mcp, or: cargo install sylphx-mcp`} />
	<CodeTab
		label="Configure it"
		language="json"
		code={`{
  "mcpServers": {
    "sylphx": {
      "command": "npx",
      "args": ["-y", "@sylphx/mcp"],
      "env": { "SYLPHX_API_KEY": "sylphx_sk_…" }
    }
  }
}`}
	/>
</CodeTabs>

## What the server gives an agent

Twelve tools, in two kinds. Six lead the common offers, each with its input
schema:

<KeyValue
	items={[
		{ key: 'Who is this key', value: 'access_whoami', mono: true },
		{ key: 'Read the plan and its limits', value: 'entitlement_entitlements_get', mono: true },
		{ key: 'Read the account and what it owes', value: 'billing_billing_accounts_get', mono: true },
		{ key: 'Read last month\'s usage', value: 'billing_usage_reports_query', mono: true },
		{ key: 'Search logs', value: 'observability_log_entries_query', mono: true },
		{ key: 'Search traces', value: 'observability_traces_query', mono: true },
	]}
/>

The other three reach everything else without filling the agent's context with
several hundred method definitions:

- `sylphx_search_methods` finds a method by what it does;
- `sylphx_describe_method` returns one method's full input schema;
- `sylphx_call` calls any method by its id with wire JSON.

That trio is the point of the design. An agent that wants to attach a custom
domain does not need a `network_domains_create` tool to exist: it searches,
describes, and calls. Tool annotations come from each method's own effect, so a
read is marked as a read, and a destructive call will not run without an
explicit `confirm: true`.

## Create a project and its first resources

The whole sequence, from an empty terminal to a project with a database and a
service, with no browser involved. Project, database and Hosting service
creation are served today through the management API, so the agent calls them
with `sylphx api`; the same calls reach it through the MCP server's
`sylphx_call` once those collections are on the one API.

<Steps>
	<Step title="Check where the key points">
		<CodeBlock language="bash" code={`sylphx access whoami`} />
		A key scoped to an organization can create a project; a key scoped to a
		project works inside it.
	</Step>
	<Step title="Create the project">
		<CodeBlock
			language="bash"
			code={`sylphx api POST /v1/projects -d '{"name":"shop","gitRepository":"acme/shop","gitBranch":"main"}'`}
		/>
		The answer holds the project's `id` and its environments.
	</Step>
	<Step title="Link this directory to an environment">
		<CodeBlock
			language="bash"
			code={`sylphx link --env orgs/acme/projects/shop/envs/production`}
		/>
		The link is written to `.sylphx/project.json`, so later commands can name
		a resource as a bare id and the parent is filled in.
	</Step>
	<Step title="Add a service and a database">
		<CodeBlock
			language="bash"
			code={`sylphx api POST /v1/projects/$PROJECT_ID/services -d '{"name":"web","githubRepo":"acme/shop","githubBranch":"main","port":"3000","sourceKind":"git"}'
sylphx api POST /v1/resources -d '{"name":"shop-main","kind":"database","tier":"hobby","projectId":"'$PROJECT_ID'"}'`}
		/>
		The [Hosting](/docs/hosting/quickstart) and
		[Database](/docs/database/quickstart) quickstarts continue from here:
		deploy, then bind the database to the environment.
	</Step>
</Steps>

Generated commands that change something wait for the operation to settle before
the command returns. `--no-wait` returns as soon as the call is accepted,
`--output json` prints the resource for a script to read, and `--from-file`
takes a whole request body when the flags would be long.

<Callout tone="note" title="When a command does not exist">
	The CLI and the SDK are generated from one schema, so anything the API can
	do is already a command. `sylphx api GET /v1/whoami` is the raw escape
	hatch, and an agent using MCP reaches the same method with
	`sylphx_call`.
</Callout>

## Let the agent ask

The MCP server is not only for creating things. An agent that has just deployed
can read its own service, check what the plan allows, and look at the last
error before deciding what to do:

<CodeTabs>
	<CodeTab
		label="MCP"
		language="json"
		code={`sylphx_describe_method { "method_id": "observability.error_groups.list" }
sylphx_call            { "method_id": "observability.error_groups.list", "request": { "parent": "orgs/acme/projects/shop/envs/production" } }`}
	/>
	<CodeTab
		label="TypeScript"
		language="ts"
		code={`const me = await sylphx.access.whoami({})
for await (const project of sylphx.access.projects.listAll({ parent: me.org })) {
  console.log(project.name)
}`}
	/>
</CodeTabs>

`listAll` walks every page for you. Every other collection has the same shape —
`get`, `list`, `listAll`, `create`, `update`, `delete`, and the methods that are
specific to it.

<RelatedDocs
	links={[
		{ href: '/docs/platform/keys-and-scopes', label: 'Keys and scopes' },
		{ href: '/docs/platform/environments', label: 'Environments' },
		{ href: '/docs/platform/errors', label: 'Errors' },
	]}
/>
