Skip to main content
Related: What is MCPWhy build an MCPQuickstartPlatform overviewPylee MarketplaceMCP vs APIHosting and deployment of MCPsPublishing MCP servers

Overview

An MCP server is not just “some code running on a machine.” It’s a structured way to expose implemented capabilities through the Model Context Protocol once running. Each server starts with a specification (the manifest describing its tools, resources, and prompts), has implementation code that fulfills that specification, and can be turned into a running instance. Pylee helps manage that lifecycle: versioning, registries, runtime secret injection, access control, monitoring, and audit.

Core MCP Server Building Blocks

Every MCP server defines what it can do using three primitives:
  • Tools — actions the client or agent can perform. Each tool has a schema for inputs and outputs (e.g. sendEmail(to, subject, body) or createCalendarEvent(title, start, end)).
  • Resources — structured data sources available to clients, identified by URIs. (e.g. file:///notes/project.md, calendar://events/2025, or vault://secret/{name}.)
  • Prompts — reusable workflows or templates that guide how tools and resources are used together.
    (e.g. triageSupportTicket(ticket_id) or planVacation(destination, duration)).
Together, tools, resources, and prompts make servers predictable and reusable across clients.

Server Hierarchy and Ownership

Everything in Pylee belongs to an organization, which is the top level entity. OrganizationServersServer VersionsDeployments
  • Organizations own servers, registries, deployments, variables, secrets, and memberships.
  • Servers belong to exactly one organization and live under a namespace like @org-slug/server-name.
  • Server versions are immutable snapshots of a server, tied back to the organization.
  • Deployments are running instances of specific server versions.
  • Registries are owned by organizations. They act as curated collections of servers for teams or projects.

Relationship model

Pylee Organization
├── Servers (0 to many)
│   ├── Server Versions (immutable, org-owned)
│   │   └── Variables & Secrets Placeholders
│   │   └── Deployments (instances of versions)
├── Registries (0 to many)
│   ├── Server Versions (many-to-many relationship)
│   └── Variables & Secrets
└── Memberships & Access Control
└── Variables & Secrets
This model keeps ownership clear: organizations own everything, while registries and versions provide flexibility to share and govern servers.

Talking about MCP “servers”

The word server inevitably comes up in conversations about MCP in a few nuanced but important ways. To avoid confusion, here’s how we think of this at Pylee:
  1. Server specification — a manifest file that describes what the server can do (its tools, resources, and prompts) and configuration (connection type, transportation type, and arguments). Think of this as a blueprint.
    Example: a JSON manifest listing an issue:create tool and a projects://roadmap resource via a remote HTTP server.
  2. Server implementation — the actual code, package, or container that fulfills the specification. This is what you, as a developer, write.
    Example: a Python package that knows how to create issues in GitHub.
  3. Running instance — a live process that clients can connect to. This is the “server” in the classic sense.
    Example: a process running on your laptop, or an HTTP server hosted in your cloud.
You’ll see us use these terms explicitly throughout this page.

Deployment, Connection, and Transport

Another common source of confusion while speaking about MCP servers is confounding the deployment, connection type, and transportation protocol. We like to separate into three distinct questions:
  1. Deployment / LocationWhere is the server running?
    • Local: runs on the same machine as the client (e.g. your IDE spawns it).
    • Remote: runs elsewhere (a container, VM, or hosted service).
  2. Connection / Entry PointHow do I reach it?
    Think of this as the connection method, startup mode, or endpoint type.
    • Package (start on demand): the client starts a child process server by running a command.
      Example: ["python", "-m", "my_mcp"]
    • Remote (prerunning): the client connects to a server already running at a URL.
      Example: https://my-server.acme.com
  3. TransportOnce connected, how do messages flow?
    • stdio: when one program starts another, they talk through built-in text channels (stdin/stdout) - like how terminals and editors communicate with tools they launch.
    • http/sse: network-friendly web protocols; common in production.
Common patterns
Use caseLocationEntry pointTransportHow the client connectsTypical fit
Editor/CLI local toolLocalPackage (start command)STDIOClient launches the process; no network portLocal file access, quick iteration
Local web testingLocalRemote (URL on localhost)HTTP/SSEClient connects to http://localhost:PORTTest the same server you’ll deploy
Team/shared serviceRemoteRemote (public/internal URL)HTTP/SSEClient connects to URL (often via registry)Production and shared integrations
Notes
  • A local package is often paired with stdio, but could also spawn an HTTP/SSE server that the client then connects to.
  • A remote almost always uses HTTP/SSE, since stdio only works with parent/child processes.
  • A pre-running server can still be on your local machine at http://localhost - useful when testing servers during development.

How Servers Map into Pylee

In Pylee, a server is the top level MCP definition your organization owns. Servers specs evolve through server versions, which are immutable snapshots that declare:
  • Entry point — how clients connect (either a Package launched locally via STDIO, or a Remote at a URL over HTTP/SSE).
  • Capabilities — the tools, resources, and prompts exposed.
  • Placeholders — configuration keys (like API_KEY, BASE_URL) that Pylee fills in at runtime.
A deployment is a live instance of a particular server version — running locally, in your infrastructure, or on Pylee hosted infrastructure. Servers and versions can be shared through registries, which provide governance, discovery, version pinning, and configuration overrides.

Configuration: Connection Type, Versions, & Placeholders

To create an MCP server spec, you first instantiate a server version. While configuring arguments, server versions may declare placeholders (like {API_KEY}, {BASE_URL}) instead of hardcoding values. At runtime, Pylee fills in these placeholders with the right values.

Versioning

Servers evolve through versions. A server version first declares the appropriate connection or entry point type(s). e.g. Package or Remote and associated approrpiate runtime or header arguments. Each version is immutable and should be pinned for consistency.
  • Versions are editable until published; after publish they’re immutable.
  • Any alphanumeric string is accepted as a version label.
  • Best practice: use semantic versioning (1.2.0) to signal breaking, minor, and patch changes.
  • Pinning makes CI, IDEs, and agents more reliable.
  • Immutable versions make rollbacks simple.

Placeholders

Declare placeholders (e.g., API_KEY, BASE_URL) in the Server Version. Pylee resolves them at runtime using the following order for runtime:
  1. Registry values — highest priority, often used to scope per team or project.
  2. Organization values — defaults shared across the org.
Secrets are always stored encrypted in Pylee’s vault and injected only when the server runs. They never appear in configs, logs, or client files.

Visibility and Sharing

Servers can be:
  • Private — default. Visible only inside your organization and its registries.
  • Public — listed in the Pylee Marketplace, and optionally mirrored to Anthropic’s global registry.
Most teams start private, then promote servers into registries for controlled sharing. See Publishing MCP servers for details.

Deployment and running instances

Once you’ve written your implementation code (your repo), the next question is: where do I want this code to run?
There are three main options. Each one ties back to how MCP defines a server in the spec (as a package or a remote).

1. Run locally (on your laptop)

  • Where it runs: directly on your machine.
  • How it works:
    • If the server is a package (stdio), the client launches it as a local process. No network port is used — the client and server just talk through stdin/stdout.
    • If the server is a remote (HTTP/SSE), you can still run it locally on a port like http://localhost:3000. Even though it’s on your laptop, you configure it as a remote in the server spec.
  • When to use it: quick iteration, debugging, or servers that need access to your local files.
  • How to connect: usually via direct connect in your IDE or client. You can also use a registry if you want to share consistent settings across multiple clients.

2. Run in your own infrastructure

  • Where it runs: in your cloud or on-prem environment (e.g., AWS, GCP, Azure, or your own servers).
  • How it works:
    • Always configured as a remote (HTTP/SSE).
    • The same process you tested on localhost:3000 during development can be deployed behind your own public or internal URL. Update the server version in Pylee to point to the new URL.
  • When to use it: when your team already manages hosting and scaling.
  • How to connect: recommended via registries (for audit and governance), but direct connect is still possible for testing.

3. Run on Pylee (hosted deployment)

  • Where it runs: Pylee builds and runs your implementation for you in a managed environment.
  • How it works:
    • Pylee deploys it as a remote (HTTP/SSE).
    • You don’t need to assign a URL — Pylee issues a secure one automatically.
    • Variables and secrets are injected safely at runtime.
  • When to use it: when you want a production-ready server without setting up infrastructure.
  • How to connect: usually through registries, which add visibility, approvals, and version pinning.

Localhost during development

When you’re building a server that will eventually be a remote, it’s normal to run it first on http://localhost:3000.
  1. Create or select a server version.
  2. Register localhost:3000 as the remote.
  3. Run your implementation code locally and connect to it.
  4. Optionally use a tool like ngrok if you need to expose it temporarily for external clients.
  5. Later, swap the remote URL for a production endpoint (your own infra or Pylee-hosted).
Remember:
  • A “remote” just means “a server with an HTTP/SSE endpoint.” That endpoint can point to localhost during dev or a hosted URL in production.
  • A stdio server is always a package and never runs on a port.

Pylee Usage

Where the server runs (local, your infra, or Pylee) is separate from how to use through Pylee. There are two ways:
  • Direct connection — attach to one server at a time. Simple for testing or focused tasks.
  • Registry connection — attach through a registry, which can include many servers. Registries also provide approvals, pinning, and audit. This is the recommended way for production.

Putting it together

A common path looks like this:
  1. Write your implementation code.
  2. Run it locally:
    • as a package (stdio), or
    • as a remote (HTTP/SSE) bound to localhost:3000.
  3. Create a server version in Pylee, marking it as a package or remote.
  4. Promote the same implementation:
    • run it in your own infra and update the remote URL, or
    • deploy on Pylee and use the URL provided for you.
  5. Pin the version in a registry so teams connect to the same server securely with variables and secrets resolved.
For a step-by-step guide, see the Hello World tutorial.
I